diff --git a/.bsp/sbt.json b/.bsp/sbt.json new file mode 100644 index 0000000..7c86a39 --- /dev/null +++ b/.bsp/sbt.json @@ -0,0 +1 @@ +{"name":"sbt","version":"1.7.1","bspVersion":"2.0.0-M5","languages":["scala"],"argv":["/home/jgall/.jabba/jdk/openjdk@1.17.0/bin/java","-Xms100m","-Xmx100m","-classpath","/home/jgall/bin/sbt-lib/bin/sbt-launch.jar","-Dsbt.script=/home/jgall/bin/sbt","xsbt.boot.Boot","-bsp"]} \ No newline at end of file diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..3b2bb16 --- /dev/null +++ b/.cproject @@ -0,0 +1,600 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + make + + all + true + true + false + + + make + + am--refresh + true + true + false + + + make + + check + true + true + false + + + make + + clean + true + true + false + + + make + + clean-libtool + true + true + false + + + make + + config.h + true + true + false + + + make + + ctags + true + true + false + + + make + + ctags-recursive + true + true + false + + + make + + dist + true + true + false + + + make + + dist-all + true + true + false + + + make + + dist-bzip2 + true + true + false + + + make + + dist-gzip + true + true + false + + + make + + dist-lzma + true + true + false + + + make + + dist-shar + true + true + false + + + make + + dist-tarZ + true + true + false + + + make + + dist-zip + true + true + false + + + make + + distcheck + true + true + false + + + make + + distclean + true + true + false + + + make + + distclean-hdr + true + true + false + + + make + + distclean-libtool + true + true + false + + + make + + distclean-tags + true + true + false + + + make + + distcleancheck + true + true + false + + + make + + distdir + true + true + false + + + make + + distuninstallcheck + true + true + false + + + make + + dvi + true + true + false + + + make + + html + true + true + false + + + make + + info + true + true + false + + + make + + install + true + true + false + + + make + + install-data + true + true + false + + + make + + install-dvi + true + true + false + + + make + + install-exec + true + true + false + + + make + + install-exec-hook + true + true + false + + + make + + install-html + true + true + false + + + make + + install-info + true + true + false + + + make + + install-man + true + true + false + + + make + + install-pdf + true + true + false + + + make + + install-ps + true + true + false + + + make + + install-strip + true + true + false + + + make + + installcheck + true + true + false + + + make + + installdirs + true + true + false + + + make + + maintainer-clean + true + true + false + + + make + + Makefile + true + true + false + + + make + + mostlyclean + true + true + false + + + make + + mostlyclean-libtool + true + true + false + + + make + + pdf + true + true + false + + + make + + ps + true + true + false + + + make + + stamp-h1 + true + true + false + + + make + + tags + true + true + false + + + make + + tags-recursive + true + true + false + + + make + + uninstall + true + true + false + + + + diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..00788a8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +docker +deploy diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f39719 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +*.pyc +*.swp +Makefile.in +*.o +*.pyo +*.lo +*.la +.deps +.libs +*.log +/build/ +/autom4te.cache/ +/aclocal.m4 +/config.guess +/config.h.in +/config.status +/config.sub +/configure +/depcomp +/install-sh +/libtool +/missing +/stamp-h1 +/config.h +/ltmain.sh +/ar-lib +workspace.code-workspace diff --git a/.project b/.project new file mode 100644 index 0000000..fab42e8 --- /dev/null +++ b/.project @@ -0,0 +1,62 @@ + + + spell + + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + + + org.python.pydev.PyDevBuilder + + + + + org.eclipse.cdt.autotools.core.genmakebuilderV2 + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.autotools.core.autotoolsNatureV2 + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.python.pydev.pythonNature + org.eclipse.xtext.ui.shared.xtextNature + + + + python2.7 + 2 + /home/spell/SPELL-COTS2.5.7a/include/python3.7m + + + spell_stubs + 2 + /home/jgall/SPELL_TEST/spell + + + protos/google + 2 + /home/spell/spell_cots/lib/python2.7/site-packages/grpc_tools/_proto/google + + + diff --git a/.pydevproject b/.pydevproject new file mode 100644 index 0000000..389ee64 --- /dev/null +++ b/.pydevproject @@ -0,0 +1,11 @@ + + +Default +python 3.0 + +/${PROJECT_DIR_NAME}/src/spell +/${PROJECT_DIR_NAME}/spell_stubs +/${PROJECT_DIR_NAME}/drivers/remote_interface +/${PROJECT_DIR_NAME}/drivers/service + + diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml new file mode 100644 index 0000000..adcc38a --- /dev/null +++ b/.settings/language.settings.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.settings/org.eclipse.cdt.codan.core.prefs b/.settings/org.eclipse.cdt.codan.core.prefs new file mode 100644 index 0000000..b5248c6 --- /dev/null +++ b/.settings/org.eclipse.cdt.codan.core.prefs @@ -0,0 +1,71 @@ +eclipse.preferences.version=1 +org.eclipse.cdt.codan.checkers.errnoreturn=Warning +org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false} +org.eclipse.cdt.codan.checkers.errreturnvalue=Error +org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"} +org.eclipse.cdt.codan.checkers.nocommentinside=-Error +org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"} +org.eclipse.cdt.codan.checkers.nolinecomment=-Error +org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"} +org.eclipse.cdt.codan.checkers.noreturn=Error +org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false} +org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error +org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"} +org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error +org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"} +org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning +org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"} +org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error +org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"} +org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning +org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false} +org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning +org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error +org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"} +org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning +org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true} +org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error +org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error +org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error +org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"} +org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error +org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"} +org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error +org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"} +org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error +org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"} +org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error +org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info +org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning +org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"} +org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error +org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"} +org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error +org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"} +org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error +org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"} +org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"} +org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"} +org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning +org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning +org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false} +org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning +org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false} +org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error +org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning +org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning +org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning +org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")} +org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error +org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"} diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..371b909 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,132 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What is SPELL + +SPELL (Spacecraft Procedure Execution Language and Library) is a ground software framework for spacecraft operations, developed by SES Engineering. It provides: +- A Python-based **USL (User Script Language)** for writing spacecraft procedures +- A distributed process architecture: Listener → Context → Executor(s) +- A driver layer for connecting to different Ground Control Systems (GCS) + +## Build System + +SPELL uses GNU Autotools (autoconf + automake). The build requires: +- GCC/G++ with pthreads +- Python development headers +- `xerces-c` (XML parsing), `log4cplus` (logging), `librt`, `libdl`, `libutil` +- Optional: `cppunit` (unit tests), `ncurses`+`menu` (command-line executor) + +```bash +# Standard build flow +autoreconf -fi # Generate configure script (if needed) +./configure [options] # Configure the build +make # Build +make install # Install to prefix + +# Configure options (all default to disabled except executor, shell, listener, context): +./configure --enable-executor # Build SPELL-Executor binary (default on) +./configure --enable-context # Build SPELL-Context binary (default on) +./configure --enable-listener # Build SPELL-Shell binary (default on) +./configure --enable-shell # Build SPELL-Shell binary (default on) +./configure --enable-executorcmd # Build command-line executor (requires ncurses) +./configure --enable-gui # Build SPELL-GUI (requires --with-eclipse=PATH) +./configure --enable-driverstd # Build standalone driver +./configure --enable-procs # Include sample procedures +./configure --enable-documentation # Build Doxygen docs +./configure --with-eclipse=PATH # Eclipse installation for GUI build +./configure --with-log4cplus=PATH # log4cplus library path (default: /usr) +``` + +Compiler flags are defined in `common.mk`: includes `$(top_srcdir)/include`, `$SPELL_COTS/include`, Python headers, and log4cplus. All C++ objects are compiled with `-fPIC -g3 -Wall`. + +## Runtime Environment Variables + +Scripts in `scripts/linux/` require these to be set: + +| Variable | Purpose | +|---|---| +| `SPELL_HOME` | Installation root (contains `bin/`, `lib/`, `config/`, `data/`) | +| `SPELL_DATA` | Runtime data directory (defaults to `$SPELL_HOME/data`) | +| `SPELL_CONFIG` | Configuration directory (defaults to `$SPELL_HOME/config`) | + +Source `$SPELL_HOME/bin/setup-environment.sh` to set `LD_LIBRARY_PATH` and other derived variables. + +## Starting the Server + +```bash +$SPELL_HOME/bin/SPELL-Server +# Looks for config at: $SPELL_CONFIG/server/server__.xml +``` + +## Running Unit Tests + +After building with tests enabled: +```bash +$SPELL_HOME/bin/SPELL-RunTests +# Runs all SPELL_unittest_* binaries from $SPELL_HOME/bin/ +# Logs output to $SPELL_HOME/log/unittests_.log +# Test data expected at $SPELL_HOME/data/UnitTests/ +``` + +## Architecture + +### Process Hierarchy + +``` +SPELL-Listener (entry point, port 9980) + └── SPELL-Context (manages spacecraft context, spawns executors) + └── SPELL-Executor (one per running procedure, embeds CPython) +``` + +All processes communicate over TCP sockets using the IPC layer (`lib/SPELL_IPC`). Configuration is loaded from XML files in `config/`. + +### C++ Library Layers (`lib/`) + +| Library | Purpose | +|---|---| +| `SPELL_UTIL` | Utilities (logging, time, string handling) | +| `SPELL_IPC` | Inter-process communication (sockets, message mailboxes) | +| `SPELL_SYN` | Synchronization primitives | +| `SPELL_CFG` | XML configuration loading | +| `SPELL_WRP` | Python/C++ wrapper layer (embeds CPython in executor) | +| `SPELL_EXC` | Execution engine (bytecode analysis, callstack, controller) | +| `SPELL_CTX` | Context management | +| `SPELL_LST` | Listener process logic | +| `SPELL_CIF` | Client interface (GUI-facing) | +| `SPELL_CIFC` / `SPELL_CIFS` | CIF client/server implementations | +| `SPELL_PRD` | Procedure management | +| `SPELL_PRC` | Process control | +| `SPELL_WS` | Warm-start / state persistence | +| `SPELL_SDB` | Spacecraft database access | +| `SPELL_DTA` | Data types and structures | + +Headers for all libraries live in `include/` (mirroring library names). + +### Python Layer (`src/spell/`) + +The `spell` Python package is what procedures import. Key sub-packages: + +- `spell.lang.functions` — USL functions (`Send`, `Verify`, `GetTM`, `BuildTC`, `Prompt`, `StartProc`, `Abort`, etc.) +- `spell.lang.modifiers` — Modifier constants (`OnFailure`, `Timeout`, `Wait`, `ValueFormat`, etc.) +- `spell.lang.constants` — Value constants (e.g., `ENG`, `RAW`, `ABORT`, `SKIP`) +- `spell.lib.adapter` — Abstract base classes for driver interfaces (TC, TM, EV, USR, RSC, MEM, RNG, etc.) +- `spell.lib.registry` — Runtime registry of active driver interface instances +- `spell.utils` — Logging utilities + +### Driver Layer (`drivers/`) + +Drivers implement the `spell.lib.adapter` interfaces for a specific GCS. The `drivers/example/` directory is the reference implementation. Each driver provides modules: `tc.py`, `tm.py`, `ev.py`, `usr.py`, `resources.py`, `task.py`, `config.py`, `modifiers.py`. + +The `drivers/standalone/` driver runs without a GCS (simulator mode). Driver XML config files go in `config/contexts/`. + +### Configuration (`config/`) + +- `config/server/server.xml` — Main server config (ports, executor settings, driver list, context list) +- `config/spell/language.xml` — Default modifier values per USL function +- `config/contexts/context_STD.xml` — Context definition linking to satellite family and driver +- `config/gui/config.xml` — GUI configuration + +### Sample Procedures (`procs/`) + +`procs/procedures/` contains example USL procedures. The `procs/userlib/` directory holds user procedure libraries importable from procedures. diff --git a/INSTALL b/INSTALL index 7d1c323..f214f5f 100644 --- a/INSTALL +++ b/INSTALL @@ -1,365 +1,17 @@ -Installation Instructions -************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008, 2009 Free Software Foundation, Inc. +$ autoreconf -fi +$ mkdir build && cd build +$ ../configure --prefix=/path/to/install/dir - Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. This file is offered as-is, -without warranty of any kind. +If some headers or libraries reside in exotic locations, add CPPFLAGS and LDFLAGS. +Export PATH and LD_LIBRARY_PATH for those libraries to be detected. For example, -Basic Installation -================== +$ SPELL_COTS=/path/to/spell/cots +$ export LD_LIBRARY_PATH=$SPELL_COTS/lib:$LD_LIBRARY_PATH +$ PATH=$SPELL_COTS/bin:$PATH +$ ../configure --prefix=/path/to/install/dir CPPFLAGS="-I$SPELL_COTS/include" LDFLAGS="-L$SPELL_COTS/lib" - Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. Some packages provide this -`INSTALL' file but do not implement all of the features documented -below. The lack of an optional feature in a given package is not -necessarily a bug. More recommendations for GNU packages can be found -in *note Makefile Conventions: (standards)Makefile Conventions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - - The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package, generally using the just-built uninstalled binaries. - - 4. Type `make install' to install the programs and any data files and - documentation. When installing into a prefix owned by root, it is - recommended that the package be configured and built as a regular - user, and only the `make install' phase executed with root - privileges. - - 5. Optionally, type `make installcheck' to repeat any self-tests, but - this time using the binaries in their final installed location. - This target does not install anything. Running this target as a - regular user, particularly if the prior `make install' required - root privileges, verifies that the installation completed - correctly. - - 6. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 7. Often, you can also type `make uninstall' to remove the installed - files again. In practice, not all packages have tested that - uninstallation works correctly, even though it is required by the - GNU Coding Standards. - - 8. Some packages, particularly those that use Automake, provide `make - distcheck', which can by used by developers to test that all other - targets like `make install' and `make uninstall' work correctly. - This target is generally not run by end users. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. This -is known as a "VPATH" build. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - - On MacOS X 10.5 and later systems, you can create libraries and -executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like -this: - - ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CPP="gcc -E" CXXCPP="g++ -E" - - This is not guaranteed to produce working output in all cases, you -may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. - -Installation Names -================== - - By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX', where PREFIX must be an -absolute file name. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. In general, the -default for these options is expressed in terms of `${prefix}', so that -specifying just `--prefix' will affect all of the other directory -specifications that were not explicitly provided. - - The most portable way to affect installation locations is to pass the -correct locations to `configure'; however, many packages provide one or -both of the following shortcuts of passing variable assignments to the -`make install' command line to change installation locations without -having to reconfigure or recompile. - - The first method involves providing an override variable for each -affected directory. For example, `make install -prefix=/alternate/directory' will choose an alternate location for all -directory configuration variables that were expressed in terms of -`${prefix}'. Any directories that were specified during `configure', -but not in terms of `${prefix}', must each be overridden at install -time for the entire installation to be relocated. The approach of -makefile variable overrides for each directory variable is required by -the GNU Coding Standards, and ideally causes no recompilation. -However, some platforms have known limitations with the semantics of -shared libraries that end up requiring recompilation when using this -method, particularly noticeable in packages that use GNU Libtool. - - The second method involves providing the `DESTDIR' variable. For -example, `make install DESTDIR=/alternate/directory' will prepend -`/alternate/directory' before all installation names. The approach of -`DESTDIR' overrides is not required by the GNU Coding Standards, and -does not work on platforms that have drive letters. On the other hand, -it does better at avoiding recompilation issues, and works well even -when some directory options were not specified in terms of `${prefix}' -at `configure' time. - -Optional Features -================= - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - - Some packages offer the ability to configure how verbose the -execution of `make' will be. For these packages, running `./configure ---enable-silent-rules' sets the default to minimal output, which can be -overridden with `make V=1'; while running `./configure ---disable-silent-rules' sets the default to verbose, which can be -overridden with `make V=0'. - -Particular systems -================== - - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in -order to use an ANSI C compiler: - - ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" - -and if that doesn't work, install pre-built binaries of GCC for HP-UX. - - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try - - ./configure CC="cc" - -and if that doesn't work, try - - ./configure CC="cc -nodtk" - - On Solaris, don't put `/usr/ucb' early in your `PATH'. This -directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. - - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: - - ./configure --prefix=/boot/common - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. - -`--help=short' -`--help=recursive' - Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. - -`--no-create' -`-n' - Run the configure checks, but stop before creating any output - files. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. +To enable debugging, add -DWITH_DEBUG to CPPFLAGS. +$ make +$ make install diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Makefile.am b/Makefile.am index 6935578..2e436d2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,34 +1,34 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2012 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ +AUTOMAKE_OPTIONS = subdir-objects foreign + +include ${top_srcdir}/common.mk ACLOCAL_AMFLAGS = -I m4 -AUTOMAKE_OPTIONS = foreign -SUBDIRS = lib drivers src config doc rcp scripts procs data -install-exec-hook: - mkdir -p ${exec_prefix}/log +SUBDIRS = lib drivers src config data scripts +RELEASE_NFO=${exec_prefix}/release.nfo +install-exec-hook: + mkdir -p ${exec_prefix}/log + chmod g+w ${exec_prefix}/log + ${top_srcdir}/scripts/src/generate-release-nfo.sh ${top_srcdir}/RELEASENOTES ${PACKAGE_VERSION} ${exec_prefix} > ${RELEASE_NFO} diff --git a/README b/README deleted file mode 100644 index 1143bda..0000000 --- a/README +++ /dev/null @@ -1,20 +0,0 @@ - - Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. - - This file is part of SPELL. - - SPELL is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - SPELL is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with SPELL. If not, see . - - Comments are welcome. - diff --git a/README.md b/README.md new file mode 100644 index 0000000..bc48c12 --- /dev/null +++ b/README.md @@ -0,0 +1,152 @@ +# SPELL + +**Spacecraft Procedure Execution Language and Library** — a ground software framework for spacecraft operations, developed by SES Engineering. + +> Current version: **2.6.8.4** +> See [RELEASENOTES](RELEASENOTES) for the full changelog. + +## Overview + +SPELL provides: +- A Python-based **USL (User Script Language)** for writing spacecraft procedures +- A distributed process architecture: `SPELL-Listener` → `SPELL-Context` → `SPELL-Executor(s)` +- A driver layer for connecting to different Ground Control Systems (GCS) + +## Requirements + +- GCC/G++ with pthreads (32-bit build: `gcc -m32` / `g++ -m32`) +- Python development headers +- `xerces-c`, `log4cplus`, `librt`, `libdl`, `libutil` +- `SPELL_COTS` environment variable pointing to third-party dependencies directory +- Optional: `cppunit` (unit tests), `ncurses`+`menu` (command-line executor) + +## Building + +### Quick build scripts (recommended) + +```bash +# Standard (32-bit, with submodule proto support) +./build_spell.sh hifly|scorpio|fuzzer|none [extra-configure-flags] + +# Ubuntu (64-bit, with address sanitizer) +./build_spell_ubuntu.sh hifly|scorpio|fuzzer|none [extra-configure-flags] + +# Driver only +./build_driver.sh hifly|scorpio|fuzzer|example [deps] [extra-configure-flags] +``` + +`SPELL_COTS` must be set before running any build script. + +### Manual build (Autotools) + +```bash +autoreconf -fi +mkdir -p build && cd build +../configure --prefix=$SPELL_HOME [options] \ + CPPFLAGS="-I$SPELL_COTS/include" \ + LDFLAGS="-L$SPELL_COTS/lib" +make -j4 && make install +``` + +### Configure options + +| Option | Default | Description | +|---|---|---| +| `--enable-executor` | on | Build SPELL-Executor | +| `--enable-context` | on | Build SPELL-Context | +| `--enable-listener` | on | Build SPELL-Listener | +| `--enable-shell` | on | Build SPELL-Shell | +| `--enable-executorcmd` | off | Command-line executor (requires ncurses) | +| `--enable-gui` | off | SPELL-GUI (requires `--with-eclipse=PATH`) | +| `--enable-hiflydriver` | off | Hifly GCS driver | +| `--enable-scorpiodriver` | off | Scorpio GCS driver | +| `--enable-fuzzerdriver` | off | Fuzzer driver | +| `--enable-exampledriver` | off | Example/reference driver | +| `--enable-driverstd` | off | Standalone driver | +| `--enable-pace` | off | PACE support | +| `--enable-tests` | off | Unit tests (requires cppunit) | +| `--enable-address-sanitizer` | off | Build with AddressSanitizer | +| `--enable-documentation` | off | Doxygen docs | +| `--enable-procs` | off | Sample procedures | +| `--with-eclipse=PATH` | — | Eclipse installation for GUI build | +| `--with-log4cplus=PATH` | `/usr` | log4cplus library path | +| `--with-exif=6` | — | EXIF version (required for hifly driver) | + +## Runtime + +### Environment variables + +| Variable | Purpose | +|---|---| +| `SPELL_HOME` | Installation root (`bin/`, `lib/`, `config/`, `data/`) | +| `SPELL_COTS` | Third-party dependencies root | +| `SPELL_DATA` | Runtime data directory (default: `$SPELL_HOME/data`) | +| `SPELL_CONFIG` | Configuration directory (default: `$SPELL_HOME/config`) | + +Source `$SPELL_HOME/bin/setup-environment.sh` to set `LD_LIBRARY_PATH` and derived variables. + +### Starting the server + +```bash +$SPELL_HOME/bin/SPELL-Server +# Looks for config at: $SPELL_CONFIG/server/server__.xml +``` + +### Running unit tests + +```bash +$SPELL_HOME/bin/SPELL-RunTests +# Runs all SPELL_unittest_* binaries from $SPELL_HOME/bin/ +# Logs to $SPELL_HOME/log/unittests_.log +# Test data expected at $SPELL_HOME/data/UnitTests/ +``` + +## Architecture + +### Process hierarchy + +``` +SPELL-Listener (entry point, default port 9980) + └── SPELL-Context (manages spacecraft context, spawns executors) + └── SPELL-Executor (one per running procedure, embeds CPython) +``` + +All processes communicate over TCP sockets via `lib/SPELL_IPC`. Configuration is loaded from XML files in `config/`. + +### Key directories + +| Directory | Contents | +|---|---| +| `lib/` | C++ libraries (SPELL_EXC, SPELL_IPC, SPELL_WRP, etc.) | +| `include/` | C++ headers mirroring `lib/` structure | +| `src/spell/` | Python `spell` package (USL functions, adapters, utilities) | +| `src/executor/` | SPELL-Executor binary | +| `src/context/` | SPELL-Context binary | +| `src/listener/` | SPELL-Listener binary | +| `drivers/` | GCS driver implementations (example, standalone, and others) | +| `config/` | XML configuration (server, contexts, language defaults) | +| `procs/` | Sample USL procedures | +| `data/` | Runtime data directories (AsRun, Warmstart, Procedures, etc.) | +| `scripts/linux/` | Startup and utility scripts | +| `deploy/` | Kubernetes/Helm deployment manifests | +| `azure_pipelines/` | CI/CD pipeline definitions | + +### Python USL + +Procedures import from the `spell` package: + +```python +from spell.lang.functions import Send, Verify, GetTM, Prompt, Abort +from spell.lang.modifiers import OnFailure, Timeout, Wait +from spell.lang.constants import ENG, RAW, ABORT, SKIP +``` + +### Implementing a driver + +Use `drivers/example/` as the reference. Each driver must implement these modules in its `src/` directory: `tc.py`, `tm.py`, `ev.py`, `usr.py`, `resources.py`, `task.py`, `config.py`, `modifiers.py`. + +## License + +SPELL is distributed under the [GNU General Public License v3](COPYING.GPLv3). Python library components use [LGPLv3](COPYING.LGPLv3). + +Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. diff --git a/RELEASENOTES b/RELEASENOTES new file mode 100644 index 0000000..7dcc485 --- /dev/null +++ b/RELEASENOTES @@ -0,0 +1,332 @@ +--------- +CHANGELOG +--------- + +What's new in SPELL 2.6.8.4 +========================== +** Task + * Fix procedure listener cleanup + * Fix port assignment for on prem deployment + * Fix badly formatted WaitFor + * Fix loading of SCDB and GDB entries + +What's new in SPELL 2.6.8.2 +========================== +** Task + * [SPELL-650] - Issue when taking control of a background (ARC) service running for a long time + +What's new in SPELL 2.6.8.1 +========================== +** Bug + * [SPELL-644] - AOS_TM_TC_MONITOR stuck on ARC BB and SPELL Froze + +** Enhancement + * [SPELL-547] - Containerize SPELL to ease deployment + +What's new in SPELL 2.6.8 +========================== +** Bug + * [SPELL-631] - Merge file import does not read content correctly + * [SPELL-641] - TIME object can't be created using a long anymore + +What's new in SPELL 2.6.7.8 +========================== +** Bug + * [SPELL-640] - SPELL Listener and SPELL context crash on Disconnect + +What's new in SPELL 2.6.7.7 +========================== +** Enhancement + * [SPELL-635] - Implement RestoreNormalLimits using FleetLimits + * [SPELL-637] - allow fleetlimits and archiva to coexist in the driver config + +What's new in SPELL 2.6.7.6 +========================== +** Bug + * [SPELL-636] - SPELL Scorpio driver crashes when loosing connection to GCS + +What's new in SPELL 2.6.7.5 +========================== +** Bug + * [SPELL-631] - Merge file import does not read content correctly + +What's new in SPELL 2.6.7.4 +========================== +** Bug + * [SPELL-625] - IPA_CALIBRATION procedure crashed for MP01 on M2 + * [SPELL-631] - Merge file import does not read content correctly + +** Enhancement + * [FLEET-3342] - Use a clientname to enable sticky sessions + +What's new in SPELL 2.6.7.3 +========================== +** Bug + * [SPELL-626] - PACE activities failing and not being able to reopen in SPELL + +What's new in SPELL 2.6.7.2 +========================== +** Bug + * [SPELL-622] - Regression - Issues with Prompt after ECHO CV Failure + +What's new in SPELL 2.6.7.1 +========================== +** Bug + * [SPELL-622] - Issues with Prompt after ECHO CV Failure + +What's new in SPELL 2.6.7 +========================== +** Bug + * [SPELL-624] - Retry Command Prompts are broken + +What's new in SPELL 2.6.6.5 +========================== +** Bug + * [SPELL-618] - stranded crtxcmdb processes on m2cntl - SPELL false CV failures + +What's new in SPELL 2.6.6.4 +========================== +** Bug + * [SPELL-619] - NORTH_SOUTH_STATIONKEEPING proc crash due to Execution aborted: Key error + +What's new in SPELL 2.6.6.3 +========================== +** Bug + * [SPELL-616] - Undefined error variable in Scoprio driver causes memory corruption in SPELL + +What's new in SPELL 2.6.6.2 +========================== +** Bug + * [SPELL-615] - ORT Uplink Check script failing. (additional fix) + +What's new in SPELL 2.6.6.1 +========================== +** Bug + * [SPELL-615] - ORT Uplink Check script failing. + +What's new in SPELL 2.6.6 +========================== +** Bug + * [SPELL-608] - IPC not connected message for long running procedures + * [SPELL-610] - Recurrent failures trying to acquire ground variables + * [SPELL-611] - Use After Free Crash of scorpio driver interface + * [SPELL-614] - GAR13043-Procedure 31104_North_South_Stationkeeping aborted and could not be unrecovered + +What's new in SPELL 2.6.5.5 +========================== +** Bug + * [SPELL-307] - Sorting of files at the import file viewer/edit calling arguments (Server file selection)Sorting of files at the import file viewer/edit calling arguments (Server file selection) + * [Commit-cb233664787] Fix-regression-in-sce-toggle-functionality + +What's new in SPELL 2.6.5.4 +========================== +** Bug + * [SPELL-599] - SPELL error : Lost connection with executor - Process crashed. + +** New Requirement + * [SPELL-590] - Retrieve and output current limit, msg ab algo version and time stamp and output it in SPELL + * [MPD-705] - Update Lookup_DataObject with Field fswpackage + +What's new in SPELL 2.6.5.3 +========================== +** Enhancement + * [FLEET-720] - Activation of ephemeral and Overlay limits from SPELL + * [SCO-2992] - Trigger TPU restart from SPELL script + +What's new in SPELL 2.6.5.2 +========================== +** Enhancement + * [SCO-3740] - SPELL prompt options after command failure + +What's new in SPELL 2.6.5.1 +========================== +** Bug + * [SES2223-190] - Spell instruction WaitFor cannot be interrupted + +What's new in SPELL 2.6.5 +========================== +** Bug + * [SPELL-582] - Avoid calling doStep when doSkip fails + +What's new in SPELL 2.6.4.3 +========================== +** Bug + * [SPELL-573] - SPELL Crash on Python 3 Abort() + +What's new in SPELL 2.6.4.2 +========================== +** Bug + * [SPELL-571] - Setting DUVs is only supported on the SES Mnemonic + +What's new in SPELL 2.6.4.1 +========================== +** Bug + * [SPELL-557] - SPELL Deadlock when Pausing a Procedure inside a WaitFor with TM checks + * [SPELL-560] - WaitFor TM instruction crashed upon REPEAT + * [SPELL-568] - FleetTM connector is reutrning 999999 as a raw value for DPs + + +** New Requirement + * [SPELL-565] - Ability to set the Spell Execution by STEP in the procedure + +What's new in SPELL 2.6.4 +========================== +** Bug + * [SPELL-554] - Fix SB4000 tduinfo global rewrite + + + ** New Requirement + * [SPELL-517] - SPELL procedure should be able to restore manually applied limits + +What's new in SPELL 2.6.3.3 +========================== +** Enhancement + * [SPELL-551] - Make SPELL driver more robust when accessing Scorpio variables + +What's new in SPELL 2.6.3.2 +========================== +** Hotfix + * [SPELL-549] - SPELL Unable to Read\Set Resources - Fix for endless loop when receiving bad data + +What's new in SPELL 2.6.3.1 +========================== +** Bug + * [SPELL-549] - SPELL Unable to Read\Set Resources + +What's new in SPELL 2.6.3 +========================== +** Bug + * [SPELL-539] - Send ping to Collector + * [SPELL-542] - SetGroundParameter can't be executed + * [SPELL-544] - SPELL did not send all commands during a PACE Bi-weekly operations (PR #261). + +What's new in SPELL 2.6.2.3 +========================== +** Bug + * [SPELL-544] - SPELL did not send all commands during a PACE Bi-weekly operations. + +What's new in SPELL 2.6.2.2 +========================== +** Bug + * [SPELL-537] - Properly handle Collector connection error and failures + * [SPELL-475] - Enable LoadDictionary to load Data from Pharos + +What's new in SPELL 2.6.2.1 +========================== +** Bug + * [SPELL-536] - SPELL SCE toggle error checking mistake success with error + + + ** New Requirement + * [SPELL-475] - Enable LoadDictionary to load Data from Pharos + +What's new in SPELL 2.6.2 +========================== + +** Bug + * [SPELL-505] - Unable to command after a TC failure + * [SPELL-512] - Deadlock caused by ping not receiving any data + + +** New Requirement + * [SPELL-516] - SPELL back-end to query for applied overlay limit files + +** Enhancement + * [SPELL-456] - GCS Enhancement Request - Automated Uplink Checks via SPELL + * [SPELL-484] - Raise an alarm (if possible) if procedure loses connection to context + * [SPELL-527] - Collector interfacing for SES20/21 + * [SPELL-533] - Add bzcesim collector node number to scorpio driver + +What's new in SPELL 2.6.1.1 +========================== + +** Bug + * [SPELL-513] - SPELL failure to command at P2 for AMC18 + +What's new in SPELL 2.6.1 +========================== + +** New Requirement + * [SPELL-457] - New message from SPELL to CWS to request VCC bump + * [SPELL-500] - New SPELL function to retrieve TM packets + +** Bug + * [SPELL-465] - Fix Python3 Memory lookup functions in Scorpio driver + * [SPELL-482] - SPELL crash during SN preparation + * [SPELL-489] - Python3: OpenFile with MODE=WRITE doesn't create a new file + * [SPELL-493] - IVARS and ARGS missing millisecond and microsecond + * [SPELL-496] - SPELL Context locks up when more then one service needs to get started + * [SPELL-506] - Missing import of TIME in the implementation of GetTMPackets makes the SPELL context crash + +** Enhancement + * [SPELL-426] - SPELL resource display (to check and set local TC options) + * [SPELL-455] - SES17: Improve CWS timeout message when TC packets are pending + * [SPELL-464] - Catch Common key/value parsing errors + * [SPELL-471] - Add M1/M2 node names + * [SPELL-473] - Add proto Git submodule + * [SPELL-494] - Improve SPELL Scorpio driver to make available exception messages to ARC + * [SPELL-507] - Meaningful error message on SCE toggle driver function error + * [SPELL-508] - Do not enforce the Collector availability for a procedure to run with mPower + * [SPELL-510] - Helper wrapping library to easily make GPS communication in Scorpio Driver + +What's new in SPELL 2.6.0.1 +========================== + +** Bug + * [SPELL-466] - SN1313: Process crashed during manoeuvre set up + +What's new in SPELL 2.6.0 +========================== + +** New Requirement + * [SPELL-337] - Make SPELL Python 3 compatible + * [SPELL-338] - Implement SES17 command capability + * [SPELL-344] - New SPELL functions to access Ground DTP Image + +** Bug + * [SPELL-281] - Don't do busy waiting while trying to receive an Ack in Scorpio driver + * [SPELL-340] - No audible for Spell Prompts + * [SPELL-356] - SES17 SetResource doesn't work and gives SPELL exeception + * [SPELL-357] - PACE alarm : Backup seat GE (g2anal02) not reachable: listener: login: send request: response timeout) + * [SPELL-358] - AMC07 & AMC08 SPELL Crash During BATMON Script + * [SPELL-359] - P.A3B.SEASON_MANAGEMENT procedure got stuck in the WaitFor statement + * [SPELL-365] - SPELL WaitFor TM crashes when there are issues + * [SPELL-373] - SPELl Service not copmpatible with Python3 + * [SPELL-377] - Prompt will cuase SPELL v3 to crash + * [SPELL-383] - GOTO doesn't work on Python 3 + * [SPELL-388] - Update STC.i for increased commanding buffer + * [SPELL-389] - Default sec/millis must be positive + * [SPELL-390] - Setting further TC options fails after encryption is set to ON + * [SPELL-392] - Python 3 breaks the Watch variables feature + * [SPELL-393] - SaveDictionary is not python 3 compatible + * [SPELL-394] - SPELL Warmstart crashes on throwing an excpetion within SPELL library code + * [SPELL-395] - SetUserAction crashes in Python 3 + * [SPELL-396] - SendDelay/ReleaseTime modifiers don't work + * [SPELL-398] - Group command sending fails + * [SPELL-399] - mPower - big command crashes procedure + * [SPELL-401] - The Dynamic GRPCThreadPool used for GRPC connections and the SPELL Service is not working in Python 3 + * [SPELL-403] - LoadExternalData doesn't work in new SPELL version + * [SPELL-406] - BuildTC command options are dropped in a command group of size one + * [SPELL-407] - SPELL-Driver start-up fails due to relative and missing imports + * [SPELL-413] - PACE: SPELL-Driver does not like relative parts + * [SPELL-430] - FleetTM output bus: With Wait=True, gRPC timeout does not work + * [SPELL-434] - SES17/mPower: Reset TC group after skip/cancel Prompt (Q, K, C) + * [SPELL-451] - Add missing sc= keyword in the GPS message + * [SPELL-460] - SES17 TC acceptance: n/a messges are not correctly handled resulting in timeouts + * [SPELL-463] - Long CWS messages crash Common client in the driver + +** Enhancement + * [SPELL-341] - FLEET - Enable SPELL access to PHAROS + * [SPELL-346] - Kill SPELL-Service as well when stopping SPELL + * [SPELL-348] - Add mission name to SPELL driver log file name + * [SPELL-354] - Add subschedule_id flag to SBNEO time tag command format + * [SPELL-370] - Add millisecond support for SES17 (SBNEO) platform + * [SPELL-371] - Make TC options and other ground resources local to the procedure + * [SPELL-372] - Update Scorpio TM Archiva interface to new Python3 module + * [SPELL-376] - Notify = False is not implemented for BuildTC + * [SPELL-385] - Teach mPower/sbneo drivers to use the convert_arguments_validate function + * [SPELL-391] - Add TC acceptance & verification flags to SBNEO + * [SPELL-429] - FleetTM output bus: Add gRPC request retries before throwing an exception + * [SPELL-433] - Check CWS request buffer size to avoid overflow in Common and STC + * [SPELL-453] - Refresh GPS connections after (long) commanding to avoid disconnections + * [SPELL-454] - Make Handle exception inherit from Exception diff --git a/SPELL Debug.launch b/SPELL Debug.launch new file mode 100644 index 0000000..7cd2f83 --- /dev/null +++ b/SPELL Debug.launch @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/azure_pipelines/ci_logrotate.yaml b/azure_pipelines/ci_logrotate.yaml new file mode 100644 index 0000000..2403643 --- /dev/null +++ b/azure_pipelines/ci_logrotate.yaml @@ -0,0 +1,139 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + + +trigger: + branches: + include: + - develop + paths: + include: + - azure_pipelines/variables/logrotate.yaml + - azure_pipelines/variables/baseline.yaml + - azure_pipelines/ci_logrotate.yaml + - docker/logrotate/** + + +name: "SPELL Logrotate CI Pipeline" + +pool: + name: weu1-d-keda + +variables: +- template: variables/baseline.yaml +- name: tags + value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)" +- name: DOCKER_BUILDKIT + value: 1 +- name: NODE_TLS_REJECT_UNAUTHORIZED + value: 0 +- template: variables/logrotate.yaml +- group: nexus-auth +- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE + value: neuvector/scanner +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL + value: https://docker-weu.spo.internal.ses.com +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) + +stages: +- stage: + displayName: Nexus IQ Check + jobs: + - job: + displayName: Docker image + steps: + - task: Bash@3 + displayName: Extract Version + inputs: + targetType: inline + script: | + get_next_version() { + local increment_type="$1" + local RE='([0-9]*)[.]([0-9]*)[.]([0-9]*)([.-][0-9A-Za-z.-]+)?' + + if [ -z "$increment_type" ]; then + increment_type="patch" + fi + if [[ "$2" =~ $RE ]]; then + local MAJOR="${BASH_REMATCH[1]}" + local MINOR="${BASH_REMATCH[2]}" + local PATCH="${BASH_REMATCH[3]}" + local pre="" + else + local MAJOR=0 + local MINOR=0 + local PATCH=0 + local pre="" + fi + + case "$increment_type" in + major) + ((MAJOR += 1)) + ((MINOR = 0)) + ((PATCH = 0)) + ;; + minor) + ((MINOR += 1)) + ((PATCH = 0)) + ;; + patch) + ((PATCH += 1)) + ;; + esac + + local NEXT_VERSION="$MAJOR.$MINOR.$PATCH" + echo "$NEXT_VERSION" + } + + HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD} + VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG} + TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT} + if [[ "$HEAD" != "$TAG_COMMIT" ]] + then + VERSION_TAG=`get_next_version patch ${VERSION_TAG}` + fi + echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG" + echo "ADO Tag: $(tags)" + echo "New Version to be built: ${VERSION_TAG}" + + workingDirectory: "$(system.defaultWorkingDirectory)/" + - task: Docker@2 + displayName: Build + inputs: + command: build + repository: "$(DOCKER_IMAGE)" + containerRegistry: "$(NEXUS_REGISTRY)" + buildContext: "**$(DOCKER_BUILD_CONTEXT)" + Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile" + tags: "$(VERSION_TAG)" + arguments: "--build-arg RUNTIME_IMAGE=$(RUNTIME_IMAGE) --build-arg BUILD_IMAGE=$(BUILD_IMAGE) --build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)" + - task: Docker@2 + displayName: Push + inputs: + command: push + repository: "$(DOCKER_IMAGE)" + containerRegistry: "$(NEXUS_REGISTRY)" + tags: "$(VERSION_TAG)" + - task: NexusIqPipelineTask@1 + continueOnError: true + env: + NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + inputs: + nexusIqService: 'nexus-iq' + organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a' + applicationId: '$(NEXUS_APPLICATION)' + stage: 'Build' + scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)' + enableDebugLogging: true + ignoreSystemError: true + ignoreScanningError: true \ No newline at end of file diff --git a/azure_pipelines/ci_spell_driver_scorpio.yaml b/azure_pipelines/ci_spell_driver_scorpio.yaml new file mode 100644 index 0000000..0a29170 --- /dev/null +++ b/azure_pipelines/ci_spell_driver_scorpio.yaml @@ -0,0 +1,139 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +trigger: + branches: + include: + - develop + paths: + include: + - azure_pipelines/variables/spell_driver_scorpio.yaml + - azure_pipelines/variables/baseline.yaml + - azure_pipelines/ci_spell_driver_scorpio.yaml + - drivers/scorpio/** + - docker/drivers/scorpio/** + - include/** + +name: "SPELL Scorpio Driver CI Pipeline" + +pool: + name: weu1-d-keda + +variables: +- template: variables/baseline.yaml +- name: tags + value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)" +- name: DOCKER_BUILDKIT + value: 1 +- name: NODE_TLS_REJECT_UNAUTHORIZED + value: 0 +- template: variables/spell_driver_scorpio.yaml +- group: nexus-auth +- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE + value: neuvector/scanner +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL + value: https://docker-weu.spo.internal.ses.com +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) + +stages: +- stage: + displayName: Nexus IQ Check + jobs: + - job: + displayName: Docker image + steps: + - task: Bash@3 + displayName: Extract Version + inputs: + targetType: inline + script: | + get_next_version() { + local increment_type="$1" + local RE='([0-9]*)[.]([0-9]*)[.]([0-9]*)([.-][0-9A-Za-z.-]+)?' + + if [ -z "$increment_type" ]; then + increment_type="patch" + fi + if [[ "$2" =~ $RE ]]; then + local MAJOR="${BASH_REMATCH[1]}" + local MINOR="${BASH_REMATCH[2]}" + local PATCH="${BASH_REMATCH[3]}" + local pre="" + else + local MAJOR=0 + local MINOR=0 + local PATCH=0 + local pre="" + fi + + case "$increment_type" in + major) + ((MAJOR += 1)) + ((MINOR = 0)) + ((PATCH = 0)) + ;; + minor) + ((MINOR += 1)) + ((PATCH = 0)) + ;; + patch) + ((PATCH += 1)) + ;; + esac + + local NEXT_VERSION="$MAJOR.$MINOR.$PATCH" + echo "$NEXT_VERSION" + } + + HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD} + VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG} + TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT} + if [[ "$HEAD" != "$TAG_COMMIT" ]] + then + VERSION_TAG=`get_next_version patch ${VERSION_TAG}` + fi + echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG" + echo "ADO Tag: $(tags)" + echo "New Version to be built: ${VERSION_TAG}" + + workingDirectory: "$(system.defaultWorkingDirectory)/" + - task: Docker@2 + displayName: Build + inputs: + command: build + repository: "$(DOCKER_IMAGE)" + containerRegistry: "$(NEXUS_REGISTRY)" + buildContext: "**$(DOCKER_BUILD_CONTEXT)" + Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile" + tags: "$(VERSION_TAG)" + arguments: "--build-arg RUNTIME_IMAGE=$(RUNTIME_IMAGE) --build-arg BUILD_IMAGE=$(BUILD_IMAGE) --build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)" + - task: Docker@2 + displayName: Push + inputs: + command: push + repository: "$(DOCKER_IMAGE)" + containerRegistry: "$(NEXUS_REGISTRY)" + tags: "$(VERSION_TAG)" + - task: NexusIqPipelineTask@1 + continueOnError: true + env: + NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + inputs: + nexusIqService: 'nexus-iq' + organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a' + applicationId: '$(NEXUS_APPLICATION)' + stage: 'Build' + scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)' + enableDebugLogging: true + ignoreSystemError: true + ignoreScanningError: true diff --git a/azure_pipelines/ci_spell_registry.yaml b/azure_pipelines/ci_spell_registry.yaml new file mode 100644 index 0000000..4e378ed --- /dev/null +++ b/azure_pipelines/ci_spell_registry.yaml @@ -0,0 +1,158 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + + +trigger: + branches: + include: + - develop + paths: + include: + - azure_pipelines/variables/spell_registry.yaml + - azure_pipelines/variables/baseline.yaml + - azure_pipelines/ci_spell_registry.yaml + - docker/spell-registry/** + +name: "SPELL Registry CI Pipeline" + +pool: + name: weu1-d-keda + +variables: +- template: variables/baseline.yaml +- name: tags + value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)" +- name: DOCKER_BUILDKIT + value: 1 +- name: NODE_TLS_REJECT_UNAUTHORIZED + value: 0 +- template: variables/spell_registry.yaml +- group: nexus-auth +- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE + value: neuvector/scanner +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL + value: https://docker-weu.spo.internal.ses.com +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) + +stages: +- stage: + displayName: Nexus IQ Check + jobs: + - job: + displayName: Docker image + steps: + - task: Bash@3 + displayName: Extract Version + inputs: + targetType: inline + script: | + get_next_version() { + local increment_type="$1" + local RE='v?[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)' + + if [ -z "$increment_type" ]; then + increment_type="patch" + fi + + local base=$(node -pe 'require("./package.json")["version"]') + + local MAJOR=$(echo $base | sed -e "s#$RE#\1#") + local MINOR=$(echo $base | sed -e "s#$RE#\2#") + local PATCH=$(echo $base | sed -e "s#$RE#\3#") + local HOTFIX=$(echo $base | sed -e "s#$RE#\4#") + + case "$increment_type" in + major) + ((MAJOR += 1)) + ((MINOR = 0)) + ((PATCH = 0)) + ((HOTFIX = 0)) + ;; + minor) + ((MINOR += 1)) + ((PATCH = 0)) + ((HOTFIX = 0)) + ;; + patch) + ((PATCH += 1)) + ((HOTFIX = 0)) + ;; + hotfix) + ((HOTFIX += 1)) + ;; + esac + + local NEXT_VERSION="$MAJOR.$MINOR.$PATCH.$HOTFIX" + echo "$NEXT_VERSION" + } + + HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD} + VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG} + TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT} + if [[ "$HEAD" != "$TAG_COMMIT" ]] + then + VERSION_TAG=${VERSION_TAG}-dev + fi + echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG" + echo "ADO Tag: $(tags)" + + workingDirectory: "$(system.defaultWorkingDirectory)/" + - task: Docker@2 + inputs: + containerRegistry: 'nexus-docker-weu' + command: 'login' + - task: Bash@3 + displayName: Build + inputs: + targetType: inline + script: | + export HTTP_PROXY=$(PROXY) + export HTTPS_PROXY=$(PROXY) + export NO_PROXY=$(NO_PROXY) + cd $(DOCKER_FILEPATH) + ls -al + echo $(PWD) + docker pull docker-weu.spo.internal.ses.com/eclipse-temurin:19.0.1_10-jre-alpine + docker run --rm -e VERSION=$(VERSION_TAG) -e http_proxy=$(PROXY) -e https_proxy=$(PROXY) -e no_proxy=$(NO_PROXY) -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v `pwd`:/app -w /app $(BUILD_IMAGE) sbt docker:publishLocal + + workingDirectory: "$(system.defaultWorkingDirectory)/" + + # - task: Docker@2 + # displayName: Build + # inputs: + # command: build + # repository: "$(DOCKER_IMAGE)" + # containerRegistry: "$(NEXUS_REGISTRY)" + # buildContext: "**$(DOCKER_BUILD_CONTEXT)" + # Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile" + # tags: "$(VERSION_TAG)" + # arguments: "--build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)" + - task: Docker@2 + displayName: Push + inputs: + command: push + repository: "$(DOCKER_IMAGE)" + containerRegistry: "$(NEXUS_REGISTRY)" + tags: "$(VERSION_TAG)" + - task: NexusIqPipelineTask@1 + env: + NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + inputs: + nexusIqService: 'nexus-iq' + organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a' + applicationId: '$(NEXUS_APPLICATION)' + stage: 'Build' + scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)' + enableDebugLogging: true + ignoreSystemError: true + ignoreScanningError: true diff --git a/azure_pipelines/ci_spell_server.yaml b/azure_pipelines/ci_spell_server.yaml new file mode 100644 index 0000000..3b1f681 --- /dev/null +++ b/azure_pipelines/ci_spell_server.yaml @@ -0,0 +1,147 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +trigger: + branches: + include: + - develop + paths: + include: + - azure_pipelines/variables/spell_server.yaml + - azure_pipelines/variables/baseline.yaml + - azure_pipelines/ci_spell_server.yaml + - lib/** + - src/** + - include/** + - configure.ac + - RELEASENOTES + - build_spell_ubuntu.sh + - docker/spell-server/** + - proto/** + - protos/** + + +name: "SPELL Server CI Pipeline" + +pool: + name: weu1-d-keda + +variables: +- template: variables/baseline.yaml +- name: tags + value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)" +- name: DOCKER_BUILDKIT + value: 1 +- name: NODE_TLS_REJECT_UNAUTHORIZED + value: 0 +- template: variables/spell_server.yaml +- group: nexus-auth +- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE + value: neuvector/scanner +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL + value: https://docker-weu.spo.internal.ses.com +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) + + +stages: +- stage: + displayName: Nexus IQ Check + jobs: + - job: + displayName: Docker image + steps: + - task: Bash@3 + displayName: Extract Version + inputs: + targetType: inline + script: | + get_next_version() { + local increment_type="$1" + local RE='([0-9]*)[.]([0-9]*)[.]([0-9]*)([.-][0-9A-Za-z.-]+)?' + + if [ -z "$increment_type" ]; then + increment_type="patch" + fi + if [[ "$2" =~ $RE ]]; then + local MAJOR="${BASH_REMATCH[1]}" + local MINOR="${BASH_REMATCH[2]}" + local PATCH="${BASH_REMATCH[3]}" + local pre="" + else + local MAJOR=0 + local MINOR=0 + local PATCH=0 + local pre="" + fi + + case "$increment_type" in + major) + ((MAJOR += 1)) + ((MINOR = 0)) + ((PATCH = 0)) + ;; + minor) + ((MINOR += 1)) + ((PATCH = 0)) + ;; + patch) + ((PATCH += 1)) + ;; + esac + + local NEXT_VERSION="$MAJOR.$MINOR.$PATCH" + echo "$NEXT_VERSION" + } + + HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD} + VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG} + TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT} + if [[ "$HEAD" != "$TAG_COMMIT" ]] + then + VERSION_TAG=`get_next_version patch ${VERSION_TAG}` + fi + echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG" + echo "ADO Tag: $(tags)" + echo "New Version to be built: ${VERSION_TAG}" + + workingDirectory: "$(system.defaultWorkingDirectory)/" + - task: Docker@2 + displayName: Build + inputs: + command: build + repository: "$(DOCKER_IMAGE)" + containerRegistry: "$(NEXUS_REGISTRY)" + buildContext: "**$(DOCKER_BUILD_CONTEXT)" + Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile" + tags: "$(VERSION_TAG)" + arguments: "--build-arg RUNTIME_IMAGE=$(RUNTIME_IMAGE) --build-arg VERSION_TAG=$(VERSION_TAG) --build-arg BUILD_IMAGE=$(BUILD_IMAGE) --build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)" + - task: Docker@2 + displayName: Push + inputs: + command: push + repository: "$(DOCKER_IMAGE)" + containerRegistry: "$(NEXUS_REGISTRY)" + tags: "$(VERSION_TAG)" + - task: NexusIqPipelineTask@1 + continueOnError: true + env: + NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + inputs: + nexusIqService: 'nexus-iq' + organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a' + applicationId: '$(NEXUS_APPLICATION)' + stage: 'Build' + scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)' + enableDebugLogging: true + ignoreSystemError: true + ignoreScanningError: true diff --git a/azure_pipelines/ci_spell_ssh.yaml b/azure_pipelines/ci_spell_ssh.yaml new file mode 100644 index 0000000..50f3b6f --- /dev/null +++ b/azure_pipelines/ci_spell_ssh.yaml @@ -0,0 +1,139 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + + +trigger: + branches: + include: + - develop + paths: + include: + - azure_pipelines/variables/spell_ssh.yaml + - azure_pipelines/variables/baseline.yaml + - azure_pipelines/ci_spell_ssh.yaml + - docker/ssh-server/** + + +name: "SPELL SSH Server CI Pipeline" + +pool: + name: weu1-d-keda + +variables: +- template: variables/baseline.yaml +- name: tags + value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)" +- name: DOCKER_BUILDKIT + value: 1 +- name: NODE_TLS_REJECT_UNAUTHORIZED + value: 0 +- template: variables/spell_ssh.yaml +- group: nexus-auth +- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE + value: neuvector/scanner +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL + value: https://docker-weu.spo.internal.ses.com +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER + value: $(NEXUS_USER) +- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD + value: $(NEXUS_PASSWORD) + +stages: +- stage: + displayName: Nexus IQ Check + jobs: + - job: + displayName: Docker image + steps: + - task: Bash@3 + displayName: Extract Version + inputs: + targetType: inline + script: | + get_next_version() { + local increment_type="$1" + local RE='([0-9]*)[.]([0-9]*)[.]([0-9]*)([.-][0-9A-Za-z.-]+)?' + + if [ -z "$increment_type" ]; then + increment_type="patch" + fi + if [[ "$2" =~ $RE ]]; then + local MAJOR="${BASH_REMATCH[1]}" + local MINOR="${BASH_REMATCH[2]}" + local PATCH="${BASH_REMATCH[3]}" + local pre="" + else + local MAJOR=0 + local MINOR=0 + local PATCH=0 + local pre="" + fi + + case "$increment_type" in + major) + ((MAJOR += 1)) + ((MINOR = 0)) + ((PATCH = 0)) + ;; + minor) + ((MINOR += 1)) + ((PATCH = 0)) + ;; + patch) + ((PATCH += 1)) + ;; + esac + + local NEXT_VERSION="$MAJOR.$MINOR.$PATCH" + echo "$NEXT_VERSION" + } + + HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD} + VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG} + TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT} + if [[ "$HEAD" != "$TAG_COMMIT" ]] + then + VERSION_TAG=`get_next_version patch ${VERSION_TAG}` + fi + echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG" + echo "ADO Tag: $(tags)" + echo "New Version to be built: ${VERSION_TAG}" + + workingDirectory: "$(system.defaultWorkingDirectory)/" + - task: Docker@2 + displayName: Build + inputs: + command: build + repository: "$(DOCKER_IMAGE)" + containerRegistry: "$(NEXUS_REGISTRY)" + buildContext: "**$(DOCKER_BUILD_CONTEXT)" + Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile" + tags: "$(VERSION_TAG)" + arguments: "--build-arg RUNTIME_IMAGE=$(RUNTIME_IMAGE) --build-arg BUILD_IMAGE=$(BUILD_IMAGE) --build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)" + - task: Docker@2 + displayName: Push + inputs: + command: push + repository: "$(DOCKER_IMAGE)" + containerRegistry: "$(NEXUS_REGISTRY)" + tags: "$(VERSION_TAG)" + - task: NexusIqPipelineTask@1 + continueOnError: true + env: + NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD) + inputs: + nexusIqService: 'nexus-iq' + organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a' + applicationId: '$(NEXUS_APPLICATION)' + stage: 'Build' + scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)' + enableDebugLogging: true + ignoreSystemError: true + ignoreScanningError: true \ No newline at end of file diff --git a/azure_pipelines/variables/baseline.yaml b/azure_pipelines/variables/baseline.yaml new file mode 100644 index 0000000..42845a7 --- /dev/null +++ b/azure_pipelines/variables/baseline.yaml @@ -0,0 +1,8 @@ +variables: + NEXUS_REGISTRY: nexus-docker-weu + NEXUS_REGISTRY_URL: docker-weu.spo.internal.ses.com + BUILD_IMAGE: docker-weu.spo.internal.ses.com/spell/spell-cots-ubuntu-build:1.0.1 + RUNTIME_IMAGE: docker-weu.spo.internal.ses.com/spell/spell-cots-ubuntu-runtime:1.0.1 + PROXY: "${HTTPS_PROXY}" + NO_PROXY: "${NO_PROXY}" + \ No newline at end of file diff --git a/azure_pipelines/variables/logrotate.yaml b/azure_pipelines/variables/logrotate.yaml new file mode 100644 index 0000000..1db6d1f --- /dev/null +++ b/azure_pipelines/variables/logrotate.yaml @@ -0,0 +1,5 @@ +variables: + DOCKER_FILEPATH: docker/logrotate + DOCKER_IMAGE: spell/logrotate-ubuntu + NEXUS_APPLICATION: spell-logrotate + DOCKER_BUILD_CONTEXT: "" \ No newline at end of file diff --git a/azure_pipelines/variables/spell_driver_scorpio.yaml b/azure_pipelines/variables/spell_driver_scorpio.yaml new file mode 100644 index 0000000..26d1700 --- /dev/null +++ b/azure_pipelines/variables/spell_driver_scorpio.yaml @@ -0,0 +1,5 @@ +variables: + DOCKER_FILEPATH: docker/drivers/scorpio + DOCKER_IMAGE: spell/spell-driver-ubuntu-scorpio + NEXUS_APPLICATION: spell-scorpio-driver + DOCKER_BUILD_CONTEXT: "/../" \ No newline at end of file diff --git a/azure_pipelines/variables/spell_registry.yaml b/azure_pipelines/variables/spell_registry.yaml new file mode 100644 index 0000000..627aec2 --- /dev/null +++ b/azure_pipelines/variables/spell_registry.yaml @@ -0,0 +1,8 @@ +variables: + DOCKER_FILEPATH: docker/spell-registry + DOCKER_IMAGE: spell/spell-registry + NEXUS_APPLICATION: spell-registry + DOCKER_BUILD_CONTEXT: "." + BUILD_IMAGE: docker-weu.spo.internal.ses.com/sbtscala/scala-sbt:eclipse-temurin-19_36_1.8.0_3.2.1 + #scala-sbt:eclipse-temurin-focal-17.0.10_7_1.9.9_3.4.0 + \ No newline at end of file diff --git a/azure_pipelines/variables/spell_server.yaml b/azure_pipelines/variables/spell_server.yaml new file mode 100644 index 0000000..b359dc8 --- /dev/null +++ b/azure_pipelines/variables/spell_server.yaml @@ -0,0 +1,5 @@ +variables: + DOCKER_FILEPATH: docker/spell-server + DOCKER_IMAGE: spell/spell-server-ubuntu + NEXUS_APPLICATION: spell-server + DOCKER_BUILD_CONTEXT: "/../" \ No newline at end of file diff --git a/azure_pipelines/variables/spell_ssh.yaml b/azure_pipelines/variables/spell_ssh.yaml new file mode 100644 index 0000000..29aebca --- /dev/null +++ b/azure_pipelines/variables/spell_ssh.yaml @@ -0,0 +1,5 @@ +variables: + DOCKER_FILEPATH: docker/ssh-server + DOCKER_IMAGE: spell/ssh-server-ubuntu + NEXUS_APPLICATION: spell-ssh-server + DOCKER_BUILD_CONTEXT: "" \ No newline at end of file diff --git a/build_driver.sh b/build_driver.sh new file mode 100644 index 0000000..1a3c113 --- /dev/null +++ b/build_driver.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +function die() { + echo -e >&2 "ERROR: $@" + echo "Usage: $(basename $0) install-path hifly|scorpio|fuzzer" + exit 1 +} + +# sanity checks +[ $# -ge 2 ] || die "Invalid arguments.\n\ +Please specify installation path and the driver." +SPELL_HOME=$1 +[ -d $SPELL_HOME ] || die "cannot find the given installation directory: $SPELL_HOME" + +shift +DRIVER=$1 +[[ "$DRIVER" == "hifly" ]] || [[ "$DRIVER" == "scorpio" ]] || [[ "$DRIVER" == "fuzzer" ]] || [[ "$DRIVER" == "example" ]] || die "Unknown driver \"$DRIVER\"" +shift +DEPS=$1 +shift + +! [ -z $SPELL_COTS ] || die "Set SPELL_COTS environment variable" +[ -d $SPELL_COTS ] || die "cannot find the SPELL_COTS directory: $SPELL_COTS" +[ "$(ls -A $SPELL_COTS)" ] || die "SPELL_COTS directory $SPELL_COTS is empty" + +export LD_LIBRARY_PATH=$SPELL_COTS/lib +export PATH=$SPELL_COTS/bin:$PATH + + +if [[ "$DRIVER" == "hifly" ]]; then + DRIVER="--enable-hiflydriver --with-exif=6" + DRIVER_FOLDER="hifly2" +elif [[ "$DRIVER" == "scorpio" ]]; then + DRIVER="--enable-scorpiodriver" + DRIVER_FOLDER="scorpio" +elif [[ "$DRIVER" == "fuzzer" ]]; then + DRIVER="--enable-fuzzerdriver" + DRIVER_FOLDER="fuzzer" +elif [[ "$DRIVER" == "example" ]]; then + DRIVER="--enable-exampledriver" + DRIVER_FOLDER="example" +fi + +autoreconf -fi .|| die "autoreconf failed!" +mkdir -p build +rm -rf build/* > /dev/null 2>&1 +cd build +set -x +LSAN_OPTIONS=verbosity=1:log_threads=1 ASAN_OPTIONS=halt_on_error=0 ../configure --disable-dependency-tracking --enable-address-sanitizer --prefix=$SPELL_HOME $DRIVER --enable-pace CPPFLAGS="-w -I$SPELL_COTS/include $@" LDFLAGS="-Wl,--copy-dt-needed-entries -L$SPELL_COTS/lib" + +for dep in ${DEPS}; do + pushd lib/${dep} + make -j4 -s && make install + popd +done + +cd drivers/${DRIVER_FOLDER} +set +x +make -j4 -s && make install diff --git a/build_spell.sh b/build_spell.sh new file mode 100644 index 0000000..fb5099a --- /dev/null +++ b/build_spell.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +function die() { + echo -e >&2 "ERROR: $@" + echo "Usage: $(basename $0) install-path hifly|scorpio|fuzzer" + exit 1 +} + +# sanity checks +[ $# -ge 2 ] || die "Invalid arguments.\n\ +Please specify installation path and the driver." +SPELL_HOME=$1 +[ -d $SPELL_HOME ] || die "cannot find the given installation directory: $SPELL_HOME" +! [ "$(ls -A $SPELL_HOME)" ] || die "installation directory $SPELL_HOME must be empty" +shift +DRIVER=$1 +[[ "$DRIVER" == "hifly" ]] || [[ "$DRIVER" == "scorpio" ]] || [[ "$DRIVER" == "fuzzer" ]] || [[ "$DRIVER" == "none" ]] || die "Unknown driver \"$DRIVER\"" +shift + +! [ -z $SPELL_COTS ] || die "Set SPELL_COTS environment variable" +[ -d $SPELL_COTS ] || die "cannot find the SPELL_COTS directory: $SPELL_COTS" +[ "$(ls -A $SPELL_COTS)" ] || die "SPELL_COTS directory $SPELL_COTS is empty" + +export LD_LIBRARY_PATH=$SPELL_COTS/lib +export PATH=$SPELL_COTS/bin:$PATH + +export CC="gcc -m32" +export CXX="g++ -m32" + +if [[ "$DRIVER" == "hifly" ]]; then + DRIVER="--enable-hiflydriver --with-exif=6" +elif [[ "$DRIVER" == "scorpio" ]]; then + DRIVER="--enable-scorpiodriver" +elif [[ "$DRIVER" == "fuzzer" ]]; then + DRIVER="--enable-fuzzerdriver" +elif [[ "$DRIVER" == "none" ]]; then + DRIVER="" +fi + +git submodule init +git submodule update +cd proto +git checkout develop +cd .. + +autoreconf -fi +mkdir -p build +rm -rf build/* > /dev/null 2>&1 +cd build +set -x +../configure --prefix=$SPELL_HOME $DRIVER --enable-pace CPPFLAGS="-std=c++11 -I$SPELL_COTS/include $@" LDFLAGS="-L$SPELL_COTS/lib" +set +x +make -j4 -s && make install diff --git a/build_spell_ubuntu.sh b/build_spell_ubuntu.sh new file mode 100644 index 0000000..f80f2db --- /dev/null +++ b/build_spell_ubuntu.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +function die() { + echo -e >&2 "ERROR: $@" + echo "Usage: $(basename $0) install-path hifly|scorpio|fuzzer" + exit 1 +} + +# sanity checks +[ $# -ge 2 ] || die "Invalid arguments.\n\ +Please specify installation path and the driver." +SPELL_HOME=$1 +[ -d $SPELL_HOME ] || die "cannot find the given installation directory: $SPELL_HOME" +! [ "$(ls -A $SPELL_HOME)" ] || die "installation directory $SPELL_HOME must be empty" +shift +DRIVER=$1 +[[ "$DRIVER" == "hifly" ]] || [[ "$DRIVER" == "scorpio" ]] || [[ "$DRIVER" == "fuzzer" ]] || [[ "$DRIVER" == "none" ]] || die "Unknown driver \"$DRIVER\"" +shift + +! [ -z $SPELL_COTS ] || die "Set SPELL_COTS environment variable" +[ -d $SPELL_COTS ] || die "cannot find the SPELL_COTS directory: $SPELL_COTS" +[ "$(ls -A $SPELL_COTS)" ] || die "SPELL_COTS directory $SPELL_COTS is empty" + +export LD_LIBRARY_PATH=$SPELL_COTS/lib +export PATH=$SPELL_COTS/bin:$PATH + +if [[ "$DRIVER" == "hifly" ]]; then + DRIVER="--enable-hiflydriver --with-exif=6" +elif [[ "$DRIVER" == "scorpio" ]]; then + DRIVER="--enable-scorpiodriver" +elif [[ "$DRIVER" == "fuzzer" ]]; then + DRIVER="--enable-fuzzerdriver" +elif [[ "$DRIVER" == "none" ]]; then + DRIVER="" +fi + +mkdir -p build +rm -rf build/* > /dev/null 2>&1 + + +autoreconf -fi . || die "autoconf failed" + +cd build +set -x +../configure --enable-address-sanitizer --prefix=$SPELL_HOME $DRIVER --enable-pace CPPFLAGS="-I$SPELL_COTS/include -fno-omit-frame-pointer $@" LDFLAGS="-rdynamic -ldw -Wl,--copy-dt-needed-entries -L$SPELL_COTS/lib" || die "configure failed" +set +x +make -j4 -s || die "build failed" + +make install || die "install failed" diff --git a/common.mk b/common.mk index e9701b6..b0d85e1 100644 --- a/common.mk +++ b/common.mk @@ -1,11 +1,11 @@ ################################################################################### ## FILE : common.mk -## DATE : Mar 17, 2011 +## DATE : May 11, 2017 ## PROJECT : SPELL -## DESCRIPTION: Automake rules +## DESCRIPTION: Common compilation and linking flags ## -------------------------------------------------------------------------------- ## -## Copyright (C) 2008, 2012 SES ENGINEERING, Luxembourg S.A.R.L. +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. ## ## This file is part of SPELL. ## @@ -23,10 +23,7 @@ ## along with SPELL. If not, see . ## ################################################################################### - -AUTOMAKE_OPTIONS=foreign -#REMOVED -O2 -AM_CPPFLAGS = -I$(top_srcdir)/include -I${SPELL_COTS}/include $(PYTHON_CPPFLAGS) -I${WITH_LOG4CPLUS}/include -fPIC -fno-strict-aliasing -g3 -Wall -c -fmessage-length=0 -MMD -MP -AM_LDFLAGS = $(PYTHON_LDFLAGS) $(PYTHON_EXTRA_LIBS) $(PYTHON_EXTRA_LDFLAGS) -L/usr/local/lib -L${WITH_LOG4CPLUS}/lib -llog4cplus -RSYNC=rsync -av --exclude-from=${top_srcdir}/exclude.list - +AUTOMAKE_OPTIONS = subdir-objects foreign +AM_CPPFLAGS = -I${top_srcdir}/include -Wall -fno-strict-aliasing -fmessage-length=0 -MMD +AM_LDFLAGS = ${LIBS} -lxerces-c -lz -lrt -llog4cplus +RELEASE_LDFLAG = -release ${PACKAGE_VERSION} diff --git a/config/Makefile.am b/config/Makefile.am index ba52126..76b24e8 100644 --- a/config/Makefile.am +++ b/config/Makefile.am @@ -1,53 +1,29 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ -include ${top_srcdir}/common.mk +SRC=${srcdir} +DST=${exec_prefix}/config install-exec-hook: - mkdir -p ${exec_prefix}/config -if HAVE_RSYNC -if WITH_LIBS - $(RSYNC) ${top_srcdir}/config/server ${exec_prefix}/config/ - $(RSYNC) ${top_srcdir}/config/contexts ${exec_prefix}/config/ -endif - $(RSYNC) ${top_srcdir}/config/spell ${exec_prefix}/config/ -if WITH_GUI - $(RSYNC) ${top_srcdir}/config/gui ${exec_prefix}/config/ -endif - -else - -if WITH_LIBS - cp -r ${top_srcdir}/config/server ${exec_prefix}/config/. - cp -r ${top_srcdir}/config/contexts ${exec_prefix}/config/. -endif - cp -r ${top_srcdir}/config/spell ${exec_prefix}/config/. -if WITH_GUI - cp -r ${top_srcdir}/config/gui ${exec_prefix}/config/. -endif - find ${exec_prefix}/config -name ".svn" | xargs rm -rf -endif - + mkdir -p ${DST} + cp -ur ${SRC}/contexts ${DST} + cp -ur ${SRC}/server ${DST} + cp -ur ${SRC}/spell ${DST} diff --git a/config/contexts/context_example.xml b/config/contexts/context_example.xml new file mode 100644 index 0000000..61be975 --- /dev/null +++ b/config/contexts/context_example.xml @@ -0,0 +1,83 @@ + + + + + + Example context + Exmaple context description + + + + + example + + + + + Y + Spacecraft + X + N/A + + + + + $SPELL_DATA/Procedures + $SPELL_DATA/UserLib + $SPELL_DATA + $SPELL_DATA + + + + + + + + + + + + 0 + 30 + True + False + False + 5 + + DISABLED + DISABLED + DISABLED + False + + + + + + + + SpacecraftDB + GroundDB + ManeuvreMessage + User + OutputFiles/AsRun + OutputFiles/Warmstart + SCDB + GDB + + + + + + + + + + + + + + + + + + diff --git a/config/server/server_example.xml b/config/server/server_example.xml new file mode 100644 index 0000000..b228ac6 --- /dev/null +++ b/config/server/server_example.xml @@ -0,0 +1,69 @@ + + + + + + + ENABLED + PROC + + 9 + + + + + + + language.xml + + + + + + + 9980 + 9981 + + + + $SPELL_HOME/bin/SPELL-Executor + false + + + + + + + 0 + True + False + True + 5 + ON_LINE + ENABLED + ENABLED + False + + + + + + + driver_example.xml + + + + + + + context_example.xml + + + + + + + Y + + + diff --git a/config/spell/language.xml b/config/spell/language.xml index 575d25c..ab9f0c2 100644 --- a/config/spell/language.xml +++ b/config/spell/language.xml @@ -29,6 +29,70 @@ False False + + + + + ABORT|SKIP|RESEND|CANCEL + True + 0 + 30 + 0.1 + None + False + True + ABORT|SKIP|RESEND|CANCEL + NOACTION + False + False + + + + ABORT|SKIP|REPEAT + True + 1 + + + + ABORT|SKIP|REPEAT + True + 1 + + + + ABORT|SKIP|REPEAT + True + 1 + + + + ABORT|SKIP|REPEAT + True + 1 + + + + ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL + ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL + True + 1 + + + + ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL + ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL + True + 1 + + + + ABORT|SKIP|REPEAT + True + 1 + + + + ABORT|SKIP|REPEAT|CANCEL @@ -210,6 +274,18 @@ ABORT|SKIP|REPEAT + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + ABORT|SKIP|REPEAT diff --git a/configure.ac b/configure.ac index ab949b0..221a86b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,263 +1,271 @@ ################################################################################ -# -# FILE : configure.ac -# DESCRIPTION: automake and autoconf configuration file, and source for the -# 'configure' script. Describes the structure and organization -# of all makefiles to be generated in order to build SPELL. -# -# LICENSE ------------------------------------------------------------------ -# -# -# Copyright (C) 2008, 2012 SES ENGINEERING, Luxembourg S.A.R.L. # +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# # This file is part of SPELL. -# -# SPELL is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# SPELL is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with SPELL. If not, see . +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . # ################################################################################ +AC_INIT([SPELL], + [m4_esyscmd([scripts/src/version.sh])], + [juergen.gall@ses.com, raimondas.sasnauskas@ses.com]) +AM_INIT_AUTOMAKE([1.9 tar-pax -Wall -Werror foreign subdir-objects]) -AC_INIT([SPELL], [2.4], []) -AM_INIT_AUTOMAKE([1.9 tar-pax -Wall -Werror foreign]) +AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) -CXXFLAGS= - +AM_DISABLE_STATIC #------------------------------------------------------------------------------# # Checks for basic standard programs #------------------------------------------------------------------------------# AC_PROG_CC AC_PROG_CXX +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_LIBTOOL AC_PROG_INSTALL AC_PROG_MAKE_SET -AM_PATH_PYTHON +#AM_PATH_PYTHON + +AC_CHECK_PROG(protoc, protoc, true) +if [ test x$protoc != xtrue ] +then + AC_MSG_ERROR([Protobuf compiler protoc required to compile SPELL]) +fi #------------------------------------------------------------------------------# -# Checks for some development headers (POSIX-threads,C++ standard library) +# Checks for some development headers (POSIX-threads, C++ standard library) #------------------------------------------------------------------------------# AC_HEADER_STDC AC_LANG_CPLUSPLUS -AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR(POSIX threads library is required)) - -AC_CHECK_LIB([rt] , [clock_gettime] ,,[AC_MSG_ERROR(rt library is required)] ) -AC_CHECK_LIB([dl] , [dlopen] ,,[AC_MSG_ERROR(dl library is required)] ) -AC_CHECK_LIB([util] , [openpty] ,,[AC_MSG_ERROR(util library is required)] ) -AC_CHECK_LIB([xerces-c] , [_init] ,,[AC_MSG_ERROR(xerces-c library is required)]) -AX_PYTHON_DEVEL([]) - - -#------------------------------------------------------------------------------# -# Conditional: check the platform in order to know which scripts to use -#------------------------------------------------------------------------------# -AM_CONDITIONAL(PLATFORM_LINUX, test ! -z `echo $host_os | grep "linux"`) - -#------------------------------------------------------------------------------# -# Conditional: check rsync availability -#------------------------------------------------------------------------------# -AM_CONDITIONAL(HAVE_RSYNC, test `which rsync`) - -#------------------------------------------------------------------------------# -# ENABLE argument to activate or deactivate the SPELL Executor component -#------------------------------------------------------------------------------# -AC_ARG_ENABLE([executor], - [AS_HELP_STRING([--enable-executor],[Compile the executor process (default is yes) ])] , - [executor=true], - [executor=true]) -AM_CONDITIONAL([WITH_EXECUTOR], [test x$executor = xtrue]) - - -#------------------------------------------------------------------------------# -# ENABLE argument to activate or deactivate the SPELL Executor Command Line -#------------------------------------------------------------------------------# -AC_ARG_ENABLE([executorcmd], - [AS_HELP_STRING([--enable-executorcmd],[Compile the command line executor (default is no) ])], - [executorcmd=true], - [executorcmd=false]) -AM_CONDITIONAL([WITH_EXECUTOR_CMD], [test x$executorcmd = xtrue]) - - -#------------------------------------------------------------------------------# -# ENABLE argument to activate or deactivate the SPELL GUI component -#------------------------------------------------------------------------------# -AC_ARG_ENABLE([gui], - [AS_HELP_STRING([--enable-gui],[Compile the SPELL-GUI (default is no) ])], - [gui=true], - [gui=false]) -AM_CONDITIONAL([WITH_GUI], [test x$gui = xtrue]) - - -#------------------------------------------------------------------------------# -# ENABLE argument to activate or deactivate the SPELL standalone driver -#------------------------------------------------------------------------------# -AC_ARG_ENABLE([driverstd], - [AS_HELP_STRING([--enable-driverstd],[Compile the SPELL standalone driver (default is no) ])], - [driverstd=true], - [driverstd=false]) -AM_CONDITIONAL([WITH_DRIVER_STD], [test x$driverstd = xtrue]) - - -#------------------------------------------------------------------------------# -# ENABLE argument to activate or deactivate the SPELL Shell component -#------------------------------------------------------------------------------# -AC_ARG_ENABLE([shell], - [AS_HELP_STRING([--enable-shell],[Compile the SPELL shell (default is yes) ])], - [shell=true], - [shell=true]) -AM_CONDITIONAL([WITH_SHELL], [test x$shell = xtrue]) - - -#------------------------------------------------------------------------------# -# ENABLE argument to activate or deactivate the SPELL Listener component -#------------------------------------------------------------------------------# -AC_ARG_ENABLE([listener], - [AS_HELP_STRING([--enable-listener],[Compile the SPELL listener process (default is yes) ])], - [listener=true], - [listener=true]) -AM_CONDITIONAL([WITH_LISTENER], [test x$listener = xtrue]) - - -#------------------------------------------------------------------------------# -# ENABLE argument to activate or deactivate the SPELL Context component -#------------------------------------------------------------------------------# -AC_ARG_ENABLE([context], - [AS_HELP_STRING([--enable-context],[Compile the SPELL context process (default is yes) ])], - [context=true], - [context=true]) -AM_CONDITIONAL([WITH_CONTEXT], [test x$context = xtrue]) - -#------------------------------------------------------------------------------# -# ENABLE argument to activate or deactivate the documentation build -#------------------------------------------------------------------------------# -AC_ARG_ENABLE([documentation], - [AS_HELP_STRING([--enable-documentation],[Compile the SPELL documentation (default is no) ])], - [documentation=true], - [documentation=false]) -AM_CONDITIONAL([WITH_DOCUMENTATION], [test x$documentation = xtrue]) - - -#------------------------------------------------------------------------------# -# ENABLE argument to activate or deactivate the sample procedures -#------------------------------------------------------------------------------# -AC_ARG_ENABLE([procs], - [AS_HELP_STRING([--enable-procs],[Include the sample procedures (default is no) ])], - [procs=true], - [procs=false]) -AM_CONDITIONAL([WITH_PROCS], [test x$procs = xtrue]) - -#------------------------------------------------------------------------------# -# WITH argument to indicate the path to the Eclipse installation used to -# compile the RCP applications. Shall be of version 3.7. -#------------------------------------------------------------------------------# -AC_ARG_WITH([eclipse], - [AS_HELP_STRING([--with-eclipse=PATH],[eclipse installation used to compile RCP components])], - [ - echo "using eclipse at ${withval}" - if [[ ! -d ${withval} ]] - then - AC_MSG_ERROR([Unable to find the eclipse installation: ${withval}]) - fi - with_eclipse_inst=${withval} +PYTHON2_VERSION=2 +AC_PYTHON_DEVEL_V2 +PYTHON3_VERSION=3 +AC_PYTHON_DEVEL_V3 +AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([pthread.h is required (POSIX threads library)])) +AC_CHECK_HEADER(ncurses.h,,AC_MSG_ERROR([ncurses.h is required])) +PKG_PROG_PKG_CONFIG + +AC_CHECK_LIB([rt] , [clock_gettime] ,[:],[AC_MSG_ERROR(rt library is required)]) +AC_CHECK_LIB([dl] , [dlopen] ,[:],[AC_MSG_ERROR(dl library is required)]) +AC_CHECK_LIB([util] , [openpty] ,[:],[AC_MSG_ERROR(util library is required)]) +AC_CHECK_LIB([xerces-c] , [_init] ,[:],[AC_MSG_ERROR(xerces-c library is required)]) +AC_CHECK_LIB([z] , [inflate] ,[:],[AC_MSG_ERROR(zlib library is required)]) +AC_CHECK_LIB([menu] , [_init] ,[:],[AC_MSG_ERROR(menu library is required)]) +AC_CHECK_LIB([ncurses] , [initscr] ,[:],[AC_MSG_ERROR(ncurses library is required)]) +AC_CHECK_LIB([ncursesw] , [initscr] ,[:],[AC_MSG_ERROR(ncursesw library is required)]) +AC_CHECK_LIB([log4cplus], [_init] ,[:],[AC_MSG_ERROR(log4cplus library is required)]) + +#------------------------------------------------------------------------------# +# ENABLE argument to activate or deactivate the SPELL hifly driver +#------------------------------------------------------------------------------# +AC_ARG_ENABLE([hiflydriver], + [AS_HELP_STRING([--enable-hiflydriver],[Compile the hifly driver (default is no) ])], + [hiflydriver=true], + [hiflydriver=false]) +AM_CONDITIONAL([WITH_DRIVER_HIFLY], [test x$hiflydriver = xtrue]) + +#------------------------------------------------------------------------------# +# WITH argument to indicate the EXIF version for the hifly driver 2.0 +#------------------------------------------------------------------------------# +AC_ARG_WITH([exif], + [AS_HELP_STRING([--with-exif=5 or 6],[hifly EXIF version to be used ])], + [ + case "${withval}" in + 5) with_exif_version=EXIF5 ;; + 6) with_exif_version=EXIF6 ;; + *) AC_MSG_ERROR([bad value ${withval} for --with-exif]) ;; + esac ], []) -WITH_ECLIPSE= -AS_IF([ test "x$with_eclipse_inst" != x], - [AC_SUBST([WITH_ECLIPSE],[${with_eclipse_inst}])], +WITH_EXIF= +AS_IF([ test "x$with_exif_version" != x], + [AC_SUBST([WITH_EXIF],[${with_exif_version}])], []) #------------------------------------------------------------------------------# -# WITH argument to indicate the path to the Log4CPlus library +# Hifly driver checks #------------------------------------------------------------------------------# -AC_ARG_WITH([log4cplus], - [AS_HELP_STRING([--with-log4cplus=PATH],[path to the Log4C++ libraries])], - [ - echo "using Log4C++ libraries at ${withval}" - if [[ ! -d ${withval} ]] - then - AC_MSG_ERROR([Unable to find the Log$C++ libraries directory: ${withval}]) - fi - with_log4cplus=${withval} - ], - [ - echo "using default Log4C++ libraries path (/usr)" - with_log4cplus=/usr +AS_IF([test x$hiflydriver = xtrue], + [ + if [ test -z "$WITH_EXIF" ] + then + AC_MSG_ERROR([Must provide the EXIF version (--with-exif) to compile the hifly driver]) + else + echo "using EXIF version $WITH_EXIF" + fi + ], + []) + +AS_IF([test x$hiflydriver = xtrue], + [ + # just check for existence, don't create -l flags + AC_CHECK_LIB([boost_system], [_init], [AC_SUBST([BOOST_SYSTEM],[boost_system])], [ + AC_CHECK_LIB([boost-system], [_init], [AC_SUBST([BOOST_SYSTEM],[boost-system])], [ + AC_MSG_ERROR(boost-system library is required) ]) + ]) -WITH_LOG4CPLUS= -AS_IF([ test "x$with_log4cplus" != x], - [AC_SUBST([WITH_LOG4CPLUS],[${with_log4cplus}])], + AC_CHECK_LIB([boost_thread], [_init], [AC_SUBST([BOOST_THREAD],[boost_thread])], [ + AC_CHECK_LIB([boost-thread], [_init], [AC_SUBST([BOOST_THREAD],[boost-thread])], [ + AC_MSG_ERROR(boost-thread library is required) + ]) + ]) + AC_CHECK_LIB([boost_chrono], [_init], [AC_SUBST([BOOST_CHRONO],[boost_chrono])], [ + AC_CHECK_LIB([boost-chrono], [_init], [AC_SUBST([BOOST_CHRONO],[boost-chrono])], [ + AC_MSG_ERROR(boost-chrono library is required) + ]) + ]) + AC_CHECK_LIB([omniORB4] , [_init], [:], [AC_MSG_ERROR(omniORB4 library is required)]) + AC_CHECK_LIB([omnithread] , [_init], [:], [AC_MSG_ERROR(omnithread library is required)]) + ], []) #------------------------------------------------------------------------------# -# Some checks to do in case of compiling SPELL-DEV or SPELL-GUI +# ENABLE argument to activate or deactivate the scorpio driver +#------------------------------------------------------------------------------# +AC_ARG_ENABLE([scorpiodriver], + [AS_HELP_STRING([--enable-scorpiodriver],[Compile the scorpio driver (default is no) ])], + [scorpiodriver=true], + [scorpiodriver=false]) +AM_CONDITIONAL([WITH_DRIVER_SCORPIO], [test x$scorpiodriver = xtrue]) + +#------------------------------------------------------------------------------# +# Scorpio driver checks #------------------------------------------------------------------------------# -AS_IF([ test x$gui = xtrue], +AS_IF([test x$scorpiodriver = xtrue], [ - if [[ -z "$WITH_ECLIPSE" ]] + AC_CHECK_LIB([zmq], [_init], [:], [AC_MSG_ERROR(zmq library is required)]) + AC_CHECK_PROG(swig, swig, true) + if [ test x$swig != xtrue ] then - AC_MSG_ERROR([Must provide an eclipse installation path (--with-eclipse) to compile the SPELL-GUI]) + AC_MSG_ERROR([SWIG required to compile the scorpio driver]) fi + SWIGFULL=`swig -version | grep "SWIG Version" | cut -d' ' -f3` + AX_COMPARE_VERSION([$SWIGFULL],[ge],[1.3.36],[], + [AC_MSG_ERROR(SWIG version >= 1.3.36 required)]) ], []) #------------------------------------------------------------------------------# -# Some checks to do in case of compiling tests +# ENABLE argument to activate or deactivate the SPELL Unit Tests component #------------------------------------------------------------------------------# -AS_IF([ test x$tests = xtrue], - [ - AC_MSG_WARN(Tests and unit tests programs enabled) - AC_CHECK_LIB([cppunit],[_init],,[AC_MSG_ERROR(cppunit library is required to compile unit tests)]) - ], - [ - AC_MSG_WARN(Tests and unit tests programs disabled) - ]) +AC_ARG_ENABLE([tests], + [AS_HELP_STRING([--enable-tests],[Compile the SPELL tests (default is no) ])], + [tests=true], + [tests=false]) +AM_CONDITIONAL([WITH_TESTS], [test x$tests = xtrue]) -#------------------------------------------------------------------------------# -# Some checks to do in case of compiling SPELL executor command line -#------------------------------------------------------------------------------# -AS_IF([ test x$executorcmd = xtrue], +AS_IF([test x$tests = xtrue], [ - AC_CHECK_LIB([menu],[_init],,[AC_MSG_ERROR(menu library is required to compile the command line executor)]) - - # Checks for ncurses. - AC_CHECK_HEADERS([ncurses.h], [ - AC_CHECK_LIB(ncurses, initscr, [ - LIBS="$LIBS -lncurses" - AC_DEFINE(HAVE_LIBNCURSES, 1, [Define to 1 if you have the 'ncurses' library (-lncurses).]) - ], AC_MSG_ERROR(The ncurses library is required in order to build the command line executor!)) - ], AC_MSG_ERROR(The ncurses header is required in order to build the command line executor!)) + AC_CHECK_LIB([cppunit], [_init], [:], [AC_MSG_ERROR(cppunit library is required)]) ], []) -AM_CONDITIONAL([WITH_LIBS], [test x$executor$executorcmd$shell$tests != xfalsefalsefalsefalse ]) - -#------------------------------------------------------------------------------# -# Some checks to do in case of compiling documentation #------------------------------------------------------------------------------# -AM_CONDITIONAL([HAVE_DOXYGEN], [test x$`which doxygen &> /dev/null` != x]) +# ENABLE argument to include PACE +#------------------------------------------------------------------------------# +AC_ARG_ENABLE([pace], + [AS_HELP_STRING([--enable-pace],[Include PACE (default is no) ])], + [pace=true], + [pace=false]) +AM_CONDITIONAL([WITH_PACE], [test x$pace = xtrue]) + + +# Address Sanitizer + +AC_MSG_CHECKING([whether to build with Address Sanitizer support]) +AC_ARG_ENABLE(address-sanitizer, + [AS_HELP_STRING([--enable-address-sanitizer],[Enable Address Sanitizer support @<:@default=no@:>@.])], + [ + case "${enableval}" in + no|yes) + enable_address_sanitizer=${enableval} + ;; + *) + AC_MSG_ERROR([Invalid value ${enableval} for --enable-address-sanitizer]) + ;; + esac + ], + [enable_address_sanitizer=no]) +AC_MSG_RESULT(${enable_address_sanitizer}) + + + +convert_warning_flags_to_positive() { + flags_to_check="" + warning_flag_backup="" + for option in ${1}; do + case "$option" + in + -Wno-*) + flags_to_check="${flags_to_check} -W${option##-Wno-}" + warning_flag_backup="${warning_flag_backup} ${option##-Wno-}";; + *) + flags_to_check="${flags_to_check} ${option}";; + esac + done +} + +restore_negative_form_of_warning_flags() { + final_flags=${1} + for positive_option in ${warning_flag_backup}; do + final_flags=$(echo $ECHO_N $final_flags | $SED "s|-W${positive_option}|-Wno-${positive_option}|g") + done + unset flags_to_check + unset warning_flag_backup +} + +check_prospective_CFLAGS() { + convert_warning_flags_to_positive "${PROSPECTIVE_CFLAGS}" + #AX_CHECK_COMPILER_OPTIONS([C], ${flags_to_check}) + restore_negative_form_of_warning_flags "${CFLAGS}" + CFLAGS=${final_flags} + unset final_flags + +} + +check_prospective_CXXFLAGS() { + convert_warning_flags_to_positive "${PROSPECTIVE_CXXFLAGS}" + #AX_CHECK_COMPILER_OPTIONS([C++], ${flags_to_check}) + restore_negative_form_of_warning_flags "${CXXFLAGS}" + CXXFLAGS=${final_flags} + unset final_flags +} + +if test "${enable_address_sanitizer}" = "yes" ; then + + PROSPECTIVE_CFLAGS="-fsanitize-recover=address -fsanitize=address -O1 -fno-omit-frame-pointer -g" + PROSPECTIVE_CXXFLAGS="-fsanitize-recover=address -fsanitize=address -O1 -fno-omit-frame-pointer -g " + + # Check if the compilers support address sanitizer + check_prospective_CFLAGS + check_prospective_CXXFLAGS +fi + #------------------------------------------------------------------------------# # Specification of all the makefiles to be generated. #------------------------------------------------------------------------------# - MAKEFILES=Makefile AC_CONFIG_FILES([Makefile \ - lib/Makefile \ + lib/Makefile \ lib/SPELL_CIF/Makefile \ lib/SPELL_CTX/Makefile \ @@ -276,25 +284,23 @@ AC_CONFIG_FILES([Makefile \ lib/SPELL_SDB/Makefile \ lib/SPELL_DTA/Makefile \ - doc/Makefile \ - procs/Makefile \ config/Makefile \ - rcp/Makefile \ data/Makefile \ scripts/Makefile \ - scripts/linux/Makefile \ src/Makefile \ - src/spell/Makefile \ + src/context/Makefile \ src/executor/Makefile \ src/executorcmd/Makefile\ - src/context/Makefile \ src/listener/Makefile \ + src/service/Makefile \ src/shell/Makefile \ - src/spel-gui/Makefile \ + src/spell/Makefile \ + src/ping/Makefile \ drivers/Makefile \ - drivers/standalone/Makefile \ + drivers/example/Makefile\ + drivers/hifly2/Makefile \ + drivers/scorpio/Makefile ]) -AC_OUTPUT() - +AC_OUTPUT diff --git a/data/InputFiles/GroundDB/GDB.DB b/data/InputFiles/GroundDB/GDB.DB new file mode 100644 index 0000000..24cfc40 --- /dev/null +++ b/data/InputFiles/GroundDB/GDB.DB @@ -0,0 +1,24 @@ +# Sample boolean +BOOL1 True +# Sample forced string +STR1 A string +# Sample string +STR2 "A string" +# Sample list +LIST1 [1,2,3] +# Sample dictionary +DICT1 {"A":1,"B":2} +# Sample hexadecimal value +HEX1 0xA +# Sample float value +FLT1 -0.435 +# Sample float value +FLT2 0.34 +# Sample integer value +INT1 345 +# Sample octal value +OCT1 041 +# Sample date/time value +DAT1 01/01/2001 00:11:22 +# Sample binary value +BIN1 0b00101 diff --git a/data/InputFiles/ManeuvreMessage/TEST.IMP b/data/InputFiles/ManeuvreMessage/TEST.IMP new file mode 100644 index 0000000..24cfc40 --- /dev/null +++ b/data/InputFiles/ManeuvreMessage/TEST.IMP @@ -0,0 +1,24 @@ +# Sample boolean +BOOL1 True +# Sample forced string +STR1 A string +# Sample string +STR2 "A string" +# Sample list +LIST1 [1,2,3] +# Sample dictionary +DICT1 {"A":1,"B":2} +# Sample hexadecimal value +HEX1 0xA +# Sample float value +FLT1 -0.435 +# Sample float value +FLT2 0.34 +# Sample integer value +INT1 345 +# Sample octal value +OCT1 041 +# Sample date/time value +DAT1 01/01/2001 00:11:22 +# Sample binary value +BIN1 0b00101 diff --git a/data/InputFiles/SpacecraftDB/SCDB.DB b/data/InputFiles/SpacecraftDB/SCDB.DB new file mode 100644 index 0000000..2b72837 --- /dev/null +++ b/data/InputFiles/SpacecraftDB/SCDB.DB @@ -0,0 +1,2 @@ +Number_Of_EQUs 2 +Available_EQUs ['EQU1', 'EQU2'] diff --git a/data/InputFiles/User/TEST.IMP b/data/InputFiles/User/TEST.IMP new file mode 100644 index 0000000..24cfc40 --- /dev/null +++ b/data/InputFiles/User/TEST.IMP @@ -0,0 +1,24 @@ +# Sample boolean +BOOL1 True +# Sample forced string +STR1 A string +# Sample string +STR2 "A string" +# Sample list +LIST1 [1,2,3] +# Sample dictionary +DICT1 {"A":1,"B":2} +# Sample hexadecimal value +HEX1 0xA +# Sample float value +FLT1 -0.435 +# Sample float value +FLT2 0.34 +# Sample integer value +INT1 345 +# Sample octal value +OCT1 041 +# Sample date/time value +DAT1 01/01/2001 00:11:22 +# Sample binary value +BIN1 0b00101 diff --git a/data/Makefile.am b/data/Makefile.am index 2f22bf0..d76907e 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,46 +1,30 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ -include ${top_srcdir}/common.mk +SRC=${srcdir} +DST=${exec_prefix}/data install-exec-hook: - mkdir -p ${exec_prefix}/data -if HAVE_RSYNC - $(RSYNC) ${top_srcdir}/data/DriverData ${exec_prefix}/data/ - $(RSYNC) ${top_srcdir}/data/InputFiles ${exec_prefix}/data/ - $(RSYNC) ${top_srcdir}/data/OutputFiles ${exec_prefix}/data/ - $(RSYNC) ${top_srcdir}/data/Runtime ${exec_prefix}/data/ - $(RSYNC) ${top_srcdir}/data/Simulator ${exec_prefix}/data/ -else - cp -r ${top_srcdir}/data/DriverData ${exec_prefix}/data/. - cp -r ${top_srcdir}/data/InputFiles ${exec_prefix}/data/. - cp -r ${top_srcdir}/data/OutputFiles ${exec_prefix}/data/. - cp -r ${top_srcdir}/data/Runtime ${exec_prefix}/data/. - cp -r ${top_srcdir}/data/Simulator ${exec_prefix}/data/. - find ${exec_prefix}/data -name ".svn" | xargs rm -rf - rm -f ${exec_prefix}/data/Makefile* -endif - + cp -ur ${SRC}/InputFiles ${DST} + cp -ur ${SRC}/OutputFiles ${DST} + cp -ur ${SRC}/Procedures ${DST} + cp -ur ${SRC}/UserLib ${DST} + cp -ur ${SRC}/Runtime ${DST} diff --git a/data/OutputFiles/AsRun/.gitignore b/data/OutputFiles/AsRun/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/data/OutputFiles/Warmstart/.gitignore b/data/OutputFiles/Warmstart/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/data/Procedures/.gitignore b/data/Procedures/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/data/Procedures/TestProcedure.py b/data/Procedures/TestProcedure.py new file mode 100644 index 0000000..1590f7b --- /dev/null +++ b/data/Procedures/TestProcedure.py @@ -0,0 +1,19 @@ +################################################################################ +# +# NAME : TestProcedure +# DESCRIPTION : This is a sample procedure +# +# FILE : TestProcedure.py +# +# SPACECRAFT : Y +# +# SPECIFICATION : +# REVISION HISTORY: +# +################################################################################ + +Step('INIT', 'Initializing test procedure') + +Display('Hello, world!') + +Finish('Done!') diff --git a/data/Runtime/.gitignore b/data/Runtime/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/data/UserLib/.gitignore b/data/UserLib/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/deploy/bftd/ddcntl.yaml b/deploy/bftd/ddcntl.yaml new file mode 100644 index 0000000..5a15356 --- /dev/null +++ b/deploy/bftd/ddcntl.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: ddcntl + labels: + app.kubernetes.io/name: spell-cws-scorpio-ddcntl + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-server:tag"} +spec: + type: ExternalName + externalName: cws-lb.scorpio.svc.cluster.local +# --- +# apiVersion: v1 +# kind: Endpoints +# metadata: +# name: ddcntl +# subsets: +# - addresses: +# - hostname: ddcntl +# ip: 10.35.46.170 diff --git a/deploy/bftd/externalsecret.yaml b/deploy/bftd/externalsecret.yaml new file mode 100644 index 0000000..7a21cf4 --- /dev/null +++ b/deploy/bftd/externalsecret.yaml @@ -0,0 +1,34 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: spell-git-access +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + data: + - secretKey: id_rsa + remoteRef: + key: /spell-git-access + property: id_rsa + - secretKey: id_rsa.pub + remoteRef: + key: /spell-git-access + property: id_rsa.pub +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ldap-secret +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + data: + - secretKey: ldap-secret + remoteRef: + key: /ldap-secret + property: ldap-secret \ No newline at end of file diff --git a/deploy/bftd/flux-policies/imagepolicy.yaml b/deploy/bftd/flux-policies/imagepolicy.yaml new file mode 100644 index 0000000..4223022 --- /dev/null +++ b/deploy/bftd/flux-policies/imagepolicy.yaml @@ -0,0 +1,27 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImagePolicy +metadata: + name: spell-registry +spec: + imageRepositoryRef: + name: spell-registry + filterTags: + pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)' + extract: '$semver$minor' + policy: + semver: + range: x.x.x +--- +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImagePolicy +metadata: + name: spell-server +spec: + imageRepositoryRef: + name: spell-server + filterTags: + pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)' + extract: '$semver$minor' + policy: + semver: + range: x.x.x \ No newline at end of file diff --git a/deploy/bftd/flux-policies/imagerepository.yaml b/deploy/bftd/flux-policies/imagerepository.yaml new file mode 100644 index 0000000..b18478b --- /dev/null +++ b/deploy/bftd/flux-policies/imagerepository.yaml @@ -0,0 +1,23 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImageRepository +metadata: + name: spell-registry +spec: + certSecretRef: + name: nexus-ca + image: bzengnexus1.idmz.eng.ses/spell/spell-registry + interval: 1m0s + secretRef: + name: bzengnexus-secret +--- +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImageRepository +metadata: + name: spell-server +spec: + certSecretRef: + name: nexus-ca + image: bzengnexus1.idmz.eng.ses/spell/spell-server + interval: 1m0s + secretRef: + name: bzengnexus-secret \ No newline at end of file diff --git a/deploy/bftd/flux-policies/imageupdateautomation.yaml b/deploy/bftd/flux-policies/imageupdateautomation.yaml new file mode 100644 index 0000000..61fa4e2 --- /dev/null +++ b/deploy/bftd/flux-policies/imageupdateautomation.yaml @@ -0,0 +1,43 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImageUpdateAutomation +metadata: + name: spell-repo + namespace: spell +spec: + interval: 1m0s + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + git: + checkout: + ref: + branch: jgall/container-updates + commit: + author: + email: fluxcdbot@users.noreply.internal.ses.com + name: fluxcdbot + messageTemplate: | + Automated image update + + Automation name: {{ .AutomationObject }} + + Files: + {{ range $filename, $_ := .Updated.Files -}} + - {{ $filename }} + {{ end -}} + + Objects: + {{ range $resource, $_ := .Updated.Objects -}} + - {{ $resource.Kind }} {{ $resource.Name }} + {{ end -}} + + Images: + {{ range .Updated.Images -}} + - {{.}} + {{ end -}} + push: + branch: flux-image-version-update + update: + path: ./deploy/bfts + strategy: Setters \ No newline at end of file diff --git a/deploy/bftd/flux-policies/nexus-ca.yaml b/deploy/bftd/flux-policies/nexus-ca.yaml new file mode 100644 index 0000000..977340d --- /dev/null +++ b/deploy/bftd/flux-policies/nexus-ca.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +data: + caFile: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVtVENDQTRHZ0F3SUJBZ0lUTlFBQUFVeWxRZW1sNGwrcVdRQUFBQUFCVERBTkJna3Foa2lHOXcwQkFRc0YKQURBak1TRXdId1lEVlFRREV4aFRSVk5UWldOMWNtbDBlVWx6YzNWcGJtZERRVXhWTURFd0hoY05NakF3T0RBMgpNakUwTkRReldoY05NalF3T0RBMk1qRTFORFF6V2pDQmh6RUxNQWtHQTFVRUJoTUNURlV4RVRBUEJnTlZCQWNUCkNFSmxkSHBrYjNKbU1Rd3dDZ1lEVlFRS0V3TlRSVk14RERBS0JnTlZCQXNUQTFOUFJURWhNQjhHQTFVRUF4TVkKWW5wbGJtZHVaWGgxY3pFdWFXUnRlaTVsYm1jdWMyVnpNU1l3SkFZSktvWklodmNOQVFrQkZoZEZaSGRoY21RdQpRbUZ6ZEdWc2JHbEFjMlZ6TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFMbndHKzdJSTBtVCtidVp5cXU4TEd4V1NWQ3hMc1JJREpsYkZwUlNUOFdPdjh5SlpzVDBQMkNwbXZlUk9XNnMKNGNuOGs4RnBZdVRBZndLRVVTM3l5S1FyTjZobjlDZllJWVcrQ1FpcVJPQldiQWVQNVFQaDJmc3o3NURjRW5DTQoxeXRtOHZTcE05ejVHSm45b1VObTVyMEh0dmFUdVNoNzgxdEt6TEVtaHhRbE9kSWdqYzluZ2lLb1RqUC9zV2tuCkM0aU0rVEVFemtKYTNZaUZacVRsT3M5Q0JNVnhmK0IxTUMzODRvcU51YmtzSDRIVUZNbnp5cm9UOGJoVThiN1cKQk4vRUk0aEV6NDZ2ODlyZHFrdHVJZGwveklKejUrMm1ZYXRpWnc1M2VYRm1pVEV5VWNqem96YWFIdEpDWG1teQpUeDJuWnNIYllDeEs3Q3R4UWtMUTJXRUNBd0VBQWFPQ0FWOHdnZ0ZiTUIwR0ExVWREZ1FXQkJTYVc0WTUzbU1TCk1hZTJodm1qYzJhbmJIRGZNVEFmQmdOVkhTTUVHREFXZ0JTa3g2TVp3SGxoejlNaHRWWUVTRnByeC83YzBEQngKQmdOVkhSOEVhakJvTUdhZ1pLQmloaTlvZEhSd09pOHZZM0pzTG5ObGN5NWpiMjB2VTBWVFUyVmpkWEpwZEhsSgpjM04xYVc1blEwRk1WVEF4TG1OeWJJWXZhSFIwY0RvdkwyTnliQzV3YTJrdWMyVnpMMU5GVTFObFkzVnlhWFI1ClNYTnpkV2x1WjBOQlRGVXdNUzVqY213d1N3WUlLd1lCQlFVSEFRRUVQekE5TURzR0NDc0dBUVVGQnpBQ2hpOW8KZEhSd09pOHZZM0pzTG5CcmFTNXpaWE12VTBWVFUyVmpkWEpwZEhsSmMzTjFhVzVuUTBGTVZUQXhMbU55ZERBTQpCZ05WSFJNQkFmOEVBakFBTUNNR0ExVWRFUVFjTUJxQ0dHSjZaVzVuYm1WNGRYTXhMbWxrYlhvdVpXNW5Mbk5sCmN6QU9CZ05WSFE4QkFmOEVCQU1DQmFBd0ZnWURWUjBsQVFIL0JBd3dDZ1lJS3dZQkJRVUhBd0V3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFCVlA4Z1hiVmxVTzVLNExQL1lrWXY5Ykp4MnNSODdHbjBRMi85dWZDOXpHMjJOdApYZUlCcDdqc2RDTWpNYzd4QzRWUHhTNktrSjRiUk9WZWI3V3BZK2tFbTRsSklreDNSQlhsemp4aitaT2JvVmhECjNoblNrWTRhNFFzdlJURTlucjQrYlRpSGN4ck90VGNIM244NEtFZXhjRDBwaktkN29yVWVGWHl6MjBJdTN4QjYKT0w0aHB4aEUrVkNTd1I0NXhVSFRLckt3K3pJa3VUV1NYMzBVQ0hZblExRWNTQkFKdHdLNWNkbXZtdUlXazJSdgpWSlVHSjlRQnFOV0padElUZlh3Zk4yT0ljT1VweHRPK3lXckQ5RHZGak1SYVZiUEIwMkIzNW5OcXA2QWN1N21hCnVsNjRicjlSc1grS2w2SGQ1eWltTTBieWJNTXZ4QUtpczNDaGFSMD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= +kind: Secret +metadata: + name: nexus-ca diff --git a/deploy/bftd/kube-mp01-values.yaml b/deploy/bftd/kube-mp01-values.yaml new file mode 100644 index 0000000..af698d5 --- /dev/null +++ b/deploy/bftd/kube-mp01-values.yaml @@ -0,0 +1,33 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.6.5-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + properties: + key: value + settings: + cws: "ddcntl" + #archiva: "{{ .Values.spell_server.seat | lower }}dbs01.scorpio.eng.ses" + obus: obus-server.obus.svc:54407 + maxprocs: 15 + mission: MP01 + family: BSS702SP + seat: DEVB + applicable_missions: + MPOWER: MP01,ZMP01,ZMP02,ZMP03,ZMP04,ZMP05,ZMP06,ZMP07,ZMP08,ZMP09,ZMP10,ZMP11 + input_folder: "{{ .Values.spell_server.mission }}/InputFiles/{{ .Values.spell_server.mission }}" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles/{{ .Values.spell_server.mission }}" +procedures: + size: 5Gi + repo_folder: MPOWER + branch: SIM + server: bzengrcs1.idmz.eng.ses + known_hosts: |- + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT diff --git a/deploy/bftd/kustomization.yaml b/deploy/bftd/kustomization.yaml new file mode 100644 index 0000000..d2c53a2 --- /dev/null +++ b/deploy/bftd/kustomization.yaml @@ -0,0 +1,42 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- ../spell-registry/ +- secretstore.yaml +- externalsecret.yaml +- mp09-s3-server.yaml +- mp01-kube-server.yaml +- s3cntl.yaml +- s5cntl.yaml +- flux-policies/imagepolicy.yaml +- flux-policies/imagerepository.yaml +- flux-policies/imageupdateautomation.yaml +- flux-policies/nexus-ca.yaml +- ddcntl.yaml + +configMapGenerator: +- name: s3-mp09-spell-server + files: + - s3-mp09-values.yaml +- name: kube-mp01-spell-server + files: + - kube-mp01-values.yaml + +configurations: +- kustomizeconfig.yaml + + +patchesJson6902: + - target: + kind: Ingress + name: spell-registry + version: v1 + patch: |- + - op: replace + path: "/spec/rules/0/host" + value: "spell-registry.ing-lu-d.spo.internal.ses.com" + - op: replace + path: "/spec/tls/0/hosts/0" + value: "spell-registry.ing-lu-d.spo.internal.ses.com" \ No newline at end of file diff --git a/deploy/bftd/kustomizeconfig.yaml b/deploy/bftd/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/bftd/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/bftd/mp01-kube-server.yaml b/deploy/bftd/mp01-kube-server.yaml new file mode 100644 index 0000000..deb3470 --- /dev/null +++ b/deploy/bftd/mp01-kube-server.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kube-mp01-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + reconcileStrategy: Revision + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: kube-mp01-spell-server + valuesKey: kube-mp01-values.yaml + + + diff --git a/deploy/bftd/mp09-s3-server.yaml b/deploy/bftd/mp09-s3-server.yaml new file mode 100644 index 0000000..93d1b4b --- /dev/null +++ b/deploy/bftd/mp09-s3-server.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: s3-mp09-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + reconcileStrategy: Revision + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: s3-mp09-spell-server + valuesKey: s3-mp09-values.yaml + + + diff --git a/deploy/bftd/s3-mp09-values.yaml b/deploy/bftd/s3-mp09-values.yaml new file mode 100644 index 0000000..cfdc3aa --- /dev/null +++ b/deploy/bftd/s3-mp09-values.yaml @@ -0,0 +1,34 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.5.1-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + properties: + key: value + settings: + cws: "{{ .Values.spell_server.seat | lower }}cntl" + archiva: "{{ .Values.spell_server.seat | lower }}dbs01.scorpio.eng.ses" + obus: bfts-ob.eng.ses:54407 + maxprocs: 15 + ssh_port: 22 + mission: ZMP09 + family: BSS702SP + seat: S3 + applicable_missions: + MPOWER: MP01,ZMP01,ZMP02,ZMP03,ZMP04,ZMP05,ZMP06,ZMP07,ZMP08,ZMP09,ZMP10,ZMP11 + input_folder: "{{ .Values.spell_server.mission }}/InputFiles/{{ substr 1 99999 .Values.spell_server.mission }}" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles/{{ substr 1 99999 .Values.spell_server.mission }}" +procedures: + size: 5Gi + repo_folder: MPOWER + branch: SIM + server: bzengrcs1.idmz.eng.ses + known_hosts: |- + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT diff --git a/deploy/bftd/s3cntl.yaml b/deploy/bftd/s3cntl.yaml new file mode 100644 index 0000000..f2fcd66 --- /dev/null +++ b/deploy/bftd/s3cntl.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: s3cntl + labels: + app.kubernetes.io/name: spell-cws-scorpio-s3cntl + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-server:tag"} +spec: + type: ExternalName + externalName: s3cntl.scorpio.eng.ses +# --- +# apiVersion: v1 +# kind: Endpoints +# metadata: +# name: s3cntl +# subsets: +# - addresses: +# - hostname: s3cntl +# ip: 10.35.24.30 diff --git a/deploy/bftd/s5cntl.yaml b/deploy/bftd/s5cntl.yaml new file mode 100644 index 0000000..200f1ad --- /dev/null +++ b/deploy/bftd/s5cntl.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: s5cntl + labels: + app.kubernetes.io/name: spell-cws-scorpio-s5cntl + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-server:tag"} +spec: + type: ExternalName + externalName: s5cntl.scorpio.eng.ses +# --- +# apiVersion: v1 +# kind: Endpoints +# metadata: +# name: s5cntl +# subsets: +# - addresses: +# - hostname: s5cntl +# ip: 10.35.35.30 diff --git a/deploy/bftd/secretstore.yaml b/deploy/bftd/secretstore.yaml new file mode 100644 index 0000000..f42d8c6 --- /dev/null +++ b/deploy/bftd/secretstore.yaml @@ -0,0 +1,26 @@ +# Expected Structure: +# spell-git-access: {"id_rsa":"", "id_rsa.pub":""} +# ldap-access: {} +# +# +# +apiVersion: external-secrets.io/v1beta1 +kind: SecretStore +metadata: + name: spell-vault-backend +spec: + provider: + vault: + server: "https://vault.vault:8200" + path: "soe/secret/spell" + version: "v2" + caProvider: + type: "Secret" + name: "vault-ca" + key: "ca.crt" + auth: + kubernetes: + mountPath: "kubernetes" + role: "serviceaccount" + serviceAccountRef: + name: "default" diff --git a/deploy/bfts/externalsecret.yaml b/deploy/bfts/externalsecret.yaml new file mode 100644 index 0000000..dfdbc01 --- /dev/null +++ b/deploy/bfts/externalsecret.yaml @@ -0,0 +1,66 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: spell-git-access +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + data: + - secretKey: id_rsa + remoteRef: + key: /spell-git-access + property: id_rsa + - secretKey: id_rsa.pub + remoteRef: + key: /spell-git-access + property: id_rsa.pub +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ldap-secret +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + data: + - secretKey: ldap-secret + remoteRef: + key: /ldap-secret + property: ldap-secret +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ses24-encryption-keys +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + dataFrom: + - extract: + key: /ses24-encryption + decodingStrategy: Auto + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ses24-encryption-cert +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + data: + - secretKey: ses24_rsa.pem + remoteRef: + key: /ses24-encryption + property: ses24_rsa.pem diff --git a/deploy/bfts/kustomization.yaml b/deploy/bfts/kustomization.yaml new file mode 100644 index 0000000..d60f692 --- /dev/null +++ b/deploy/bfts/kustomization.yaml @@ -0,0 +1,30 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- ../spell-registry/ +- secretstore.yaml +- externalsecret.yaml +- missions/zs24a/ +- missions/zs24b/ +- missions/zs24c/ +- missions/zs24d/ +- missions/zs24e/ +- missions/zs24f/ + +patchesJson6902: + - target: + kind: Ingress + name: spell-registry + version: v1 + patch: |- + - op: replace + path: "/spec/rules/0/host" + value: "spell-registry.ing-lu-s.spo.internal.ses.com" + - op: replace + path: "/spec/tls/0/hosts/0" + value: "spell-registry.ing-lu-s.spo.internal.ses.com" + +configurations: +- kustomizeconfig.yaml diff --git a/deploy/bfts/kustomizeconfig.yaml b/deploy/bfts/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/bfts/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/bfts/missions/zs24a/kube-ses24-server.yaml b/deploy/bfts/missions/zs24a/kube-ses24-server.yaml new file mode 100644 index 0000000..438142d --- /dev/null +++ b/deploy/bfts/missions/zs24a/kube-ses24-server.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kube-zs24a-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: kube-zs24a-spell-release + valuesKey: kube-ses24-values.yaml diff --git a/deploy/bfts/missions/zs24a/kube-ses24-values.yaml b/deploy/bfts/missions/zs24a/kube-ses24-values.yaml new file mode 100644 index 0000000..959bd95 --- /dev/null +++ b/deploy/bfts/missions/zs24a/kube-ses24-values.yaml @@ -0,0 +1,75 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + env: + NODE_ID_zs24asim: "3369" + NODE_NAME_3369: zs24asim + properties: + key: value + settings: + archiva: "zs24asim" + FLEETLIMITS: limitsdb-api.limitsdb.svc:8080 + FLEETLIMITS_SEAT: SIMB + SATDB: satdb-api.satdb.svc:8080 + cws: "zs24asim" + obus: obus-test-server.obus.svc:54407 + maxprocs: 15 + mission: ZS24A + context_mission: SES24 + family: SBNEO + seat: SIMB + applicable_missions: + SBNEO: "SES24,ZS24A,ZS24B,ZS24C" + input_folder: "{{ .Values.spell_server.mission }}/InputFiles" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles" + additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24a/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'" + additionalVolumeMounts: + - mountPath: /etc/pki/tls/private/wrapped_keys/ + name: ses24-certs-folder + - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip + name: ses24-encryption-keys + subPath: ses24-keys.zip + - mountPath: /etc/pki/tls/zs24a_keys/zs24a_rsa.pem + name: ses24-encryption-cert + subPath: ses24_rsa.pem + additionalVolumes: + - name: ses24-certs-folder + emptyDir: + sizeLimit: 100Mi + medium: Memory + - name: ses24-encryption-cert + secret: + secretName: ses24-encryption-cert + optional: true + defaultMode: 0400 + - name: ses24-encryption-keys + secret: + secretName: ses24-encryption-keys + optional: true + defaultMode: 0400 +procedures: + size: 5Gi + repo_folder: SES24 + branch: SIM + server: bzengrcs1.idmz.eng.ses + known_hosts: |- + propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5 + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT + +auth: + ssh: + version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"} + ldap: + url: ldaps://beacdc1.xeneng.ses + +service: + loadBalancerIP: 10.35.47.136 \ No newline at end of file diff --git a/deploy/bfts/missions/zs24a/kustomization.yaml b/deploy/bfts/missions/zs24a/kustomization.yaml new file mode 100644 index 0000000..a50f7a0 --- /dev/null +++ b/deploy/bfts/missions/zs24a/kustomization.yaml @@ -0,0 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- kube-ses24-server.yaml +- ses24cntl.yaml + +configMapGenerator: +- name: kube-zs24a-spell-release + options: + disableNameSuffixHash: false + files: + - kube-ses24-values.yaml + + +configurations: +- kustomizeconfig.yaml \ No newline at end of file diff --git a/deploy/bfts/missions/zs24a/kustomizeconfig.yaml b/deploy/bfts/missions/zs24a/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/bfts/missions/zs24a/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/bfts/missions/zs24a/ses24cntl.yaml b/deploy/bfts/missions/zs24a/ses24cntl.yaml new file mode 100644 index 0000000..ea425fb --- /dev/null +++ b/deploy/bfts/missions/zs24a/ses24cntl.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: zs24asim + labels: + app.kubernetes.io/name: spell-cws-scorpio-zs24asim + app.kubernetes.io/instance: spell +spec: + type: ExternalName + externalName: cws-lb.scorpio-zs24a.svc.cluster.local + diff --git a/deploy/bfts/missions/zs24b/kube-ses24-server.yaml b/deploy/bfts/missions/zs24b/kube-ses24-server.yaml new file mode 100644 index 0000000..c2a382c --- /dev/null +++ b/deploy/bfts/missions/zs24b/kube-ses24-server.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kube-zs24b-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: kube-zs24b-spell-release + valuesKey: kube-ses24-values.yaml diff --git a/deploy/bfts/missions/zs24b/kube-ses24-values.yaml b/deploy/bfts/missions/zs24b/kube-ses24-values.yaml new file mode 100644 index 0000000..57b05da --- /dev/null +++ b/deploy/bfts/missions/zs24b/kube-ses24-values.yaml @@ -0,0 +1,75 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + env: + NODE_ID_zs24bsim: "3369" + NODE_NAME_3369: zs24bsim + properties: + key: value + settings: + archiva: "zs24bsim" + FLEETLIMITS: limitsdb-api.limitsdb.svc:8080 + FLEETLIMITS_SEAT: SIMB + SATDB: satdb-api.satdb.svc:8080 + cws: "zs24bsim" + obus: obus-test-server.obus.svc:54407 + maxprocs: 15 + mission: ZS24B + context_mission: SES24 + family: SBNEO + seat: SIMB + applicable_missions: + SBNEO: "SES24,ZS24A,ZS24B,ZS24C,ZS24D,ZS24E,ZS24F" + input_folder: "{{ .Values.spell_server.mission }}/InputFiles" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles" + additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24b/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'" + additionalVolumeMounts: + - mountPath: /etc/pki/tls/private/wrapped_keys/ + name: ses24-certs-folder + - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip + name: ses24-encryption-keys + subPath: ses24-keys.zip + - mountPath: /etc/pki/tls/zs24b_keys/zs24b_rsa.pem + name: ses24-encryption-cert + subPath: ses24_rsa.pem + additionalVolumes: + - name: ses24-certs-folder + emptyDir: + sizeLimit: 100Mi + medium: Memory + - name: ses24-encryption-cert + secret: + secretName: ses24-encryption-cert + optional: true + defaultMode: 0400 + - name: ses24-encryption-keys + secret: + secretName: ses24-encryption-keys + optional: true + defaultMode: 0400 +procedures: + size: 5Gi + repo_folder: SES24 + branch: SIM + server: bzengrcs1.idmz.eng.ses + known_hosts: |- + propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5 + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT + +auth: + ssh: + version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"} + ldap: + url: ldaps://beacdc1.xeneng.ses + +service: + loadBalancerIP: 10.35.47.182 diff --git a/deploy/bfts/missions/zs24b/kustomization.yaml b/deploy/bfts/missions/zs24b/kustomization.yaml new file mode 100644 index 0000000..74f3511 --- /dev/null +++ b/deploy/bfts/missions/zs24b/kustomization.yaml @@ -0,0 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- kube-ses24-server.yaml +- ses24cntl.yaml + +configMapGenerator: +- name: kube-zs24b-spell-release + options: + disableNameSuffixHash: false + files: + - kube-ses24-values.yaml + + +configurations: +- kustomizeconfig.yaml \ No newline at end of file diff --git a/deploy/bfts/missions/zs24b/kustomizeconfig.yaml b/deploy/bfts/missions/zs24b/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/bfts/missions/zs24b/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/bfts/missions/zs24b/ses24cntl.yaml b/deploy/bfts/missions/zs24b/ses24cntl.yaml new file mode 100644 index 0000000..2ea3539 --- /dev/null +++ b/deploy/bfts/missions/zs24b/ses24cntl.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: zs24bsim + labels: + app.kubernetes.io/name: spell-cws-scorpio-zs24bsim + app.kubernetes.io/instance: spell +spec: + type: ExternalName + externalName: cws-lb.scorpio-zs24b.svc.cluster.local + diff --git a/deploy/bfts/missions/zs24c/kube-ses24-server.yaml b/deploy/bfts/missions/zs24c/kube-ses24-server.yaml new file mode 100644 index 0000000..7637c7d --- /dev/null +++ b/deploy/bfts/missions/zs24c/kube-ses24-server.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kube-zs24c-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: kube-zs24c-spell-release + valuesKey: kube-ses24-values.yaml diff --git a/deploy/bfts/missions/zs24c/kube-ses24-values.yaml b/deploy/bfts/missions/zs24c/kube-ses24-values.yaml new file mode 100644 index 0000000..1ab0f76 --- /dev/null +++ b/deploy/bfts/missions/zs24c/kube-ses24-values.yaml @@ -0,0 +1,75 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + env: + NODE_ID_zs24csim: "3369" + NODE_NAME_3369: zs24csim + properties: + key: value + settings: + archiva: "zs24csim" + FLEETLIMITS: limitsdb-api.limitsdb.svc:8080 + FLEETLIMITS_SEAT: SIMB + SATDB: satdb-api.satdb.svc:8080 + cws: "zs24csim" + obus: obus-test-server.obus.svc:54407 + maxprocs: 15 + mission: ZS24C + context_mission: SES24 + family: SBNEO + seat: SIMB + applicable_missions: + SBNEO: "SES24,ZS24A,ZS24B,ZS24C,ZS24D,ZS24E,ZS24F" + input_folder: "{{ .Values.spell_server.mission }}/InputFiles" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles" + additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24c/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'" + additionalVolumeMounts: + - mountPath: /etc/pki/tls/private/wrapped_keys/ + name: ses24-certs-folder + - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip + name: ses24-encryption-keys + subPath: ses24-keys.zip + - mountPath: /etc/pki/tls/zs24c_keys/zs24c_rsa.pem + name: ses24-encryption-cert + subPath: ses24_rsa.pem + additionalVolumes: + - name: ses24-certs-folder + emptyDir: + sizeLimit: 100Mi + medium: Memory + - name: ses24-encryption-cert + secret: + secretName: ses24-encryption-cert + optional: true + defaultMode: 0400 + - name: ses24-encryption-keys + secret: + secretName: ses24-encryption-keys + optional: true + defaultMode: 0400 +procedures: + size: 5Gi + repo_folder: SES24 + branch: SIM + server: bzengrcs1.idmz.eng.ses + known_hosts: |- + propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5 + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT + +auth: + ssh: + version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"} + ldap: + url: ldaps://beacdc1.xeneng.ses + +service: + loadBalancerIP: 10.35.47.226 diff --git a/deploy/bfts/missions/zs24c/kustomization.yaml b/deploy/bfts/missions/zs24c/kustomization.yaml new file mode 100644 index 0000000..1eb4aa5 --- /dev/null +++ b/deploy/bfts/missions/zs24c/kustomization.yaml @@ -0,0 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- kube-ses24-server.yaml +- ses24cntl.yaml + +configMapGenerator: +- name: kube-zs24c-spell-release + options: + disableNameSuffixHash: false + files: + - kube-ses24-values.yaml + + +configurations: +- kustomizeconfig.yaml \ No newline at end of file diff --git a/deploy/bfts/missions/zs24c/kustomizeconfig.yaml b/deploy/bfts/missions/zs24c/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/bfts/missions/zs24c/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/bfts/missions/zs24c/ses24cntl.yaml b/deploy/bfts/missions/zs24c/ses24cntl.yaml new file mode 100644 index 0000000..9b86107 --- /dev/null +++ b/deploy/bfts/missions/zs24c/ses24cntl.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: zs24csim + labels: + app.kubernetes.io/name: spell-cws-scorpio-zs24csim + app.kubernetes.io/instance: spell +spec: + type: ExternalName + externalName: cws-lb.scorpio-zs24c.svc.cluster.local + diff --git a/deploy/bfts/missions/zs24d/kube-ses24-server.yaml b/deploy/bfts/missions/zs24d/kube-ses24-server.yaml new file mode 100644 index 0000000..8b650fc --- /dev/null +++ b/deploy/bfts/missions/zs24d/kube-ses24-server.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kube-zs24d-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: kube-zs24d-spell-release + valuesKey: kube-ses24-values.yaml diff --git a/deploy/bfts/missions/zs24d/kube-ses24-values.yaml b/deploy/bfts/missions/zs24d/kube-ses24-values.yaml new file mode 100644 index 0000000..66d2eed --- /dev/null +++ b/deploy/bfts/missions/zs24d/kube-ses24-values.yaml @@ -0,0 +1,75 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + env: + NODE_ID_zs24dsim: "3369" + NODE_NAME_3369: zs24dsim + properties: + key: value + settings: + archiva: "zs24dsim" + FLEETLIMITS: limitsdb-api.limitsdb.svc:8080 + FLEETLIMITS_SEAT: SIMB + SATDB: satdb-api.satdb.svc:8080 + cws: "zs24dsim" + obus: obus-test-server.obus.svc:54407 + maxprocs: 15 + mission: ZS24D + context_mission: SES24 + family: SBNEO + seat: SIMB + applicable_missions: + SBNEO: "SES24,ZS24A,ZS24D,ZS24C,ZS24D,ZS24E,ZS24F" + input_folder: "{{ .Values.spell_server.mission }}/InputFiles" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles" + additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24d/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'" + additionalVolumeMounts: + - mountPath: /etc/pki/tls/private/wrapped_keys/ + name: ses24-certs-folder + - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip + name: ses24-encryption-keys + subPath: ses24-keys.zip + - mountPath: /etc/pki/tls/zs24d_keys/zs24d_rsa.pem + name: ses24-encryption-cert + subPath: ses24_rsa.pem + additionalVolumes: + - name: ses24-certs-folder + emptyDir: + sizeLimit: 100Mi + medium: Memory + - name: ses24-encryption-cert + secret: + secretName: ses24-encryption-cert + optional: true + defaultMode: 0400 + - name: ses24-encryption-keys + secret: + secretName: ses24-encryption-keys + optional: true + defaultMode: 0400 +procedures: + size: 5Gi + repo_folder: SES24 + branch: SIM + server: bzengrcs1.idmz.eng.ses + known_hosts: |- + propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5 + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT + +auth: + ssh: + version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"} + ldap: + url: ldaps://beacdc1.xeneng.ses + +service: + loadBalancerIP: 10.35.47.230 diff --git a/deploy/bfts/missions/zs24d/kustomization.yaml b/deploy/bfts/missions/zs24d/kustomization.yaml new file mode 100644 index 0000000..0af5d03 --- /dev/null +++ b/deploy/bfts/missions/zs24d/kustomization.yaml @@ -0,0 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- kube-ses24-server.yaml +- ses24cntl.yaml + +configMapGenerator: +- name: kube-zs24d-spell-release + options: + disableNameSuffixHash: false + files: + - kube-ses24-values.yaml + + +configurations: +- kustomizeconfig.yaml \ No newline at end of file diff --git a/deploy/bfts/missions/zs24d/kustomizeconfig.yaml b/deploy/bfts/missions/zs24d/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/bfts/missions/zs24d/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/bfts/missions/zs24d/ses24cntl.yaml b/deploy/bfts/missions/zs24d/ses24cntl.yaml new file mode 100644 index 0000000..d2d5731 --- /dev/null +++ b/deploy/bfts/missions/zs24d/ses24cntl.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: zs24dsim + labels: + app.kubernetes.io/name: spell-cws-scorpio-zs24dsim + app.kubernetes.io/instance: spell +spec: + type: ExternalName + externalName: cws-lb.scorpio-zs24d.svc.cluster.local + diff --git a/deploy/bfts/missions/zs24e/kube-ses24-server.yaml b/deploy/bfts/missions/zs24e/kube-ses24-server.yaml new file mode 100644 index 0000000..9b3984c --- /dev/null +++ b/deploy/bfts/missions/zs24e/kube-ses24-server.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kube-zs24e-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: kube-zs24e-spell-release + valuesKey: kube-ses24-values.yaml diff --git a/deploy/bfts/missions/zs24e/kube-ses24-values.yaml b/deploy/bfts/missions/zs24e/kube-ses24-values.yaml new file mode 100644 index 0000000..07b0b6f --- /dev/null +++ b/deploy/bfts/missions/zs24e/kube-ses24-values.yaml @@ -0,0 +1,75 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + env: + NODE_ID_zs24esim: "3369" + NODE_NAME_3369: zs24esim + properties: + key: value + settings: + archiva: "zs24esim" + FLEETLIMITS: limitsdb-api.limitsdb.svc:8080 + FLEETLIMITS_SEAT: SIMB + SATDB: satdb-api.satdb.svc:8080 + cws: "zs24esim" + obus: obus-test-server.obus.svc:54407 + maxprocs: 15 + mission: ZS24E + context_mission: SES24 + family: SBNEO + seat: SIMB + applicable_missions: + SBNEO: "SES24,ZS24A,ZS24E,ZS24C,ZS24D,ZS24E,ZS24F" + input_folder: "{{ .Values.spell_server.mission }}/InputFiles" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles" + additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24e/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'" + additionalVolumeMounts: + - mountPath: /etc/pki/tls/private/wrapped_keys/ + name: ses24-certs-folder + - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip + name: ses24-encryption-keys + subPath: ses24-keys.zip + - mountPath: /etc/pki/tls/zs24e_keys/zs24e_rsa.pem + name: ses24-encryption-cert + subPath: ses24_rsa.pem + additionalVolumes: + - name: ses24-certs-folder + emptyDir: + sizeLimit: 100Mi + medium: Memory + - name: ses24-encryption-cert + secret: + secretName: ses24-encryption-cert + optional: true + defaultMode: 0400 + - name: ses24-encryption-keys + secret: + secretName: ses24-encryption-keys + optional: true + defaultMode: 0400 +procedures: + size: 5Gi + repo_folder: SES24 + branch: SIM + server: bzengrcs1.idmz.eng.ses + known_hosts: |- + propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5 + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT + +auth: + ssh: + version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"} + ldap: + url: ldaps://beacdc1.xeneng.ses + +service: + loadBalancerIP: 10.35.47.155 diff --git a/deploy/bfts/missions/zs24e/kustomization.yaml b/deploy/bfts/missions/zs24e/kustomization.yaml new file mode 100644 index 0000000..a3a5f4a --- /dev/null +++ b/deploy/bfts/missions/zs24e/kustomization.yaml @@ -0,0 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- kube-ses24-server.yaml +- ses24cntl.yaml + +configMapGenerator: +- name: kube-zs24e-spell-release + options: + disableNameSuffixHash: false + files: + - kube-ses24-values.yaml + + +configurations: +- kustomizeconfig.yaml \ No newline at end of file diff --git a/deploy/bfts/missions/zs24e/kustomizeconfig.yaml b/deploy/bfts/missions/zs24e/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/bfts/missions/zs24e/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/bfts/missions/zs24e/ses24cntl.yaml b/deploy/bfts/missions/zs24e/ses24cntl.yaml new file mode 100644 index 0000000..2d408fa --- /dev/null +++ b/deploy/bfts/missions/zs24e/ses24cntl.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: zs24esim + labels: + app.kubernetes.io/name: spell-cws-scorpio-zs24esim + app.kubernetes.io/instance: spell +spec: + type: ExternalName + externalName: cws-lb.scorpio-zs24e.svc.cluster.local + diff --git a/deploy/bfts/missions/zs24f/kube-ses24-server.yaml b/deploy/bfts/missions/zs24f/kube-ses24-server.yaml new file mode 100644 index 0000000..6770b57 --- /dev/null +++ b/deploy/bfts/missions/zs24f/kube-ses24-server.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kube-zs24f-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: kube-zs24f-spell-release + valuesKey: kube-ses24-values.yaml diff --git a/deploy/bfts/missions/zs24f/kube-ses24-values.yaml b/deploy/bfts/missions/zs24f/kube-ses24-values.yaml new file mode 100644 index 0000000..b153875 --- /dev/null +++ b/deploy/bfts/missions/zs24f/kube-ses24-values.yaml @@ -0,0 +1,75 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + env: + NODE_ID_zs24fsim: "3369" + NODE_NAME_3369: zs24fsim + properties: + key: value + settings: + archiva: "zs24fsim" + FLEETLIMITS: limitsdb-api.limitsdb.svc:8080 + FLEETLIMITS_SEAT: SIMB + SATDB: satdb-api.satdb.svc:8080 + cws: "zs24fsim" + obus: obus-test-server.obus.svc:54407 + maxprocs: 15 + mission: ZS24F + context_mission: SES24 + family: SBNEO + seat: SIMB + applicable_missions: + SBNEO: "SES24,ZS24A,ZS24F,ZS24C,ZS24D,ZS24E,ZS24F" + input_folder: "{{ .Values.spell_server.mission }}/InputFiles" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles" + additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24f/' | xargs -n2 mv) ) || echo 'Could not find encryption key archive!'" + additionalVolumeMounts: + - mountPath: /etc/pki/tls/private/wrapped_keys/ + name: ses24-certs-folder + - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip + name: ses24-encryption-keys + subPath: ses24-keys.zip + - mountPath: /etc/pki/tls/zs24f_keys/zs24f_rsa.pem + name: ses24-encryption-cert + subPath: ses24_rsa.pem + additionalVolumes: + - name: ses24-certs-folder + emptyDir: + sizeLimit: 100Mi + medium: Memory + - name: ses24-encryption-cert + secret: + secretName: ses24-encryption-cert + optional: true + defaultMode: 0400 + - name: ses24-encryption-keys + secret: + secretName: ses24-encryption-keys + optional: true + defaultMode: 0400 +procedures: + size: 5Gi + repo_folder: SES24 + branch: SIM + server: bzengrcs1.idmz.eng.ses + known_hosts: |- + propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5 + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT + +auth: + ssh: + version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"} + ldap: + url: ldaps://beacdc1.xeneng.ses + +service: + loadBalancerIP: 10.35.47.172 diff --git a/deploy/bfts/missions/zs24f/kustomization.yaml b/deploy/bfts/missions/zs24f/kustomization.yaml new file mode 100644 index 0000000..58f87ec --- /dev/null +++ b/deploy/bfts/missions/zs24f/kustomization.yaml @@ -0,0 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- kube-ses24-server.yaml +- ses24cntl.yaml + +configMapGenerator: +- name: kube-zs24f-spell-release + options: + disableNameSuffixHash: false + files: + - kube-ses24-values.yaml + + +configurations: +- kustomizeconfig.yaml \ No newline at end of file diff --git a/deploy/bfts/missions/zs24f/kustomizeconfig.yaml b/deploy/bfts/missions/zs24f/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/bfts/missions/zs24f/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/bfts/missions/zs24f/ses24cntl.yaml b/deploy/bfts/missions/zs24f/ses24cntl.yaml new file mode 100644 index 0000000..354e864 --- /dev/null +++ b/deploy/bfts/missions/zs24f/ses24cntl.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: zs24fsim + labels: + app.kubernetes.io/name: spell-cws-scorpio-zs24fsim + app.kubernetes.io/instance: spell +spec: + type: ExternalName + externalName: cws-lb.scorpio-zs24f.svc.cluster.local + diff --git a/deploy/bfts/secretstore.yaml b/deploy/bfts/secretstore.yaml new file mode 100644 index 0000000..f42d8c6 --- /dev/null +++ b/deploy/bfts/secretstore.yaml @@ -0,0 +1,26 @@ +# Expected Structure: +# spell-git-access: {"id_rsa":"", "id_rsa.pub":""} +# ldap-access: {} +# +# +# +apiVersion: external-secrets.io/v1beta1 +kind: SecretStore +metadata: + name: spell-vault-backend +spec: + provider: + vault: + server: "https://vault.vault:8200" + path: "soe/secret/spell" + version: "v2" + caProvider: + type: "Secret" + name: "vault-ca" + key: "ca.crt" + auth: + kubernetes: + mountPath: "kubernetes" + role: "serviceaccount" + serviceAccountRef: + name: "default" diff --git a/deploy/pfte/externalsecret.yaml b/deploy/pfte/externalsecret.yaml new file mode 100644 index 0000000..7a21cf4 --- /dev/null +++ b/deploy/pfte/externalsecret.yaml @@ -0,0 +1,34 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: spell-git-access +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + data: + - secretKey: id_rsa + remoteRef: + key: /spell-git-access + property: id_rsa + - secretKey: id_rsa.pub + remoteRef: + key: /spell-git-access + property: id_rsa.pub +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ldap-secret +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + data: + - secretKey: ldap-secret + remoteRef: + key: /ldap-secret + property: ldap-secret \ No newline at end of file diff --git a/deploy/pfte/flux-policies/imagepolicy.yaml b/deploy/pfte/flux-policies/imagepolicy.yaml new file mode 100644 index 0000000..4223022 --- /dev/null +++ b/deploy/pfte/flux-policies/imagepolicy.yaml @@ -0,0 +1,27 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImagePolicy +metadata: + name: spell-registry +spec: + imageRepositoryRef: + name: spell-registry + filterTags: + pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)' + extract: '$semver$minor' + policy: + semver: + range: x.x.x +--- +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImagePolicy +metadata: + name: spell-server +spec: + imageRepositoryRef: + name: spell-server + filterTags: + pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)' + extract: '$semver$minor' + policy: + semver: + range: x.x.x \ No newline at end of file diff --git a/deploy/pfte/flux-policies/imagerepository.yaml b/deploy/pfte/flux-policies/imagerepository.yaml new file mode 100644 index 0000000..b18478b --- /dev/null +++ b/deploy/pfte/flux-policies/imagerepository.yaml @@ -0,0 +1,23 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImageRepository +metadata: + name: spell-registry +spec: + certSecretRef: + name: nexus-ca + image: bzengnexus1.idmz.eng.ses/spell/spell-registry + interval: 1m0s + secretRef: + name: bzengnexus-secret +--- +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImageRepository +metadata: + name: spell-server +spec: + certSecretRef: + name: nexus-ca + image: bzengnexus1.idmz.eng.ses/spell/spell-server + interval: 1m0s + secretRef: + name: bzengnexus-secret \ No newline at end of file diff --git a/deploy/pfte/flux-policies/imageupdateautomation.yaml b/deploy/pfte/flux-policies/imageupdateautomation.yaml new file mode 100644 index 0000000..37858a8 --- /dev/null +++ b/deploy/pfte/flux-policies/imageupdateautomation.yaml @@ -0,0 +1,43 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImageUpdateAutomation +metadata: + name: spell-repo + namespace: spell +spec: + interval: 1m0s + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + git: + checkout: + ref: + branch: jgall/container-updates + commit: + author: + email: fluxcdbot@users.noreply.internal.ses.com + name: fluxcdbot + messageTemplate: | + Automated image update + + Automation name: {{ .AutomationObject }} + + Files: + {{ range $filename, $_ := .Updated.Files -}} + - {{ $filename }} + {{ end -}} + + Objects: + {{ range $resource, $_ := .Updated.Objects -}} + - {{ $resource.Kind }} {{ $resource.Name }} + {{ end -}} + + Images: + {{ range .Updated.Images -}} + - {{.}} + {{ end -}} + push: + branch: flux-image-version-update + update: + path: ./deploy/pfts + strategy: Setters \ No newline at end of file diff --git a/deploy/pfte/flux-policies/nexus-ca.yaml b/deploy/pfte/flux-policies/nexus-ca.yaml new file mode 100644 index 0000000..977340d --- /dev/null +++ b/deploy/pfte/flux-policies/nexus-ca.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +data: + caFile: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVtVENDQTRHZ0F3SUJBZ0lUTlFBQUFVeWxRZW1sNGwrcVdRQUFBQUFCVERBTkJna3Foa2lHOXcwQkFRc0YKQURBak1TRXdId1lEVlFRREV4aFRSVk5UWldOMWNtbDBlVWx6YzNWcGJtZERRVXhWTURFd0hoY05NakF3T0RBMgpNakUwTkRReldoY05NalF3T0RBMk1qRTFORFF6V2pDQmh6RUxNQWtHQTFVRUJoTUNURlV4RVRBUEJnTlZCQWNUCkNFSmxkSHBrYjNKbU1Rd3dDZ1lEVlFRS0V3TlRSVk14RERBS0JnTlZCQXNUQTFOUFJURWhNQjhHQTFVRUF4TVkKWW5wbGJtZHVaWGgxY3pFdWFXUnRlaTVsYm1jdWMyVnpNU1l3SkFZSktvWklodmNOQVFrQkZoZEZaSGRoY21RdQpRbUZ6ZEdWc2JHbEFjMlZ6TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFMbndHKzdJSTBtVCtidVp5cXU4TEd4V1NWQ3hMc1JJREpsYkZwUlNUOFdPdjh5SlpzVDBQMkNwbXZlUk9XNnMKNGNuOGs4RnBZdVRBZndLRVVTM3l5S1FyTjZobjlDZllJWVcrQ1FpcVJPQldiQWVQNVFQaDJmc3o3NURjRW5DTQoxeXRtOHZTcE05ejVHSm45b1VObTVyMEh0dmFUdVNoNzgxdEt6TEVtaHhRbE9kSWdqYzluZ2lLb1RqUC9zV2tuCkM0aU0rVEVFemtKYTNZaUZacVRsT3M5Q0JNVnhmK0IxTUMzODRvcU51YmtzSDRIVUZNbnp5cm9UOGJoVThiN1cKQk4vRUk0aEV6NDZ2ODlyZHFrdHVJZGwveklKejUrMm1ZYXRpWnc1M2VYRm1pVEV5VWNqem96YWFIdEpDWG1teQpUeDJuWnNIYllDeEs3Q3R4UWtMUTJXRUNBd0VBQWFPQ0FWOHdnZ0ZiTUIwR0ExVWREZ1FXQkJTYVc0WTUzbU1TCk1hZTJodm1qYzJhbmJIRGZNVEFmQmdOVkhTTUVHREFXZ0JTa3g2TVp3SGxoejlNaHRWWUVTRnByeC83YzBEQngKQmdOVkhSOEVhakJvTUdhZ1pLQmloaTlvZEhSd09pOHZZM0pzTG5ObGN5NWpiMjB2VTBWVFUyVmpkWEpwZEhsSgpjM04xYVc1blEwRk1WVEF4TG1OeWJJWXZhSFIwY0RvdkwyTnliQzV3YTJrdWMyVnpMMU5GVTFObFkzVnlhWFI1ClNYTnpkV2x1WjBOQlRGVXdNUzVqY213d1N3WUlLd1lCQlFVSEFRRUVQekE5TURzR0NDc0dBUVVGQnpBQ2hpOW8KZEhSd09pOHZZM0pzTG5CcmFTNXpaWE12VTBWVFUyVmpkWEpwZEhsSmMzTjFhVzVuUTBGTVZUQXhMbU55ZERBTQpCZ05WSFJNQkFmOEVBakFBTUNNR0ExVWRFUVFjTUJxQ0dHSjZaVzVuYm1WNGRYTXhMbWxrYlhvdVpXNW5Mbk5sCmN6QU9CZ05WSFE4QkFmOEVCQU1DQmFBd0ZnWURWUjBsQVFIL0JBd3dDZ1lJS3dZQkJRVUhBd0V3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFCVlA4Z1hiVmxVTzVLNExQL1lrWXY5Ykp4MnNSODdHbjBRMi85dWZDOXpHMjJOdApYZUlCcDdqc2RDTWpNYzd4QzRWUHhTNktrSjRiUk9WZWI3V3BZK2tFbTRsSklreDNSQlhsemp4aitaT2JvVmhECjNoblNrWTRhNFFzdlJURTlucjQrYlRpSGN4ck90VGNIM244NEtFZXhjRDBwaktkN29yVWVGWHl6MjBJdTN4QjYKT0w0aHB4aEUrVkNTd1I0NXhVSFRLckt3K3pJa3VUV1NYMzBVQ0hZblExRWNTQkFKdHdLNWNkbXZtdUlXazJSdgpWSlVHSjlRQnFOV0padElUZlh3Zk4yT0ljT1VweHRPK3lXckQ5RHZGak1SYVZiUEIwMkIzNW5OcXA2QWN1N21hCnVsNjRicjlSc1grS2w2SGQ1eWltTTBieWJNTXZ4QUtpczNDaGFSMD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= +kind: Secret +metadata: + name: nexus-ca diff --git a/deploy/pfte/kustomization.yaml b/deploy/pfte/kustomization.yaml new file mode 100644 index 0000000..495766b --- /dev/null +++ b/deploy/pfte/kustomization.yaml @@ -0,0 +1,26 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- ../spell-registry/ +- secretstore.yaml +- externalsecret.yaml +- missions/ses24/ +- flux-policies/imagepolicy.yaml +- flux-policies/imagerepository.yaml +- flux-policies/imageupdateautomation.yaml +- flux-policies/nexus-ca.yaml + +patchesJson6902: + - target: + kind: Ingress + name: spell-registry + version: v1 + patch: |- + - op: replace + path: "/spec/rules/0/host" + value: "spell-registry.ing-us-p.spo.internal.ses.com" + - op: replace + path: "/spec/tls/0/hosts/0" + value: "spell-registry.ing-us-p.spo.internal.ses.com" diff --git a/deploy/pfte/missions/ses24/kube-ses24-server.yaml b/deploy/pfte/missions/ses24/kube-ses24-server.yaml new file mode 100644 index 0000000..14f88a9 --- /dev/null +++ b/deploy/pfte/missions/ses24/kube-ses24-server.yaml @@ -0,0 +1,51 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kube-ses24-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + reconcileStrategy: Revision + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: kube-ses24-spell-release + valuesKey: kube-ses24-values.yaml +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ses24-encryption-keys +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + dataFrom: + - extract: + key: /ses24-encryption + decodingStrategy: Auto + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ses24-encryption-cert +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + data: + - secretKey: ses24_rsa.pem + remoteRef: + key: /ses24-encryption + property: ses24_rsa.pem diff --git a/deploy/pfte/missions/ses24/kube-ses24-values.yaml b/deploy/pfte/missions/ses24/kube-ses24-values.yaml new file mode 100644 index 0000000..2313135 --- /dev/null +++ b/deploy/pfte/missions/ses24/kube-ses24-values.yaml @@ -0,0 +1,74 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.6.5-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + env: + NODE_ID_ses24prod: "3369" + NODE_NAME_3369: ses24prod + properties: + key: value + settings: + archiva: "ses24prod" + FLEETLIMITS: limitsdb-api.limitsdb.svc:8080 + FLEETLIMITS_SEAT: VALP + SATDB: satdb-api.satdb.svc:8080 + cws: "ses24prod" + obus: obus-server.obus.svc:54407 + maxprocs: 15 + mission: SES24 + family: SBNEO + seat: "" + applicable_missions: + SBNEO: SES24 + input_folder: "{{ .Values.spell_server.mission }}/InputFiles" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles" + additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip) || echo 'Could not find encryption key archive!'" + additionalVolumeMounts: + - mountPath: /etc/pki/tls/private/wrapped_keys/ + name: ses24-certs-folder + - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip + name: ses24-encryption-keys + subPath: ses24-keys.zip + - mountPath: /etc/pki/tls/ses24_keys/ses24_rsa.pem + name: ses24-encryption-cert + subPath: ses24_rsa.pem + additionalVolumes: + - name: ses24-certs-folder + emptyDir: + sizeLimit: 100Mi + medium: Memory + - name: ses24-encryption-cert + secret: + secretName: ses24-encryption-cert + optional: true + defaultMode: 0400 + - name: ses24-encryption-keys + secret: + secretName: ses24-encryption-keys + optional: true + defaultMode: 0400 +procedures: + size: 5Gi + repo_folder: SES24 + branch: OPS + server: prengrcs1.idmz.eng.ses + known_hosts: |- + propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5 + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT + +auth: + ssh: + version: v2.6.6.5-dev # {"$imagepolicy": "spell:spell-server:tag"} + ldap: + url: ldaps://peacdc1.xeneng.ses + +service: + loadBalancerIP: 10.113.45.168 \ No newline at end of file diff --git a/deploy/pfte/missions/ses24/kustomization.yaml b/deploy/pfte/missions/ses24/kustomization.yaml new file mode 100644 index 0000000..f7b5592 --- /dev/null +++ b/deploy/pfte/missions/ses24/kustomization.yaml @@ -0,0 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- kube-ses24-server.yaml +- ses24cntl.yaml + +configMapGenerator: +- name: kube-ses24-spell-release + options: + disableNameSuffixHash: true + files: + - kube-ses24-values.yaml + + +# configurations: +# - kustomizeconfig.yaml \ No newline at end of file diff --git a/deploy/pfte/missions/ses24/kustomizeconfig.yaml b/deploy/pfte/missions/ses24/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/pfte/missions/ses24/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/pfte/missions/ses24/ses24cntl.yaml b/deploy/pfte/missions/ses24/ses24cntl.yaml new file mode 100644 index 0000000..b0aa0da --- /dev/null +++ b/deploy/pfte/missions/ses24/ses24cntl.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: ses24prod + labels: + app.kubernetes.io/name: spell-cws-scorpio-ses24cntl + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "v2.6.6.5-dev" # {"$imagepolicy": "spell:spell-server:tag"} +spec: + type: ExternalName + externalName: cws-lb.scorpio-ses24.svc.cluster.local + diff --git a/deploy/pfte/secretstore.yaml b/deploy/pfte/secretstore.yaml new file mode 100644 index 0000000..f42d8c6 --- /dev/null +++ b/deploy/pfte/secretstore.yaml @@ -0,0 +1,26 @@ +# Expected Structure: +# spell-git-access: {"id_rsa":"", "id_rsa.pub":""} +# ldap-access: {} +# +# +# +apiVersion: external-secrets.io/v1beta1 +kind: SecretStore +metadata: + name: spell-vault-backend +spec: + provider: + vault: + server: "https://vault.vault:8200" + path: "soe/secret/spell" + version: "v2" + caProvider: + type: "Secret" + name: "vault-ca" + key: "ca.crt" + auth: + kubernetes: + mountPath: "kubernetes" + role: "serviceaccount" + serviceAccountRef: + name: "default" diff --git a/deploy/pfts/externalsecret.yaml b/deploy/pfts/externalsecret.yaml new file mode 100644 index 0000000..7a21cf4 --- /dev/null +++ b/deploy/pfts/externalsecret.yaml @@ -0,0 +1,34 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: spell-git-access +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + data: + - secretKey: id_rsa + remoteRef: + key: /spell-git-access + property: id_rsa + - secretKey: id_rsa.pub + remoteRef: + key: /spell-git-access + property: id_rsa.pub +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ldap-secret +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + data: + - secretKey: ldap-secret + remoteRef: + key: /ldap-secret + property: ldap-secret \ No newline at end of file diff --git a/deploy/pfts/flux-policies/imagepolicy.yaml b/deploy/pfts/flux-policies/imagepolicy.yaml new file mode 100644 index 0000000..4223022 --- /dev/null +++ b/deploy/pfts/flux-policies/imagepolicy.yaml @@ -0,0 +1,27 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImagePolicy +metadata: + name: spell-registry +spec: + imageRepositoryRef: + name: spell-registry + filterTags: + pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)' + extract: '$semver$minor' + policy: + semver: + range: x.x.x +--- +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImagePolicy +metadata: + name: spell-server +spec: + imageRepositoryRef: + name: spell-server + filterTags: + pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)' + extract: '$semver$minor' + policy: + semver: + range: x.x.x \ No newline at end of file diff --git a/deploy/pfts/flux-policies/imagerepository.yaml b/deploy/pfts/flux-policies/imagerepository.yaml new file mode 100644 index 0000000..b18478b --- /dev/null +++ b/deploy/pfts/flux-policies/imagerepository.yaml @@ -0,0 +1,23 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImageRepository +metadata: + name: spell-registry +spec: + certSecretRef: + name: nexus-ca + image: bzengnexus1.idmz.eng.ses/spell/spell-registry + interval: 1m0s + secretRef: + name: bzengnexus-secret +--- +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImageRepository +metadata: + name: spell-server +spec: + certSecretRef: + name: nexus-ca + image: bzengnexus1.idmz.eng.ses/spell/spell-server + interval: 1m0s + secretRef: + name: bzengnexus-secret \ No newline at end of file diff --git a/deploy/pfts/flux-policies/imageupdateautomation.yaml b/deploy/pfts/flux-policies/imageupdateautomation.yaml new file mode 100644 index 0000000..37858a8 --- /dev/null +++ b/deploy/pfts/flux-policies/imageupdateautomation.yaml @@ -0,0 +1,43 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta1 +kind: ImageUpdateAutomation +metadata: + name: spell-repo + namespace: spell +spec: + interval: 1m0s + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + git: + checkout: + ref: + branch: jgall/container-updates + commit: + author: + email: fluxcdbot@users.noreply.internal.ses.com + name: fluxcdbot + messageTemplate: | + Automated image update + + Automation name: {{ .AutomationObject }} + + Files: + {{ range $filename, $_ := .Updated.Files -}} + - {{ $filename }} + {{ end -}} + + Objects: + {{ range $resource, $_ := .Updated.Objects -}} + - {{ $resource.Kind }} {{ $resource.Name }} + {{ end -}} + + Images: + {{ range .Updated.Images -}} + - {{.}} + {{ end -}} + push: + branch: flux-image-version-update + update: + path: ./deploy/pfts + strategy: Setters \ No newline at end of file diff --git a/deploy/pfts/flux-policies/nexus-ca.yaml b/deploy/pfts/flux-policies/nexus-ca.yaml new file mode 100644 index 0000000..977340d --- /dev/null +++ b/deploy/pfts/flux-policies/nexus-ca.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +data: + caFile: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVtVENDQTRHZ0F3SUJBZ0lUTlFBQUFVeWxRZW1sNGwrcVdRQUFBQUFCVERBTkJna3Foa2lHOXcwQkFRc0YKQURBak1TRXdId1lEVlFRREV4aFRSVk5UWldOMWNtbDBlVWx6YzNWcGJtZERRVXhWTURFd0hoY05NakF3T0RBMgpNakUwTkRReldoY05NalF3T0RBMk1qRTFORFF6V2pDQmh6RUxNQWtHQTFVRUJoTUNURlV4RVRBUEJnTlZCQWNUCkNFSmxkSHBrYjNKbU1Rd3dDZ1lEVlFRS0V3TlRSVk14RERBS0JnTlZCQXNUQTFOUFJURWhNQjhHQTFVRUF4TVkKWW5wbGJtZHVaWGgxY3pFdWFXUnRlaTVsYm1jdWMyVnpNU1l3SkFZSktvWklodmNOQVFrQkZoZEZaSGRoY21RdQpRbUZ6ZEdWc2JHbEFjMlZ6TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFMbndHKzdJSTBtVCtidVp5cXU4TEd4V1NWQ3hMc1JJREpsYkZwUlNUOFdPdjh5SlpzVDBQMkNwbXZlUk9XNnMKNGNuOGs4RnBZdVRBZndLRVVTM3l5S1FyTjZobjlDZllJWVcrQ1FpcVJPQldiQWVQNVFQaDJmc3o3NURjRW5DTQoxeXRtOHZTcE05ejVHSm45b1VObTVyMEh0dmFUdVNoNzgxdEt6TEVtaHhRbE9kSWdqYzluZ2lLb1RqUC9zV2tuCkM0aU0rVEVFemtKYTNZaUZacVRsT3M5Q0JNVnhmK0IxTUMzODRvcU51YmtzSDRIVUZNbnp5cm9UOGJoVThiN1cKQk4vRUk0aEV6NDZ2ODlyZHFrdHVJZGwveklKejUrMm1ZYXRpWnc1M2VYRm1pVEV5VWNqem96YWFIdEpDWG1teQpUeDJuWnNIYllDeEs3Q3R4UWtMUTJXRUNBd0VBQWFPQ0FWOHdnZ0ZiTUIwR0ExVWREZ1FXQkJTYVc0WTUzbU1TCk1hZTJodm1qYzJhbmJIRGZNVEFmQmdOVkhTTUVHREFXZ0JTa3g2TVp3SGxoejlNaHRWWUVTRnByeC83YzBEQngKQmdOVkhSOEVhakJvTUdhZ1pLQmloaTlvZEhSd09pOHZZM0pzTG5ObGN5NWpiMjB2VTBWVFUyVmpkWEpwZEhsSgpjM04xYVc1blEwRk1WVEF4TG1OeWJJWXZhSFIwY0RvdkwyTnliQzV3YTJrdWMyVnpMMU5GVTFObFkzVnlhWFI1ClNYTnpkV2x1WjBOQlRGVXdNUzVqY213d1N3WUlLd1lCQlFVSEFRRUVQekE5TURzR0NDc0dBUVVGQnpBQ2hpOW8KZEhSd09pOHZZM0pzTG5CcmFTNXpaWE12VTBWVFUyVmpkWEpwZEhsSmMzTjFhVzVuUTBGTVZUQXhMbU55ZERBTQpCZ05WSFJNQkFmOEVBakFBTUNNR0ExVWRFUVFjTUJxQ0dHSjZaVzVuYm1WNGRYTXhMbWxrYlhvdVpXNW5Mbk5sCmN6QU9CZ05WSFE4QkFmOEVCQU1DQmFBd0ZnWURWUjBsQVFIL0JBd3dDZ1lJS3dZQkJRVUhBd0V3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFCVlA4Z1hiVmxVTzVLNExQL1lrWXY5Ykp4MnNSODdHbjBRMi85dWZDOXpHMjJOdApYZUlCcDdqc2RDTWpNYzd4QzRWUHhTNktrSjRiUk9WZWI3V3BZK2tFbTRsSklreDNSQlhsemp4aitaT2JvVmhECjNoblNrWTRhNFFzdlJURTlucjQrYlRpSGN4ck90VGNIM244NEtFZXhjRDBwaktkN29yVWVGWHl6MjBJdTN4QjYKT0w0aHB4aEUrVkNTd1I0NXhVSFRLckt3K3pJa3VUV1NYMzBVQ0hZblExRWNTQkFKdHdLNWNkbXZtdUlXazJSdgpWSlVHSjlRQnFOV0padElUZlh3Zk4yT0ljT1VweHRPK3lXckQ5RHZGak1SYVZiUEIwMkIzNW5OcXA2QWN1N21hCnVsNjRicjlSc1grS2w2SGQ1eWltTTBieWJNTXZ4QUtpczNDaGFSMD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= +kind: Secret +metadata: + name: nexus-ca diff --git a/deploy/pfts/kustomization.yaml b/deploy/pfts/kustomization.yaml new file mode 100644 index 0000000..cc709e4 --- /dev/null +++ b/deploy/pfts/kustomization.yaml @@ -0,0 +1,26 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- ../spell-registry/ +- secretstore.yaml +- externalsecret.yaml +- missions/ses24/ +- flux-policies/imagepolicy.yaml +- flux-policies/imagerepository.yaml +- flux-policies/imageupdateautomation.yaml +- flux-policies/nexus-ca.yaml + +patchesJson6902: + - target: + kind: Ingress + name: spell-registry + version: v1 + patch: |- + - op: replace + path: "/spec/rules/0/host" + value: "spell-registry.ing-us-s.spo.internal.ses.com" + - op: replace + path: "/spec/tls/0/hosts/0" + value: "spell-registry.ing-us-s.spo.internal.ses.com" diff --git a/deploy/pfts/missions/ses24/kube-ses24-server.yaml b/deploy/pfts/missions/ses24/kube-ses24-server.yaml new file mode 100644 index 0000000..72c8409 --- /dev/null +++ b/deploy/pfts/missions/ses24/kube-ses24-server.yaml @@ -0,0 +1,51 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kube-ses24-spell-server +spec: + chart: + spec: + chart: ./deploy/spell-server + reconcileStrategy: Revision + sourceRef: + kind: GitRepository + name: spell-repo + namespace: flux-system + interval: 10m0s + valuesFrom: + - kind: ConfigMap + name: kube-ses24-spell-server + valuesKey: kube-ses24-values.yaml +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ses24-encryption-keys +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + dataFrom: + - extract: + key: /ses24-encryption + decodingStrategy: Auto + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: ses24-encryption-cert +spec: + refreshInterval: "15s" # synchronisation + secretStoreRef: + name: spell-vault-backend + kind: SecretStore + + data: + - secretKey: ses24_rsa.pem + remoteRef: + key: /ses24-encryption + property: ses24_rsa.pem diff --git a/deploy/pfts/missions/ses24/kube-ses24-values.yaml b/deploy/pfts/missions/ses24/kube-ses24-values.yaml new file mode 100644 index 0000000..f13b594 --- /dev/null +++ b/deploy/pfts/missions/ses24/kube-ses24-values.yaml @@ -0,0 +1,65 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa +image: + registry: bzengnexus1.idmz.eng.ses +spell_server: + version: v2.6.6.5-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + env: + NODE_ID_ddcntl: "3369" + NODE_NAME_3369: ddcntl + properties: + key: value + settings: + archiva: "ddcntl" + FLEETLIMITS: limitsdb-api.limitsdb.svc:8080 + SATDB: satdb-api.satdb.svc:8080 + cws: "ddcntl" + obus: obus-server.obus.svc:54407 + maxprocs: 15 + ssh_port: 22 + mission: SES24 + family: SBNEO + seat: SIMP + applicable_missions: + SBNEO: SES24 + input_folder: "{{ .Values.spell_server.mission }}/InputFiles" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles" + additionalInitSteps: "cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip " + additionalVolumeMounts: + - mountPath: /etc/pki/tls/private/wrapped_keys/ + name: ses24-certs-folder + - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip + name: ses24-encryption-keys + subPath: ses24-keys.zip + - mountPath: /etc/pki/tls/ses24_keys/ses24_rsa.pem + name: ses24-encryption-cert + subPath: ses24_rsa.pem + additionalVolumes: + - name: ses24-certs-folder + emptyDir: + sizeLimit: 100Mi + medium: Memory + - name: ses24-encryption-cert + secret: + secretName: ses24-encryption-cert + optional: false + defaultMode: 0400 + - name: ses24-encryption-keys + secret: + secretName: ses24-encryption-keys + optional: false + defaultMode: 0400 +procedures: + size: 5Gi + repo_folder: SES24 + branch: SIM + server: prengrcs1.idmz.eng.ses + known_hosts: |- + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT + diff --git a/deploy/pfts/missions/ses24/kustomization.yaml b/deploy/pfts/missions/ses24/kustomization.yaml new file mode 100644 index 0000000..bcd399d --- /dev/null +++ b/deploy/pfts/missions/ses24/kustomization.yaml @@ -0,0 +1,16 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: spell +resources: +- kube-ses24-server.yaml +- ses24cntl.yaml + +configMapGenerator: +- name: kube-ses24-spell-server + files: + - kube-ses24-values.yaml + + +configurations: +- kustomizeconfig.yaml \ No newline at end of file diff --git a/deploy/pfts/missions/ses24/kustomizeconfig.yaml b/deploy/pfts/missions/ses24/kustomizeconfig.yaml new file mode 100644 index 0000000..f6b2027 --- /dev/null +++ b/deploy/pfts/missions/ses24/kustomizeconfig.yaml @@ -0,0 +1,6 @@ +nameReference: +- kind: ConfigMap + version: v1 + fieldSpecs: + - path: spec/valuesFrom/name + kind: HelmRelease \ No newline at end of file diff --git a/deploy/pfts/missions/ses24/ses24cntl.yaml b/deploy/pfts/missions/ses24/ses24cntl.yaml new file mode 100644 index 0000000..371883e --- /dev/null +++ b/deploy/pfts/missions/ses24/ses24cntl.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: ddcntl + labels: + app.kubernetes.io/name: spell-cws-scorpio-ses24cntl + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "v2.6.6.5-dev" # {"$imagepolicy": "spell:spell-server:tag"} +spec: + type: ExternalName + externalName: cws-lb.scorpio-ses24.svc.cluster.local + diff --git a/deploy/pfts/secretstore.yaml b/deploy/pfts/secretstore.yaml new file mode 100644 index 0000000..f42d8c6 --- /dev/null +++ b/deploy/pfts/secretstore.yaml @@ -0,0 +1,26 @@ +# Expected Structure: +# spell-git-access: {"id_rsa":"", "id_rsa.pub":""} +# ldap-access: {} +# +# +# +apiVersion: external-secrets.io/v1beta1 +kind: SecretStore +metadata: + name: spell-vault-backend +spec: + provider: + vault: + server: "https://vault.vault:8200" + path: "soe/secret/spell" + version: "v2" + caProvider: + type: "Secret" + name: "vault-ca" + key: "ca.crt" + auth: + kubernetes: + mountPath: "kubernetes" + role: "serviceaccount" + serviceAccountRef: + name: "default" diff --git a/deploy/spell-registry/deployment.yaml b/deploy/spell-registry/deployment.yaml new file mode 100644 index 0000000..1cbffe0 --- /dev/null +++ b/deploy/spell-registry/deployment.yaml @@ -0,0 +1,60 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spell-registry + labels: + app.kubernetes.io/name: spell-registry + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-registry:tag"} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: spell-registry + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-registry:tag"} + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + template: + metadata: + labels: + app.kubernetes.io/name: spell-registry + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-registry:tag"} + spec: + automountServiceAccountToken: true + serviceAccountName: spell-registry-sa + securityContext: + runAsNonRoot: true + runAsUser: 1001 + containers: + - image: bzengnexus1.idmz.eng.ses/spell/spell-registry:v2.6.5.1-dev # {"$imagepolicy": "spell:spell-registry"} + name: spell-registry + imagePullPolicy: Always + securityContext: + allowPrivilegeEscalation: false + resources: + requests: + cpu: "20m" + memory: "55M" + livenessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 90 + timeoutSeconds: 10 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 30 + timeoutSeconds: 10 + env: + - name: ENVVARNAME + value: ENVVARVALUE + ports: + - containerPort: 8080 + name: http diff --git a/deploy/spell-registry/ingress.yaml b/deploy/spell-registry/ingress.yaml new file mode 100644 index 0000000..233b19b --- /dev/null +++ b/deploy/spell-registry/ingress.yaml @@ -0,0 +1,26 @@ +# https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: spell-registry + labels: + app.kubernetes.io/name: spell-registry + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "1.0.0" +spec: + rules: + - host: spell-registry.ing-lu-s.spo.internal.ses.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: spell-registry + port: + number: 8080 + tls: + - secretName: ingress-tls + hosts: + - spell-registry.ing-lu-s.spo.internal.ses.com \ No newline at end of file diff --git a/deploy/spell-registry/kustomization.yaml b/deploy/spell-registry/kustomization.yaml new file mode 100644 index 0000000..7a2f5ff --- /dev/null +++ b/deploy/spell-registry/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: spell +resources: +- sa.yaml +- role.yaml +- rolebinding.yaml +- deployment.yaml +- service.yaml +- ingress.yaml diff --git a/deploy/spell-registry/role.yaml b/deploy/spell-registry/role.yaml new file mode 100644 index 0000000..7ed2865 --- /dev/null +++ b/deploy/spell-registry/role.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: spell-registry +rules: +- apiGroups: [""] # "" indicates the core API group + resources: ["services"] + verbs: ["get", "watch", "list"] +- apiGroups: ["apps"] # "" indicates the core API group + resources: ["deployments"] + verbs: ["get", "watch", "list"] \ No newline at end of file diff --git a/deploy/spell-registry/rolebinding.yaml b/deploy/spell-registry/rolebinding.yaml new file mode 100644 index 0000000..c0b5a67 --- /dev/null +++ b/deploy/spell-registry/rolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: spell-registry +subjects: +- name: spell-registry-sa + kind: ServiceAccount + apiGroup: "" +roleRef: + kind: Role + name: spell-registry + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/deploy/spell-registry/sa.yaml b/deploy/spell-registry/sa.yaml new file mode 100644 index 0000000..39366ef --- /dev/null +++ b/deploy/spell-registry/sa.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ServiceAccount + +metadata: + name: spell-registry-sa + labels: + app.kubernetes.io/name: spell-registry-sa + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "1.0.0" + +imagePullSecrets: +- name: bzengnexus-secret +- name: prengnexus-secret \ No newline at end of file diff --git a/deploy/spell-registry/service.yaml b/deploy/spell-registry/service.yaml new file mode 100644 index 0000000..2e33861 --- /dev/null +++ b/deploy/spell-registry/service.yaml @@ -0,0 +1,17 @@ +kind: Service +apiVersion: v1 +metadata: + name: spell-registry + labels: + app.kubernetes.io/name: spell-registry + app.kubernetes.io/instance: spell + app.kubernetes.io/version: "1.0.0" +spec: + selector: + app.kubernetes.io/name: spell-registry + app.kubernetes.io/instance: spell + type: ClusterIP + ports: + - name: http + port: 8080 + targetPort: 8080 \ No newline at end of file diff --git a/deploy/spell-server/.helmignore b/deploy/spell-server/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/deploy/spell-server/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/deploy/spell-server/Chart.yaml b/deploy/spell-server/Chart.yaml new file mode 100644 index 0000000..d7befe4 --- /dev/null +++ b/deploy/spell-server/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +name: spell-server +description: Spell Server Helm Chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 1.0.59 +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "2.6.10" diff --git a/deploy/spell-server/configs/context.xml b/deploy/spell-server/configs/context.xml new file mode 100644 index 0000000..e488817 --- /dev/null +++ b/deploy/spell-server/configs/context.xml @@ -0,0 +1,112 @@ +{{- define "spell-server.input-folder" -}} +{{- if .Values.spell_server.input_folder -}} +{{ tpl .Values.spell_server.input_folder . }} +{{- else -}} +{{ .Values.spell_server.mission }}/InputFiles +{{- end -}} +{{- end -}} +{{- define "spell-server.output-folder" -}} +{{- if .Values.spell_server.output_folder -}} +{{ tpl .Values.spell_server.output_folder . }} +{{- else -}} +{{ .Values.spell_server.mission }}/OutputFiles +{{- end -}} +{{- end }} + + + + + + {{ .Values.spell_server.mission }} Spacecraft + Context for {{ .Values.spell_server.mission }} + + + + + + {{ .Values.spell_server.driver.name}} + + + + + + {{ .Values.spell_server.spacecraft | default .Values.spell_server.mission }} + {{ .Values.spell_server.mission }} + {{ .Values.spell_server.family }} + {{ .Values.spell_server.driver.name}} + + + + + + $SPELL_DATA/{{ .Values.spell_server.mission }}/Procedures + $SPELL_DATA/{{ .Values.spell_server.mission }}/UserLib + + $SPELL_DATA/{{- include "spell-server.output-folder" . }} + $SPELL_DATA/{{- include "spell-server.input-folder" . }} + + + + + +{{- range $key, $value := .Values.spell_server.driver.settings }} + {{ tpl $value $ }} +{{- end}} + + {{ .Values.spell_server.seat }} + + + + + + + + 0 + 60 + True + False + False + 5 + DISABLED + DISABLED + ENABLED + True + + + + + + + {{- include "spell-server.input-folder" . }}/SpacecraftDB + {{- include "spell-server.input-folder" . }}/GroundDB + {{- include "spell-server.input-folder" . }}/ManeuvreMessage + {{- include "spell-server.input-folder" . }}/User + {{- include "spell-server.output-folder" . }}/AsRun + {{- include "spell-server.output-folder" . }}/Warmstart + {{- include "spell-server.input-folder" . }}/User + {{- include "spell-server.input-folder" . }}/EphemerisFile + + SCDB + GDB + + + + + + + + + 0.0 + 140 + + + 600 + 0.0 + + + False + 0.0 + + + + diff --git a/deploy/spell-server/configs/driver.xml b/deploy/spell-server/configs/driver.xml new file mode 100644 index 0000000..4e77b25 --- /dev/null +++ b/deploy/spell-server/configs/driver.xml @@ -0,0 +1,12 @@ + + {{ .Values.spell_server.driver.name | upper}} Driver + TM,TC,EV,RSC,TIME,RNG,TASK,MEM + {{ .Values.spell_server.maxprocs | default 15}} + {{ tpl (.Values.spell_server.driver.lib | default "$SPELL_DRIVER/lib") $ }} + {{ tpl (.Values.spell_server.driver.path | default "$SPELL_DRIVER/drivers") $ }} + +{{- range $key, $value := .Values.spell_server.driver.properties }} + {{ tpl $value $ }} +{{- end}} + + diff --git a/deploy/spell-server/configs/language.xml b/deploy/spell-server/configs/language.xml new file mode 100644 index 0000000..e661f57 --- /dev/null +++ b/deploy/spell-server/configs/language.xml @@ -0,0 +1,236 @@ + + + ABORT|SKIP|RECHECK|CANCEL + True + ENG + 120 + 3 + 0 + False + None + True + ABORT|SKIP|RECHECK|CANCEL + NOACTION + False + False + + + + ABORT|SKIP|RESEND|CANCEL + True + 0 + 120 + 0 + None + False + True + ABORT|SKIP|RESEND|CANCEL + NOACTION + False + False + + + + ABORT|SKIP|REPEAT|CANCEL + True + INFORMATION + SCOPE_PROC + TIME_MODE_LIVE + True + NOACTION + NOACTION + "" + + + + ABORT|SKIP|REPEAT|CANCEL + True + True + + + + ABORT|SKIP|REPEAT|CANCEL + True + True + + + + ABORT|SKIP|REPEAT|CANCEL + True + + + + ABORT|SKIP|REPEAT|CANCEL + True + + + + ABORT|SKIP|REPEAT + False + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|RECHECK|SKIP|CANCEL + ABORT|RECHECK|SKIP|CANCEL + True + None + False + + + + ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL + ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL + True + 1 + + + + ABORT|SKIP|CANCEL|REPEAT + None + + + + REPEAT|ABORT + True + OK_CANCEL + 60 + + + + None + ABORT|SKIP|CANCEL + True + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT + + + + 6 + ABORT|SKIP + + + + 6 + "ps" + + + + 3 + + + + True + True + True + ABORT|SKIP|REPEAT|CANCEL + True + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT|CANCEL + + + + ABORT|SKIP|REPEAT + + + + ABORT|SKIP|REPEAT + + + + diff --git a/deploy/spell-server/configs/log.properties b/deploy/spell-server/configs/log.properties new file mode 100644 index 0000000..0a2e97d --- /dev/null +++ b/deploy/spell-server/configs/log.properties @@ -0,0 +1,4 @@ +log4cplus.rootLogger=STDOUT +log4cplus.appender.STDOUT=log4cplus::ConsoleAppender +log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout +log4cplus.appender.STDOUT.layout.ConversionPattern=[ %d{ %Y/%m/%d %H:%M:%S.%q} ] [%-5p] [ %h ] [ %30.30l ]: %m%n diff --git a/deploy/spell-server/configs/scheduler_wasp.xml b/deploy/spell-server/configs/scheduler_wasp.xml new file mode 100644 index 0000000..35b3fab --- /dev/null +++ b/deploy/spell-server/configs/scheduler_wasp.xml @@ -0,0 +1,13 @@ + + WASP activity scheduler + + +{{- range $idx,$value := .Values.spell_addons.pace.pharos }} + {{ $value }} +{{- end }} + + + 15 + + /home/spell/.wasp + diff --git a/deploy/spell-server/configs/server.xml b/deploy/spell-server/configs/server.xml new file mode 100644 index 0000000..968ad6c --- /dev/null +++ b/deploy/spell-server/configs/server.xml @@ -0,0 +1,84 @@ + + + + + + + ENABLED + PROC + + 9 + + 20000 + + 20000 + + 30000 + + 10000 + + 60000 + + + + + + + language.xml + + + + + + + 19823 + 19723 + + + + + + + $SPELL_HOME/bin/SPELL-Executor + false + {{ .Values.spell_server.context_mission | default .Values.spell_server.mission }} + + + + + + + 0 + 3600 + True + False + False + 5 + DISABLED + DISABLED + + + + + + + driver.xml + + + + + + + context.xml + + + + + + +{{- range $key, $value := .Values.spell_server.applicable_missions }} + {{ tpl $value $ }} +{{- end}} + + + diff --git a/deploy/spell-server/templates/NOTES.txt b/deploy/spell-server/templates/NOTES.txt new file mode 100644 index 0000000..d392cdf --- /dev/null +++ b/deploy/spell-server/templates/NOTES.txt @@ -0,0 +1,5 @@ +1. Get the application URL by running these commands: + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "spell-server.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "spell-server.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} diff --git a/deploy/spell-server/templates/_helpers.tpl b/deploy/spell-server/templates/_helpers.tpl new file mode 100644 index 0000000..fd2fab7 --- /dev/null +++ b/deploy/spell-server/templates/_helpers.tpl @@ -0,0 +1,60 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "spell-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "spell-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "spell-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "spell-server.labels" -}} +helm.sh/chart: {{ include "spell-server.chart" . }} +{{ include "spell-server.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "spell-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "spell-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +spell-mission: {{ .Values.spell_server.mission | quote }} +spell-seat: {{ .Values.spell_server.seat | quote }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "spell-server.serviceAccountName" -}} +{{- default "spell-sa" .Values.serviceAccountName }} +{{- end }} diff --git a/deploy/spell-server/templates/cm.yaml b/deploy/spell-server/templates/cm.yaml new file mode 100644 index 0000000..1448ccf --- /dev/null +++ b/deploy/spell-server/templates/cm.yaml @@ -0,0 +1,28 @@ + +kind: ConfigMap +apiVersion: v1 +metadata: + name: {{ include "spell-server.fullname" . }} + labels: + {{- include "spell-server.labels" . | nindent 4 }} +data: + context.xml : | + {{ tpl (.Files.Get "configs/context.xml") . | indent 4 | trim}} + + driver.xml : | + {{ tpl (.Files.Get "configs/driver.xml") . | indent 4 | trim}} + + language.xml : | + {{ tpl (.Files.Get "configs/language.xml") . | indent 4 | trim}} + + server.xml : | + {{ tpl (.Files.Get "configs/server.xml") . | indent 4 | trim}} + + log.properties : | + {{ tpl (.Files.Get "configs/log.properties") . | indent 4 | trim}} + + scheduler_wasp.xml: | + {{ tpl (.Files.Get "configs/scheduler_wasp.xml") . | indent 4 | trim}} + + known_hosts: | + {{ .Values.procedures.known_hosts | default "" | indent 4 | trim }} \ No newline at end of file diff --git a/deploy/spell-server/templates/deployment.yaml b/deploy/spell-server/templates/deployment.yaml new file mode 100644 index 0000000..1162433 --- /dev/null +++ b/deploy/spell-server/templates/deployment.yaml @@ -0,0 +1,410 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "spell-server.fullname" . }} + labels: + {{- include "spell-server.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "spell-server.selectorLabels" . | nindent 6 }} + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "spell-server.selectorLabels" . | nindent 8 }} + spec: + serviceAccountName: {{ .Values.serviceAccountName | default "sa-spell" }} + securityContext: + fsGroup: 1000 + initContainers: + - name: spell-driver-init + resources: + requests: + cpu: "20m" + memory: "55M" + limits: + cpu: "1" + memory: "1Gi" + image: {{ .Values.image.registry }}/spell/spell-driver-ubuntu-{{ .Values.spell_server.driver.name }}:{{ .Values.spell_server.version }} + command: ["cp", "-r", "/home/spell/SPELL/", "/home/spell/SPELL_DRIVER"] + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}} + volumeMounts: + - mountPath: /home/spell/SPELL_DRIVER + name: spell-driver + containers: + - image: {{ .Values.image.registry }}/spell/spell-server-ubuntu:{{ .Values.spell_server.version }} + name: spell-server + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}} + resources: + requests: + cpu: "20m" + memory: "55M" + limits: + cpu: "3" + memory: "4Gi" + args: + - {{ .Values.spell_server.mission }} + securityContext: + capabilities: + drop: + - all + allowPrivilegeEscalation: false + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1000 + lifecycle: + preStop: + exec: + command: + - /bin/sh + - -c + - "pgrep SPELL | xargs -I{} /bin/sh -c 'echo \\\\$(ps -p {} -o comm=): >> $SPELL_LOG/SPELL_Restart_$(date +\"%Y%m%d%H%M\").log && gdb -p {} -ex \"thread apply all bt\" >> $SPELL_LOG/SPELL_Restart_$(date +\"%Y%m%d%H%M\").log 2>&1 '" + + postStart: + exec: + command: + - "/bin/sh" + - "-c" + - "mkdir -p /home/spell/procs/DEPLOYMENT/ && cp /home/spell/SPELL/release.nfo /home/spell/procs/DEPLOYMENT ; {{ .Values.spell_server.additionalInitSteps }}" + env: + - name: SPELL_MISSION + value: {{ .Values.spell_server.mission }} + - name: SPELL_DRIVER + value: /home/spell/SPELL_DRIVER/SPELL + - name: SPELL_DATA + value: /home/spell/procs/SPELL_PROCS +{{- range $key, $value := .Values.spell_server.driver.env }} + - name: {{$key}} + value: {{$value | quote}} +{{- end }} + startupProbe: + exec: + command: + - /home/spell/SPELL/bin/SPELL-Ping + failureThreshold: 20 + timeoutSeconds: 5 + initialDelaySeconds: 30 + periodSeconds: 30 + livenessProbe: + exec: + command: + - /home/spell/SPELL/bin/SPELL-Ping + failureThreshold: 3 + timeoutSeconds: 15 + periodSeconds: 15 + volumeMounts: + {{- with .Values.spell_server.additionalVolumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + - mountPath: /home/spell/SPELL_DRIVER + name: spell-driver + - mountPath: /home/spell/SPELL_CONFIG/contexts/context.xml + name: {{ include "spell-server.fullname" . }} + subPath: context.xml + - mountPath: /home/spell/SPELL_CONFIG/server/server_{{ .Values.spell_server.mission }}.xml + name: {{ include "spell-server.fullname" . }} + subPath: server.xml + - mountPath: /home/spell/SPELL_CONFIG/spell/language.xml + name: {{ include "spell-server.fullname" . }} + subPath: language.xml + - mountPath: /home/spell/SPELL_CONFIG/spell/log.properties + name: {{ include "spell-server.fullname" . }} + subPath: log.properties + - mountPath: /home/spell/SPELL_CONFIG/spell/driver.xml + name: {{ include "spell-server.fullname" . }} + subPath: driver.xml + - mountPath: /home/spell/services + name: {{ include "spell-server.fullname" . }} + subPath: services + + - mountPath: /home/spell/procs + name: spell-procs + + - name: fileds + image: {{ .Values.image.registry }}/{{ .Values.fileds.image }}:{{ .Values.fileds.version }} + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}} + args: + - "{{ .Values.procedures.server }}" + - "{{ .Values.spell_server.mission }}" + - "{{ .Values.procedures.repo_folder }}" + - "{{ .Values.procedures.branch }}" + resources: + requests: + cpu: "20m" + memory: "55M" + limits: + cpu: "1" + memory: "2Gi" + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1000 + capabilities: + drop: ["all"] + startupProbe: + exec: + command: + - sh + - -c + - test -d /home/spell/SPELL_PROCS/{{ .Values.spell_server.mission }}/Procedures || (echo "Checkout still in Progress" && exit 1) + failureThreshold: 20 + initialDelaySeconds: 30 + periodSeconds: 30 + volumeMounts: + - name: git-ssh-key + mountPath: "/home/dt/.ssh/id_rsa" + subPath: "id_rsa" + readOnly: true + - name: git-ssh-key + mountPath: "/home/dt/.ssh/id_rsa.pub" + subPath: "id_rsa.pub" + readOnly: true + - name: git-ssh-key + mountPath: "/home/dt/.ssh/config" + subPath: "config" + readOnly: true + + - mountPath: /home/spell/ + name: spell-procs + - name: dispatch-folder + mountPath: /home/dispatch/ + - name: dispatch-log-folder + mountPath: /home/dt/fileds/log/dispatch + - image: "{{ .Values.image.registry }}/{{ .Values.auth.ssh.image }}:{{ .Values.auth.ssh.version }}" + name: spell-ssh + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}} + resources: + requests: + cpu: "20m" + memory: "55M" + limits: + cpu: "1" + memory: "2Gi" + securityContext: + capabilities: + add: ["SYS_CHROOT", "CAP_AUDIT_WRITE"] + readinessProbe: + tcpSocket: + port: 8422 + initialDelaySeconds: 5 + periodSeconds: 10 + + env: + - name: SPELL_MISSION + value: {{ .Values.spell_server.mission }} + - name: LDAP_URL + value: {{ .Values.auth.ssh.ldap.url }} + - name: LDAP_BIND_DN + value: {{ .Values.auth.ssh.ldap.binddn }} + - name: SSH_PORT + value: "8422" + - name: SPELL_HOME + value: /home/spell/ + ports: + - containerPort: 8422 + name: ssh + volumeMounts: + {{- with .Values.procedures.additionalVolumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: {{ .Values.auth.ssh.ldap.bindpwSecret }} + mountPath: /etc/ldap_password + subPath: ldap-secret + - mountPath: /home/spell + name: spell-procs +{{- if .Values.spell_addons.logrotate.enabled }} + - image: {{ .Values.image.registry }}/{{ .Values.spell_addons.logrotate.image }}:{{ .Values.spell_addons.logrotate.version }} + name: logrotate + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}} + resources: + requests: + cpu: "20m" + memory: "55M" + limits: + cpu: "2" + memory: "1000M" + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1000 + capabilities: + drop: ["all"] + env: + - name: SPELL_MISSION + value: {{ .Values.spell_server.mission }} + - name: SPELL_DRIVER + value: /home/spell/SPELL_DRIVER/SPELL + - name: SPELL_DATA + value: /home/spell/procs/SPELL_PROCS +{{- range $key, $value := .Values.spell_addons.logrotate.env }} + - name: {{$key}} + value: {{$value | quote}} +{{- end }} + volumeMounts: + {{- with .Values.spell_addons.logrotate.additionalVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} + - mountPath: /home/spell/SPELL_DRIVER + name: spell-driver + - mountPath: /home/spell/SPELL_CONFIG/contexts/context_{{ .Values.spell_server.mission }}.xml + name: {{ include "spell-server.fullname" . }} + subPath: context.xml + - mountPath: /home/spell/SPELL_CONFIG/contexts/context.xml + name: {{ include "spell-server.fullname" . }} + subPath: context.xml + - mountPath: /home/spell/SPELL_CONFIG/server/server_{{ .Values.spell_server.mission }}.xml + name: {{ include "spell-server.fullname" . }} + subPath: server.xml + - mountPath: /home/spell/SPELL_CONFIG/spell/language.xml + name: {{ include "spell-server.fullname" . }} + subPath: language.xml + - mountPath: /home/spell/SPELL_CONFIG/spell/log.properties + name: {{ include "spell-server.fullname" . }} + subPath: log.properties + - mountPath: /home/spell/SPELL_CONFIG/spell/scheduler_wasp.xml + name: {{ include "spell-server.fullname" . }} + subPath: scheduler_wasp.xml + - mountPath: /home/spell/SPELL_CONFIG/spell/driver.xml + name: {{ include "spell-server.fullname" . }} + subPath: driver.xml + - mountPath: /home/spell/services + name: {{ include "spell-server.fullname" . }} + subPath: services + - mountPath: /home/spell/procs + name: spell-procs +{{- end }} +{{- if .Values.spell_addons.pace.enabled }} + - image: {{ .Values.image.registry }}/{{ .Values.spell_addons.pace.image }}:{{ .Values.spell_addons.pace.version }} + name: pace + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}} + resources: + requests: + cpu: "20m" + memory: "55M" + limits: + cpu: "1" + memory: "500M" + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1000 + capabilities: + drop: ["all"] + args: +{{- range $idx,$value := .Values.spell_addons.pace.args }} + - {{ $value }} +{{- end }} + env: + - name: SPELL_MISSION + value: {{ .Values.spell_server.mission }} + - name: SPELL_DRIVER + value: /home/spell/SPELL_DRIVER/SPELL + - name: SPELL_DATA + value: /home/spell/procs/SPELL_PROCS +{{- if .Values.spell_addons.pace.useDriver }} +{{- range $key, $value := .Values.spell_server.driver.env }} + - name: {{$key}} + value: {{$value | quote}} +{{- end }} +{{- end }} +{{- range $key, $value := .Values.spell_addons.pace.env }} + - name: {{$key}} + value: {{$value | quote}} +{{- end }} + volumeMounts: + {{- with .Values.spell_addons.pace.additionalVolumeMounts }} + {{- toYaml . | nindent 10 }} + {{- end }} +{{- if .Values.spell_addons.pace.useDriver }} + - mountPath: /home/spell/SPELL_DRIVER + name: spell-driver +{{- end }} + - mountPath: /home/spell/SPELL_CONFIG/contexts/context_{{ .Values.spell_server.mission }}.xml + name: {{ include "spell-server.fullname" . }} + subPath: context.xml + - mountPath: /home/spell/SPELL_CONFIG/contexts/context.xml + name: {{ include "spell-server.fullname" . }} + subPath: context.xml + - mountPath: /home/spell/SPELL_CONFIG/server/server_{{ .Values.spell_server.mission }}.xml + name: {{ include "spell-server.fullname" . }} + subPath: server.xml + - mountPath: /home/spell/SPELL_CONFIG/spell/language.xml + name: {{ include "spell-server.fullname" . }} + subPath: language.xml + - mountPath: /home/spell/SPELL_CONFIG/spell/log.properties + name: {{ include "spell-server.fullname" . }} + subPath: log.properties + - mountPath: /home/spell/SPELL_CONFIG/spell/scheduler_wasp.xml + name: {{ include "spell-server.fullname" . }} + subPath: scheduler_wasp.xml + - mountPath: /home/spell/SPELL_CONFIG/spell/driver.xml + name: {{ include "spell-server.fullname" . }} + subPath: driver.xml + - mountPath: /home/spell/services + name: {{ include "spell-server.fullname" . }} + subPath: services +{{- if .Values.spell_addons.pace.mountProcs }} + - mountPath: /home/spell/procs + name: spell-procs +{{- end }} + +{{- end }} + volumes: + {{- with .Values.spell_addons.pace.additionalVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.spell_server.additionalVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: dispatch-folder + emptyDir: + sizeLimit: 100Mi + - name: dispatch-log-folder + emptyDir: + sizeLimit: 1Gi + - name: sssd-cache-folder + emptyDir: + sizeLimit: 1Gi + - name: git-ssh-key + secret: + secretName: spell-git-access + optional: false + defaultMode: 0400 + - name: spell-procs + persistentVolumeClaim: + claimName: {{ include "spell-server.fullname" . }}-pvc + - name: {{ .Values.auth.ssh.ldap.bindpwSecret }} + secret: + secretName: {{ .Values.auth.ssh.ldap.bindpwSecret }} + optional: false + - name: {{ include "spell-server.fullname" . }} + configMap: + name: {{ include "spell-server.fullname" . }} + - name: spell-driver + emptyDir: {} + restartPolicy: Always + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} \ No newline at end of file diff --git a/deploy/spell-server/templates/pvc.yaml b/deploy/spell-server/templates/pvc.yaml new file mode 100644 index 0000000..6503672 --- /dev/null +++ b/deploy/spell-server/templates/pvc.yaml @@ -0,0 +1,13 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ include "spell-server.fullname" . }}-pvc + labels: + {{- include "spell-server.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + storageClassName: {{ .Values.procedures.storageClass }} + resources: + requests: + storage: {{ .Values.procedures.size}} \ No newline at end of file diff --git a/deploy/spell-server/templates/service.yaml b/deploy/spell-server/templates/service.yaml new file mode 100644 index 0000000..c27d001 --- /dev/null +++ b/deploy/spell-server/templates/service.yaml @@ -0,0 +1,24 @@ +kind: Service +apiVersion: v1 +metadata: + name: {{ include "spell-server.fullname" . }} + labels: + {{- include "spell-server.labels" . | nindent 4 }} + annotations: + {{- toYaml .Values.service.annotations | nindent 4 }} +spec: + selector: + {{- include "spell-server.selectorLabels" . | nindent 4 }} + + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + nodePort: {{ .Values.service.nodePort }} + protocol: TCP + name: {{ .Values.service.name }} + targetPort: 8422 + + \ No newline at end of file diff --git a/deploy/spell-server/templates/tests/test-connection.yaml b/deploy/spell-server/templates/tests/test-connection.yaml new file mode 100644 index 0000000..51ab4f6 --- /dev/null +++ b/deploy/spell-server/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "spell-server.fullname" . }}-test-connection" + labels: + {{- include "spell-server.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "spell-server.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/deploy/spell-server/values.yaml b/deploy/spell-server/values.yaml new file mode 100644 index 0000000..0bbdbef --- /dev/null +++ b/deploy/spell-server/values.yaml @@ -0,0 +1,99 @@ +# Default values for spell-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +serviceAccountName: spell-sa + +image: + registry: bzengnexus1.idmz.eng.ses + +# tolerations: +# - key: agentpool +# operator: Equal +# value: escorpio +# effect: NoSchedule + +service: + annotations: {} + type: LoadBalancer + port: 22 + name: ssh + +spell_addons: + logrotate: + image: spell/logrotate-ubuntu + version: 2.6.10 + enabled: true + env: + LOGROTATE_INTERVAL: "daily" + DELAYED_START: 30 + additionalVolumeMounts: [] + additionalVolumes: [] + pace: + image: spell/pace + enabled: false + version: 2.0.7 + useDriver: true + mountProcs: true + env: {} + additionalVolumeMounts: [] + # - mountPath: /home/spell/.wasp + # name: wasp-secret + # subPath: ".wasp" + # readonly: true + additionalVolumes: [] + # - name: wasp-secret + # secret: + # secretName: wasp-secret + # optional: true + # defaultMode: 0400 + args: [] + # - "ZMP01" + pharos: [] + +auth: + mode: ssh #clear/ssh + ssh: + version: v2.6.8-dev + image: spell/ssh-server-ubuntu + ldap: + url: ldaps://beacdc1.xeneng.ses + binddn: CN=ldap,OU=G_SYS,OU=ses-users,DC=xeneng,DC=ses + bindpwSecret: ldap-secret + +fileds: + version: 1.3.7-dev + image: spell/fileds-ubuntu + +spell_server: + version: v2.6.8-dev # {"$imagepolicy": "spell:spell-server:tag"} + driver: + name: scorpio + lib: "$SPELL_DRIVER/drivers/{{ .Values.spell_server.driver.name }}/interface" + env: {} + properties: {} + settings: {} + #cws: "{{ .Values.spell_server.seat | lower }}cntl.scorpio.eng.ses" + #archiva: "{{ .Values.spell_server.seat | lower }}dbs01.scorpio.eng.ses" + #obus: bfts-ob.eng.ses:54407 + maxprocs: 15 + mission: ZMP01 + spacecraft: null + family: BSS702SP + seat: S3 + applicable_missions: {} + input_folder: "{{ .Values.spell_server.mission }}/InputFiles/{{ .Values.spell_server.mission }}" + output_folder: "{{ .Values.spell_server.mission }}/OutputFiles/{{ .Values.spell_server.mission }}" + additionalVolumeMounts: [] + additionalVolumes: [] + additionalInitSteps: "" +procedures: + additionalVolumeMounts: [] + storageClass: null + size: 5Gi + repo_folder: MPOWER + branch: SIM + server: bzengrcs1.idmz.eng.ses + known_hosts: |- + bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ== + prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT \ No newline at end of file diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 0000000..e69de29 diff --git a/docker/Makefile b/docker/Makefile new file mode 100644 index 0000000..41f481e --- /dev/null +++ b/docker/Makefile @@ -0,0 +1,14 @@ +# default: all + +REPO := bzengnexus1.idmz.eng.ses/ +# TAG := 1.0.0 + +TOPTARGETS := all push + +SUBDIRS := $(wildcard */.) + +$(TOPTARGETS): $(SUBDIRS) +$(SUBDIRS): + $(MAKE) -C $@ $(MAKECMDGOALS) REPO=$(REPO) + +.PHONY: $(TOPTARGETS) $(SUBDIRS) diff --git a/docker/drivers/Makefile b/docker/drivers/Makefile new file mode 100644 index 0000000..bc563b8 --- /dev/null +++ b/docker/drivers/Makefile @@ -0,0 +1,13 @@ +# default: all + +REPO := bzengnexus1.idmz.eng.ses/ + +TOPTARGETS := all push + +SUBDIRS := $(wildcard */.) + +$(TOPTARGETS): $(SUBDIRS) +$(SUBDIRS): + $(MAKE) -C $@ $(MAKECMDGOALS) REPO=$(REPO) + +.PHONY: $(TOPTARGETS) $(SUBDIRS) diff --git a/docker/drivers/example/Dockerfile b/docker/drivers/example/Dockerfile new file mode 100644 index 0000000..79391d2 --- /dev/null +++ b/docker/drivers/example/Dockerfile @@ -0,0 +1,26 @@ +ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 +ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 + +FROM ${BUILD_IMAGE} as builder +USER spell +WORKDIR /home/spell/SPELL_BUILD + +COPY --chown=spell . . +RUN mkdir -p /home/spell/SPELL && chown spell:spell /home/spell/SPELL +ENV SPELL_COTS=/home/spell/SPELL_COTS + +RUN ./build_driver.sh /home/spell/SPELL example "" "-DWITH_DEBUG -DWITH_KUBERNETES" + +FROM ${RUNTIME_IMAGE} + +COPY --chown=spell --from=builder /home/spell/SPELL /home/spell/SPELL + +ENV SPELL_HOME=/home/spell/SPELL +ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG +ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS +ENV SPELL_LOG=/home/spell/procs/SPELL_LOG +ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH +ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL +ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib + +USER spell diff --git a/docker/drivers/example/Makefile b/docker/drivers/example/Makefile new file mode 100644 index 0000000..47e3d50 --- /dev/null +++ b/docker/drivers/example/Makefile @@ -0,0 +1,20 @@ +default: build + +REPO := bzengnexus1.idmz.eng.ses/ +NAME := spell/spell-driver-ubuntu-example +COMMIT := $(shell git rev-parse --short HEAD) +TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true) +TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG}) + +VERSION := $(TAG:v%=%) +ifneq ($(COMMIT), $(TAG_COMMIT)) + VERSION := $(VERSION)-dev +endif +TAG := $(VERSION) + +build: + docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../../ -f ./Dockerfile + +push: + docker push $(REPO)$(NAME):v$(TAG) + diff --git a/docker/drivers/fuzzer/Dockerfile b/docker/drivers/fuzzer/Dockerfile new file mode 100644 index 0000000..ff3de18 --- /dev/null +++ b/docker/drivers/fuzzer/Dockerfile @@ -0,0 +1,25 @@ +ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 +ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 + +FROM ${BUILD_IMAGE} as builder +USER spell +WORKDIR /home/spell/SPELL_BUILD + +COPY --chown=spell . . +RUN mkdir -p /home/spell/SPELL && chown spell:spell /home/spell/SPELL +ENV SPELL_COTS=/home/spell/SPELL_COTS + +RUN ./build_driver.sh /home/spell/SPELL fuzzer "" "-DWITH_DEBUG -DWITH_KUBERNETES" + +FROM ${RUNTIME_IMAGE} +COPY --chown=spell --from=builder /home/spell/SPELL /home/spell/SPELL + +ENV SPELL_HOME=/home/spell/SPELL +ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG +ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS +ENV SPELL_LOG=/home/spell/procs/SPELL_LOG +ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH +ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL +ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib + +USER spell diff --git a/docker/drivers/fuzzer/Makefile b/docker/drivers/fuzzer/Makefile new file mode 100644 index 0000000..d44ccf0 --- /dev/null +++ b/docker/drivers/fuzzer/Makefile @@ -0,0 +1,20 @@ +default: build + +REPO := bzengnexus1.idmz.eng.ses/ +NAME := spell/spell-driver-ubuntu-fuzzer +COMMIT := $(shell git rev-parse --short HEAD) +TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true) +TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG}) + +VERSION := $(TAG:v%=%) +ifneq ($(COMMIT), $(TAG_COMMIT)) + VERSION := $(VERSION)-dev +endif +TAG := $(VERSION) + +build: + docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../../ -f ./Dockerfile + +push: + docker push $(REPO)$(NAME):v$(TAG) + diff --git a/docker/drivers/hifly2/Dockerfile b/docker/drivers/hifly2/Dockerfile new file mode 100644 index 0000000..9e053f9 --- /dev/null +++ b/docker/drivers/hifly2/Dockerfile @@ -0,0 +1,39 @@ +ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 +ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 + +FROM ${BUILD_IMAGE} as builder +USER root +RUN apt-get update && apt-get install -y omniidl libomniorb4-dev && rm -rf /var/cache/apt/archives /var/lib/apt/lists/* + +USER spell + +RUN mkdir -p /home/spell/SPELL_BUILD +WORKDIR /home/spell/SPELL_BUILD + +COPY --chown=spell . . +RUN mkdir -p /home/spell/SPELL +ENV SPELL_COTS=/home/spell/SPELL_COTS + +#RUN ./build_spell.sh /home/spell/SPELL "none" "-DWITH_DEBUG -DWITH_KUBERNETES" + +RUN cd drivers/hifly2 && ./generate_stubs.sh 6 && cd ../.. && ./build_driver.sh /home/spell/SPELL hifly "SPELL_SYN SPELL_UTIL SPELL_WRP" "-DWITH_DEBUG -DWITH_KUBERNETES" + +FROM ${RUNTIME_IMAGE} + +USER spell +COPY --from=builder --chown=spell /home/spell/SPELL /home/spell/SPELL + +ENV SPELL_HOME=/home/spell/SPELL +ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG +ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS +ENV SPELL_LOG=/home/spell/procs/SPELL_LOG +ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH +ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL +ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib + +RUN chmod u+rwx -R /home/spell && chmod g+rx -R /home/spell + +USER root +COPY drivers/scorpio/services /services +RUN cat /services >> /etc/services && rm /services +USER spell diff --git a/docker/drivers/hifly2/Makefile b/docker/drivers/hifly2/Makefile new file mode 100644 index 0000000..8825538 --- /dev/null +++ b/docker/drivers/hifly2/Makefile @@ -0,0 +1,21 @@ +default: build + +REPO := bzengnexus1.idmz.eng.ses/ +NAME := spell/spell-driver-ubuntu-hifly2 +COMMIT := $(shell git rev-parse --short HEAD) +TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true) +TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG}) + +VERSION := $(TAG:v%=%) +ifneq ($(COMMIT), $(TAG_COMMIT)) + VERSION := $(VERSION)-dev +endif +TAG := $(VERSION) + + +build: + docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../../ -f ./Dockerfile + +push: + docker push $(REPO)$(NAME):v$(TAG) + diff --git a/docker/drivers/scorpio/Dockerfile b/docker/drivers/scorpio/Dockerfile new file mode 100644 index 0000000..f01a1aa --- /dev/null +++ b/docker/drivers/scorpio/Dockerfile @@ -0,0 +1,30 @@ +ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 +ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 + +FROM ${BUILD_IMAGE} as builder +USER spell +WORKDIR /home/spell/SPELL_BUILD + +COPY --chown=spell . . +RUN mkdir -p /home/spell/SPELL && chown spell:spell /home/spell/SPELL +ENV SPELL_COTS=/home/spell/SPELL_COTS + +RUN ./build_driver.sh /home/spell/SPELL scorpio "" "-DWITH_DEBUG -DWITH_KUBERNETES" + +FROM ${RUNTIME_IMAGE} + +COPY --chown=spell --from=builder /home/spell/SPELL /home/spell/SPELL +COPY --chown=spell --from=builder /home/spell/SPELL_BUILD/build/drivers/scorpio/ITC_wrap* /home/spell/SPELL/drivers/scorpio/interface/ + +ENV SPELL_HOME=/home/spell/SPELL +ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG +ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS +ENV SPELL_LOG=/home/spell/procs/SPELL_LOG +ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH +ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL +ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib + +USER root +COPY drivers/scorpio/services /services +RUN cat /services >> /etc/services && rm /services +USER spell diff --git a/docker/drivers/scorpio/Makefile b/docker/drivers/scorpio/Makefile new file mode 100644 index 0000000..21800e9 --- /dev/null +++ b/docker/drivers/scorpio/Makefile @@ -0,0 +1,20 @@ +default: build + +REPO := bzengnexus1.idmz.eng.ses/ +NAME := spell/spell-driver-ubuntu-scorpio +COMMIT := $(shell git rev-parse --short HEAD) +TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true) +TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG}) + +VERSION := $(TAG:v%=%) +ifneq ($(COMMIT), $(TAG_COMMIT)) + VERSION := $(VERSION)-dev +endif +TAG := $(VERSION) + +build: + docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../../ -f ./Dockerfile + +push: + docker push $(REPO)$(NAME):v$(TAG) + diff --git a/docker/logrotate/Dockerfile b/docker/logrotate/Dockerfile new file mode 100644 index 0000000..37cd20e --- /dev/null +++ b/docker/logrotate/Dockerfile @@ -0,0 +1,37 @@ +ARG UBUNTU_VERSION=22.04 +ARG NEXUS_REPO=docker-weu.spo.internal.ses.com/ + +FROM ${NEXUS_REPO}ubuntu:${UBUNTU_VERSION} as base + +# permissions +ARG CONTAINER_UID=1001 +ARG CONTAINER_GID=1000 + +COPY ./go-cron.tar.gz /tmp/go-cron.tar.gz + +# install dev tools +RUN export CONTAINER_USER=logrotate && \ + export CONTAINER_GROUP=logrotate && \ + addgroup --group --gid $CONTAINER_GID logrotate && \ + adduser --uid $CONTAINER_UID --ingroup logrotate --home /usr/bin/logrotate.d --shell /bin/bash --system logrotate && \ + apt-get update && apt-get install -y \ + tini \ + tar \ + gzip \ + tzdata \ + logrotate && \ + mkdir -p /usr/bin/logrotate.d && \ + tar xvf /tmp/go-cron.tar.gz -C /usr/bin && \ + rm -rf /var/cache/apt/archives /var/lib/apt/lists/* + +COPY docker-entrypoint.sh /usr/bin/logrotate.d/docker-entrypoint.sh +COPY logrotate.conf /usr/bin/logrotate.d/logrotate.conf + +# environment variable for this container +ENV LOGROTATE_INTERVAL= \ + LOG_PATHS= + + +ENTRYPOINT ["/bin/tini","--","/usr/bin/logrotate.d/docker-entrypoint.sh"] +VOLUME ["/logrotate-status"] +CMD ["cron"] \ No newline at end of file diff --git a/docker/logrotate/Makefile b/docker/logrotate/Makefile new file mode 100644 index 0000000..6d17139 --- /dev/null +++ b/docker/logrotate/Makefile @@ -0,0 +1,21 @@ +default: build + +REPO := bzengnexus1.idmz.eng.ses/ +NAME := spell/logrotate-ubuntu +COMMIT := $(shell git rev-parse --short HEAD) +TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true) +TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG}) + +VERSION := $(TAG:v%=%) +ifneq ($(COMMIT), $(TAG_COMMIT)) + VERSION := $(VERSION)-dev +endif +TAG := $(VERSION) + + +build: + docker build --build-arg NEXUS_REPO= --build-arg VERSION_TAG=2.6.10 --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ./ -f ./Dockerfile + +push: + docker push $(REPO)$(NAME):v$(TAG) + diff --git a/docker/logrotate/docker-entrypoint.sh b/docker/logrotate/docker-entrypoint.sh new file mode 100644 index 0000000..5054085 --- /dev/null +++ b/docker/logrotate/docker-entrypoint.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# + + +if [ -n "${DELAYED_START}" ]; then + sleep ${DELAYED_START} +fi + +logrotate_croninterval="@daily" + +if [ -n "${LOGROTATE_INTERVAL}" ]; then + case "$LOGROTATE_INTERVAL" in + hourly) + logrotate_croninterval='@hourly' + ;; + daily) + logrotate_croninterval='@daily' + ;; + weekly) + logrotate_croninterval='@weekly' + ;; + monthly) + logrotate_croninterval='@monthly' + ;; + yearly) + logrotate_croninterval='@yearly' + ;; + *) + logrotate_croninterval="$LOGROTATE_INTERVAL" + ;; + esac +fi + +logrotate_cron_timetable="/usr/sbin/logrotate --state=/tmp/logrotate.status /usr/bin/logrotate.d/logrotate.conf" + +if [ "$1" = 'cron' ]; then + exec /usr/bin/go-cron "${logrotate_croninterval}" /bin/bash -c "${logrotate_cron_timetable}" +else + exec "$@" +fi + diff --git a/docker/logrotate/go-cron.tar.gz b/docker/logrotate/go-cron.tar.gz new file mode 100644 index 0000000..8133551 Binary files /dev/null and b/docker/logrotate/go-cron.tar.gz differ diff --git a/docker/logrotate/logrotate.conf b/docker/logrotate/logrotate.conf new file mode 100644 index 0000000..c7b1772 --- /dev/null +++ b/docker/logrotate/logrotate.conf @@ -0,0 +1,12 @@ +/home/spell/procs/SPELL_LOG/*.log { + daily + su logrotate logrotate + rotate 4 + size 10M + compress + missingokq + copytruncate + notifempty +} + + diff --git a/docker/spell-registry/.gitignore b/docker/spell-registry/.gitignore new file mode 100644 index 0000000..9e79245 --- /dev/null +++ b/docker/spell-registry/.gitignore @@ -0,0 +1,32 @@ +# macOS +.DS_Store + +# sbt specific +dist/* +target/ +lib_managed/ +src_managed/ +project/boot/ +project/plugins/project/ +project/local-plugins.sbt +.history +.ensime +.ensime_cache/ +.sbt-scripted/ +local.sbt + +# Bloop +.bsp + +# VS Code +.vscode/ + +# Metals +.bloop/ +.metals/ +metals.sbt + +# IDEA +.idea +.idea_modules +/.worksheet/ diff --git a/docker/spell-registry/.scalafmt.conf b/docker/spell-registry/.scalafmt.conf new file mode 100644 index 0000000..8cd9640 --- /dev/null +++ b/docker/spell-registry/.scalafmt.conf @@ -0,0 +1,2 @@ +version = "3.5.3" +runner.dialect = scala3 \ No newline at end of file diff --git a/docker/spell-registry/Makefile b/docker/spell-registry/Makefile new file mode 100644 index 0000000..d2d433e --- /dev/null +++ b/docker/spell-registry/Makefile @@ -0,0 +1,23 @@ +default: build + +REPO := bzengnexus1.idmz.eng.ses/ +NAME := spell/spell-registry +COMMIT := $(shell git rev-parse --short HEAD) +TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true) +TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG}) + +VERSION := $(TAG:v%=%) +ifneq ($(COMMIT), $(TAG_COMMIT)) + VERSION := $(VERSION)-dev +endif +TAG := $(VERSION) + + +build: +# docker run -it --rm -e http_proxy=http://bzengpx1.idmz.eng.ses:8080 -e https_proxy=http://bzengpx1.idmz.eng.ses:8080 -e no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -v $(PWD):/app -w /app sbtscala/scala-sbt:eclipse-temurin-19_36_1.8.0_3.2.1 sbt docker:publishLocal + VERSION=$(TAG) sbt docker:publishLocal + +push: + docker tag spell-registry:$(TAG) $(REPO)$(NAME):v$(TAG) + docker push $(REPO)$(NAME):v$(TAG) + diff --git a/docker/spell-registry/README.md b/docker/spell-registry/README.md new file mode 100644 index 0000000..6999c4f --- /dev/null +++ b/docker/spell-registry/README.md @@ -0,0 +1,85 @@ +# openapi-client + +Swagger Spell Registry - OpenAPI 3.0 +- API version: 1.0.0 + +Spell Registry Interface + + +*Automatically generated by the [OpenAPI Generator](https://openapi-generator.tech)* + +## Requirements + +Building the API client library requires: +1. Java 1.7+ +2. Maven/Gradle/SBT + +## Installation + +To install the API client library to your local Maven repository, simply execute: + +```shell +mvn clean install +``` + +To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: + +```shell +mvn clean deploy +``` + +Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information. + +### Maven users + +Add this dependency to your project's POM: + +```xml + + org.openapitools + openapi-client + 1.0.0 + compile + +``` + +### Gradle users + +Add this dependency to your project's build file: + +```groovy +compile "org.openapitools:openapi-client:1.0.0" +``` + +### SBT users + +```scala +libraryDependencies += "org.openapitools" % "openapi-client" % "1.0.0" +``` + +## Getting Started + +## Documentation for API Endpoints + +All URIs are relative to *http://spell-registry.bftd-kube.eng.ses/api/v1* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*RegistryApi* | **listSpellServers** | **GET** /list | Finds SPELL servers and return their status and connection infos +*ServerApi* | **listSpellServers** | **GET** /list | Finds SPELL servers and return their status and connection infos + + +## Documentation for Models + + - [SpellServer](SpellServer.md) + + +## Documentation for Authorization + +All endpoints do not require authorization. +Authentication schemes defined for the API: + +## Author + +juergen.gall@ses.com + diff --git a/docker/spell-registry/build.sbt b/docker/spell-registry/build.sbt new file mode 100644 index 0000000..4e652fe --- /dev/null +++ b/docker/spell-registry/build.sbt @@ -0,0 +1,33 @@ +val scala3Version = "3.2.1" + +Global / onChangedBuildSource := ReloadOnSourceChanges + +val artifactVersion = sys.env.getOrElse("VERSION", "1.0.0") + +lazy val root = project + .in(file(".")) + .settings( + name := "spell-registry", + inThisBuild(List( + version := artifactVersion, + organization := "com.ses", + )), + + scalaVersion := scala3Version, + dockerExposedPorts ++= Seq(8080), + dockerBaseImage := "docker-weu.spo.internal.ses.com/eclipse-temurin:19.0.1_10-jre-alpine", + + libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test, + libraryDependencies ++= Seq( + "com.goyeau" %% "kubernetes-client" % "0.9.0", + "com.typesafe" % "config" % "1.4.2", + "org.http4s" %% "http4s-ember-server" % "0.23.16" + ), + dockerUsername := Some("spell"), + dockerAutoremoveMultiStageIntermediateImages := false, + dockerAliases := Seq( + dockerAlias.value.withTag(Option("latest")).withRegistryHost(Option("docker-weu.spo.internal.ses.com")), + dockerAlias.value.withRegistryHost(Option("docker-weu.spo.internal.ses.com")) + ), + ) + .enablePlugins(JavaAppPackaging).enablePlugins(AshScriptPlugin).enablePlugins(DockerPlugin) diff --git a/docker/spell-registry/project/build.properties b/docker/spell-registry/project/build.properties new file mode 100644 index 0000000..8b9a0b0 --- /dev/null +++ b/docker/spell-registry/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.8.0 diff --git a/docker/spell-registry/project/plugins.sbt b/docker/spell-registry/project/plugins.sbt new file mode 100644 index 0000000..edc9886 --- /dev/null +++ b/docker/spell-registry/project/plugins.sbt @@ -0,0 +1,2 @@ + +addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.4") diff --git a/docker/spell-registry/src/main/resources/application.conf b/docker/spell-registry/src/main/resources/application.conf new file mode 100644 index 0000000..12e57b8 --- /dev/null +++ b/docker/spell-registry/src/main/resources/application.conf @@ -0,0 +1,2 @@ +apiserver="https://kubernetes.default" +server_port=8080 \ No newline at end of file diff --git a/docker/spell-registry/src/main/scala/KubeAPI.scala b/docker/spell-registry/src/main/scala/KubeAPI.scala new file mode 100644 index 0000000..85c29fd --- /dev/null +++ b/docker/spell-registry/src/main/scala/KubeAPI.scala @@ -0,0 +1,78 @@ +package com.ses + +import cats.effect.IO +import com.goyeau.kubernetes.client.* +import org.typelevel.log4cats.Logger +import org.typelevel.log4cats.slf4j.Slf4jLogger +import java.io.File +import org.http4s.AuthScheme +import org.http4s.Credentials.Token +import org.http4s.headers.Authorization +import org.http4s.implicits.* +import scala.concurrent.ExecutionContext +import scala.io.Source +import com.typesafe.config.Config +import com.typesafe.config.ConfigFactory +import org.http4s.Uri +import org.http4s.ParseFailure +import io.k8s.api.core.v1.Service +import io.k8s.api.core.v1.ServiceList +import cats.effect.unsafe.implicits.global +import io.k8s.api.core.v1.Pod +import io.k8s.api.apps.v1.Deployment + + +object KubeAPI { + implicit val config: Config = ConfigFactory.load("application") + + val apiServer = Uri.fromString(config.getString("apiserver")) match { + case Left(ParseFailure(sanitized, details)) => { + uri"https://kubernetes.default" + } + case Right(uri) => uri + } + lazy val namespace = Source + .fromFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") + .mkString + + lazy val kubernetesClient = + KubernetesClient[IO]( + KubeConfig.of[IO]( + server = apiServer, + authorization = Option( + Authorization( + Token( + AuthScheme.Bearer, + Source + .fromFile("/var/run/secrets/kubernetes.io/serviceaccount/token") + .mkString + ) + ) + ), + caCertFile = Option( + new File("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt") + ) + ) + ) + def requestHealth() = + KubeAPI.kubernetesClient != null + + def requestServices(): ServiceList = + KubeAPI.kubernetesClient.use { client => + { + for { + serviceList <- client.services.namespace(namespace).list(Map("app.kubernetes.io/name" -> "spell-server")) + } yield (serviceList) + } + }.unsafeRunSync() + + def getDeployment(name : String) : Deployment = + KubeAPI.kubernetesClient.use { client => + { + for { + serviceList <- client.deployments.namespace(namespace).get(name) + } yield (serviceList) + } + }.unsafeRunSync() + +} diff --git a/docker/spell-registry/src/main/scala/Main.scala b/docker/spell-registry/src/main/scala/Main.scala new file mode 100644 index 0000000..533da32 --- /dev/null +++ b/docker/spell-registry/src/main/scala/Main.scala @@ -0,0 +1,34 @@ +package com.ses + +import cats.effect.IO +import com.goyeau.kubernetes.client.* +import org.typelevel.log4cats.Logger +import org.typelevel.log4cats.slf4j.Slf4jLogger +import java.io.File +import org.http4s._ +import org.http4s.AuthScheme +import org.http4s.Credentials.Token +import org.http4s.headers.Authorization +import org.http4s.implicits.* +import scala.concurrent.ExecutionContext +import scala.io.Source +import com.typesafe.config.Config +import com.typesafe.config.ConfigFactory +import org.http4s.Uri +import org.http4s.ParseFailure +import org.http4s.HttpRoutes +import cats.effect.ExitCode +import com.ses.SpellServerService +import cats.effect.IOApp + +implicit val logger: Logger[IO] = Slf4jLogger.getLogger[IO] +implicit val config: Config = ConfigFactory.load("application") + + +object Main extends IOApp { + + override def run(args: List[String]): IO[ExitCode] = { + SpellServerService.serverStream[IO].useForever.as(ExitCode.Success) + } + +} diff --git a/docker/spell-registry/src/main/scala/SpellServerService.scala b/docker/spell-registry/src/main/scala/SpellServerService.scala new file mode 100644 index 0000000..9111802 --- /dev/null +++ b/docker/spell-registry/src/main/scala/SpellServerService.scala @@ -0,0 +1,121 @@ +package com.ses + +import com.comcast.ip4s._ +import org.http4s.dsl.Http4sDsl +import org.http4s.ember.server.EmberServerBuilder +import cats.effect._ +import cats.syntax.all._ +import fs2.Stream +import io.circe.Json +import org.http4s._ +import org.http4s.circe._ +import org.http4s.dsl.Http4sDsl +import org.http4s.headers._ +import org.http4s.multipart.Multipart +import org.http4s.server._ +import org.http4s.server.middleware.authentication.BasicAuth +import org.http4s.server.middleware.authentication.BasicAuth.BasicAuthenticator +import org.http4s.syntax.all._ +import com.typesafe.config.Config +import scala.util.Try + +import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._ +import org.typelevel.log4cats.Logger +import org.typelevel.log4cats.slf4j.Slf4jLogger + +sealed trait SpellMessage +case class SpellError(error: String) extends SpellMessage + +case class SpellService( + name: String, + mission: String, + seat: String, + ip: String, + contextPort: Int, + sshPort: Int, + running: Boolean +) + +object SpellServerService { + implicit val logger: Logger[IO] = Slf4jLogger.getLogger[IO] + + def serverStream[F[_]: Async](implicit + config: Config + ) = { + val port = Port.fromString(config.getString("server_port")) match { + case None => port"8080" + case Some(p) => p + } + + EmberServerBuilder.default + .withPort(port) + .withHost(host"0.0.0.0") + .withHttpApp(new SpellServerServiceRoutes[F].routes.orNotFound) + .withLogger(Slf4jLogger.getLogger[F]) + .build + } + +} + +class SpellServerServiceRoutes[F[_]: Sync] extends Http4sDsl[F] { + + val routes: HttpRoutes[F] = + HttpRoutes.of[F] { + case GET -> Root / "healthz" => { + Try { + val services = KubeAPI.requestHealth().asJson + + Ok(services) + }.handleError { f => + val result = SpellError(s"Failed with ${f}").asJson + + InternalServerError(result) + }.get + } + + case req @ GET -> Root / "list" => + Try { + val services = KubeAPI + .requestServices() + .items + .map[SpellService](kubeService => + val name = kubeService.metadata.get.name.get + val labels = kubeService.metadata.get.labels.getOrElse(Map()) + val ip = kubeService.status.fold(None)(status => + status.loadBalancer.fold(None)(lb => + lb.ingress.fold(None)(lbi => + if (lbi.isEmpty) None + else lbi.get(0).fold(None)(f => f.ip) + ) + ) + ) + val port = kubeService.spec.get.ports + .getOrElse(Seq()) + .find(f => f.name.getOrElse("") == "ssh") + .fold(None)(p => Some(p.port)) + val deployment = KubeAPI.getDeployment(name) + SpellService( + name = name, + mission = labels + .getOrElse("mission", labels.getOrElse("spell-mission", "")), + seat = + labels.getOrElse("seat", labels.getOrElse("spell-seat", "")), + ip = ip.getOrElse(""), + contextPort = 19823, + sshPort = port.getOrElse(-1), + running = ip.isDefined && port.isDefined && (labels.isDefinedAt( + "mission" + ) || labels.isDefinedAt("spell-mission")) && (labels + .isDefinedAt("seat") || labels.isDefinedAt("spell-seat")) && deployment.status.fold(false)(st => st.availableReplicas.fold(false)(_ > 0)) + ) + ) + + Ok(services.asJson) + }.handleError { f => + val result = SpellError(s"Failed with ${f}").asJson + + Ok(result) + }.get + + } +} diff --git a/docker/spell-registry/src/test/scala/MySuite.scala b/docker/spell-registry/src/test/scala/MySuite.scala new file mode 100644 index 0000000..621784d --- /dev/null +++ b/docker/spell-registry/src/test/scala/MySuite.scala @@ -0,0 +1,9 @@ +// For more information on writing tests, see +// https://scalameta.org/munit/docs/getting-started.html +class MySuite extends munit.FunSuite { + test("example test that succeeds") { + val obtained = 42 + val expected = 42 + assertEquals(obtained, expected) + } +} diff --git a/docker/spell-server/Dockerfile b/docker/spell-server/Dockerfile new file mode 100644 index 0000000..7f8b05d --- /dev/null +++ b/docker/spell-server/Dockerfile @@ -0,0 +1,43 @@ +ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 +ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0 +ARG VERSION_TAG=0.0.1 + +FROM ${BUILD_IMAGE} as builder +ARG VERSION_TAG + +USER root +RUN apt-get update && apt-get install -y libbackward-cpp-dev libdw-dev \ + && rm -rf /var/cache/apt/archives /var/lib/apt/lists/* + +USER spell +RUN mkdir -p /home/spell/SPELL_BUILD +WORKDIR /home/spell/SPELL_BUILD + +COPY --chown=spell . /home/spell/SPELL_BUILD +RUN mkdir -p /home/spell/SPELL && chown spell /home/spell/SPELL +ENV SPELL_COTS=/home/spell/SPELL_COTS +ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib + +RUN cd /home/spell/SPELL_BUILD && ./build_spell_ubuntu.sh /home/spell/SPELL "none" "-DBACKWARD_HAS_DW=1 -DWITH_BACKTRACE -DWITH_DEBUG -DWITH_KUBERNETES" + +FROM ${RUNTIME_IMAGE} +USER spell +COPY --chown=spell --from=builder /home/spell/SPELL /home/spell/SPELL + +ENV SPELL_HOME=/home/spell/SPELL +ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG +ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS +ENV SPELL_LOG=/home/spell/procs/SPELL_LOG +ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH +ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL +ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib + +WORKDIR /home/spell +RUN ln -sf /home/spell/procs/SPACECRAFT SPACECRAFT && ln -sf /home/spell/procs/SPELL_PROCS SPELL_PROCS + +USER root +COPY --from=builder /home/spell/SPELL_BUILD/drivers/scorpio/services /services +RUN cat /services >> /etc/services && rm /services +USER spell + +ENTRYPOINT ["SPELL-Server-Docker"] diff --git a/docker/spell-server/Makefile b/docker/spell-server/Makefile new file mode 100644 index 0000000..aa5649b --- /dev/null +++ b/docker/spell-server/Makefile @@ -0,0 +1,21 @@ +default: build + +REPO := bzengnexus1.idmz.eng.ses/ +NAME := spell/spell-server-ubuntu +COMMIT := $(shell git rev-parse --short HEAD) +TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true) +TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG}) + +VERSION := $(TAG:v%=%) +ifneq ($(COMMIT), $(TAG_COMMIT)) + VERSION := $(VERSION)-dev +endif +TAG := $(VERSION) + + +build: + docker build --build-arg VERSION_TAG=2.6.10 --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../ -f ./Dockerfile + +push: + docker push $(REPO)$(NAME):v$(TAG) + diff --git a/docker/ssh-server/Dockerfile b/docker/ssh-server/Dockerfile new file mode 100644 index 0000000..8ef7a57 --- /dev/null +++ b/docker/ssh-server/Dockerfile @@ -0,0 +1,22 @@ +ARG UBUNTU_VERSION=22.04 + +FROM docker-weu.spo.internal.ses.com/ubuntu:${UBUNTU_VERSION} as base + +RUN apt-get update && apt-get install -y openssh-server net-tools sssd nscd libnss-ldap libpam-ldap ldap-auth-config libpam-sss libnss-sss sssd-tools \ + && rm -rf /var/cache/apt/archives /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y rxvt-unicode \ + && rm -rf /var/cache/apt/archives /var/lib/apt/lists/* + +RUN groupadd spell && useradd -rm -d /home/spell -s /sbin/nologin -g spell -G spell -u 1001 spell + +RUN mkdir -p /var/run/sshd +ADD init.sh /init.sh +RUN chmod u+x /init.sh + + +EXPOSE 8422 +RUN chmod u+rwx -R /home/ && mkdir -p /usr/libexec/openssh/ && ln -s /usr/lib/sftp-server /usr/libexec/openssh/sftp-server && ln -s /usr/lib/sftp-server /bin/sftp-server && chmod g+rx -R /home/ && touch /etc/services && pam-auth-update --enable mkhomedir + +ENV TERM=xterm + +CMD /init.sh \ No newline at end of file diff --git a/docker/ssh-server/Dockerfile.centos b/docker/ssh-server/Dockerfile.centos new file mode 100644 index 0000000..0fc489d --- /dev/null +++ b/docker/ssh-server/Dockerfile.centos @@ -0,0 +1,25 @@ + +FROM centos:7 as base + +RUN yum-config-manager --save --disable base && rm /etc/yum.repos.d/* +COPY etc/yum.repos.d/* /etc/yum.repos.d/ + +RUN yum makecache fast && yum update -y +RUN yum-config-manager --save --disable base --disable extras --disable updates +RUN yum clean all && yum install -y \ + openssl net-tools \ + nss-pam-ldapd nscd openldap-clients openssh-server openssh-clients rsyslog authconfig \ + && yum clean all + +RUN groupadd spell && useradd -rm -d /home/spell -s /sbin/nologin -g spell -G spell -u 1001 spell + +RUN mkdir -p /var/run/sshd +ADD init.sh /init.sh +RUN chmod u+x /init.sh + + +EXPOSE 8422 +RUN chmod u+rwx -R /home/ && chmod g+rx -R /home/ + +CMD /init.sh + diff --git a/docker/ssh-server/Makefile b/docker/ssh-server/Makefile new file mode 100644 index 0000000..93fa37d --- /dev/null +++ b/docker/ssh-server/Makefile @@ -0,0 +1,20 @@ +default: build + +REPO := bzengnexus1.idmz.eng.ses/ +NAME := spell/ssh-server-ubuntu +COMMIT := $(shell git rev-parse --short HEAD) +TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true) +TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG}) + +VERSION := $(TAG:v%=%) +ifneq ($(COMMIT), $(TAG_COMMIT)) + VERSION := $(VERSION)-dev +endif +TAG := $(VERSION) + +build: + docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) . + +push: + docker push $(REPO)$(NAME):v$(TAG) + diff --git a/docker/ssh-server/etc/yum.repos.d/bzenginst1.repo b/docker/ssh-server/etc/yum.repos.d/bzenginst1.repo new file mode 100644 index 0000000..08ec4e9 --- /dev/null +++ b/docker/ssh-server/etc/yum.repos.d/bzenginst1.repo @@ -0,0 +1,7 @@ +[bzenginst1] +name=YUM repo on bzenginst1.idmz.eng.ses +baseurl=http://10.35.66.136/centos/$releasever/$basearch +enabled=1 +gpgcheck=0 +proxy=_none_ + diff --git a/docker/ssh-server/init.sh b/docker/ssh-server/init.sh new file mode 100644 index 0000000..bfa26ba --- /dev/null +++ b/docker/ssh-server/init.sh @@ -0,0 +1,237 @@ +#!/bin/bash +# + +#LDAP_PASSWORD= + +[ -z "${LDAP_PASSWORD}" ] && LDAP_PASSWORD=$(cat /etc/ldap_password) +[ -z "${LDAP_URL}" ] && LDAP_URL=$(cat /etc/ldap_url) +[ -z "${LDAP_URL}" ] && LDAP_URL="ldaps://beacdc1.xeneng.ses" +[ -z "${SSH_PORT}" ] && SSH_PORT=8422 +[ -z "${LDAP_BIND_DN}" ] && LDAP_BIND_DN="CN=ldap,OU=G_SYS,OU=ses-users,DC=xeneng,DC=ses" +[ -z "${LDAP_SEARCH_BASE}" ] && LDAP_SEARCH_BASE="OU=ses-users,DC=xeneng,DC=ses" + +[ -f /etc/ssh/ssh_host_rsa_key ] || ssh-keygen -f /etc/ssh/ssh_host_rsa_key -q -N '' + +mkdir -p /var/lib/sss/db/ +cat > /etc/sssd/sssd.conf < /sshd_config < /home/spell/groups/\" \$7 \" &\" + system(cmd) + print substr(\$4,p+1) \"=\" \$7 + }' > /home/spell/users" +# id -G -n \$7 \ No newline at end of file diff --git a/drivers/Makefile.am b/drivers/Makefile.am index 03a1e42..ab61088 100644 --- a/drivers/Makefile.am +++ b/drivers/Makefile.am @@ -1,5 +1,41 @@ -SUBDIRS= +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ -if WITH_DRIVER_STD -SUBDIRS+=standalone +SUBDIRS = example + +if WITH_DRIVER_HIFLY +SUBDIRS += hifly2 +endif + +if WITH_DRIVER_SCORPIO +SUBDIRS += scorpio endif + +SERVICE=${top_srcdir}/drivers/service +SERVICE_DST=${exec_prefix}/drivers/service + +all-local: + find ${SERVICE} -type f -name "*.py" -print0 | xargs -0 -n1 sh -c LD_LIBRARY_PATH=${SPELL_COTS}/lib ${PYTHON2} ${top_srcdir}/scripts/src/SPELL-Compile + find ${SERVICE} -type f -name "*.py" -print0 | xargs -0 -n1 sh -c LD_LIBRARY_PATH=${SPELL_COTS}/lib ${PYTHON3} ${top_srcdir}/scripts/src/SPELL-Compile + +install-exec-hook: + mkdir -p ${SERVICE_DST} + cp -ur ${SERVICE}/*.py ${SERVICE_DST} diff --git a/drivers/example/Makefile.am b/drivers/example/Makefile.am index db5e249..fe55830 100644 --- a/drivers/example/Makefile.am +++ b/drivers/example/Makefile.am @@ -1,53 +1,36 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ DRIVER=example -DRIVER_SRC=src -DRIVER_CFG=config +DRIVER_SRC=${srcdir}/python +DRIVER_CFG=${srcdir}/config +DRIVER_DST=${exec_prefix}/drivers/${DRIVER} +CONFIG_DST=${exec_prefix}/config/spell all-local: - if [[ ! -d ${DRIVER_SRC} ]] ;\ - then \ - cp -r ${top_srcdir}/drivers/${DRIVER}/${DRIVER_SRC} . > /dev/null ;\ - fi - ${top_srcdir}/py-compiledir ${DRIVER_SRC} - -clean-local: - find ${DRIVER_SRC} -name "*.pyc" | xargs rm -f - find ${DRIVER_SRC} -name "*.pyo" | xargs rm -f - rm -f ${DRIVER_SRC}/build.date + find ${DRIVER_SRC} -type f -name "*.py" -print0 | xargs -0 -n1 sh -c LD_LIBRARY_PATH=${SPELL_COTS}/lib ${PYTHON2} ${top_srcdir}/scripts/src/SPELL-Compile + find ${DRIVER_SRC} -type f -name "*.py" -print0 | xargs -0 -n1 sh -c LD_LIBRARY_PATH=${SPELL_COTS}/lib ${PYTHON3} ${top_srcdir}/scripts/src/SPELL-Compile install-exec-hook: - if [[ ! -d ${exec_prefix}/drivers ]] ;\ - then \ - mkdir ${exec_prefix}/drivers ;\ - fi - rm -rf ${exec_prefix}/drivers/${DRIVER} - cp -r ${DRIVER_SRC} ${exec_prefix}/drivers/${DRIVER} - find ${exec_prefix}/drivers/${DRIVER} -name ".svn" | xargs rm -rf - find ${exec_prefix}/drivers/${DRIVER} -name ".py" | xargs rm -f - mkdir -p ${exec_prefix}/config/spell - cp -f ${DRIVER_CFG}/driver_${DRIVER}.xml ${exec_prefix}/config/spell/. + mkdir -p ${DRIVER_DST} + cp -ur ${DRIVER_SRC}/* ${DRIVER_DST} + mkdir -p ${CONFIG_DST} + cp -u ${DRIVER_CFG}/driver_${DRIVER}.xml ${exec_prefix}/config/spell diff --git a/drivers/example/config/driver_example.xml b/drivers/example/config/driver_example.xml index ddb841d..a579dc3 100644 --- a/drivers/example/config/driver_example.xml +++ b/drivers/example/config/driver_example.xml @@ -1,6 +1,6 @@ Example SPELL driver - TM,TC,EV,TIME,TASK,RSC,USR + TM,TC,EV,TIME,TASK,RSC,USER 5 $SPELL_HOME/drivers diff --git a/drivers/example/python/__init__.py b/drivers/example/python/__init__.py new file mode 100644 index 0000000..c37d2df --- /dev/null +++ b/drivers/example/python/__init__.py @@ -0,0 +1,25 @@ +################################################################################### +## MODULE : __init__ +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: Module initialization +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### diff --git a/drivers/example/python/config.py b/drivers/example/python/config.py new file mode 100644 index 0000000..b8d933e --- /dev/null +++ b/drivers/example/python/config.py @@ -0,0 +1,100 @@ +################################################################################### +## MODULE : config +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +#******************************************************************************* +# SPELL Imports +#******************************************************************************* +from spell.lib.exception import DriverException + +#******************************************************************************* +# Local Imports +#******************************************************************************* + +#******************************************************************************* +# System Imports +#******************************************************************************* +import os,sys + +############################################################################### +# Module import definition + +__all__ = ['CONFIG'] + +INTERFACE_DEFAULTS = {} + +############################################################################### +# Superclass +import spell.lib.adapter.config.ConfigInterface as superClass + +############################################################################### +# The configuration interface is typically in charge of managing resources and +# mechanisms that have nothing to do with specific services like TM, TC and EV. +# This interface normally prepares the ground so that the service interfaces +# like TM can initialize properly. The configuration interface is the first +# on being initialized. +############################################################################### +class ConfigInterface(superClass): + + #========================================================================== + def __init__(self): + """ + Perform the initialization of your data here, after the superClass + initialization. + """ + superClass.__init__(self) + # TODO Your initialization stuff here + + #========================================================================== + def setup(self, ctxConfig, drvConfig): + """ + Start the internal driver mechanisms (typically, start a centralized + internal service that manages all driver capabilities) + + ctxConfig : provides the current context information (S/C name and others) + drvConfig : provides the configuration parameters for this driver according + to the xml config file. + """ + superClass.setup(self, ctxConfig, drvConfig) + # TODO Initialize here the driver internal mechanisms + # Throw DriverException in case of fatal errors + + #========================================================================== + def cleanup(self, shutdown = False): + """ + Perform the cleanup of the internal driver resources. + + shutdown: when true, the SPELL executor is shutting down so every resource + should be released. When false, it means that the driver is being unloaded + but the executor keeps running. That is, it is possible that the driver + will be loaded again later on (e.g. on a RELOAD command). In this case + it may be interesting to keep some resources ready when 'shutdown' is false. + """ + superClass.cleanup(self, shutdown) + # TODO Release resources and cleanup stuff here + +############################################################################### +# Interface instance +CONFIG = ConfigInterface() diff --git a/drivers/example/python/constants.py b/drivers/example/python/constants.py new file mode 100644 index 0000000..f393547 --- /dev/null +++ b/drivers/example/python/constants.py @@ -0,0 +1,30 @@ +################################################################################### +## MODULE : constants +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: Definition of driver specific constants +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +#: Example constant +MY_CONSTANT = 'MY_CONSTANT' +#: Example constant +MY_FLAG = 1 diff --git a/drivers/example/python/ev.py b/drivers/example/python/ev.py new file mode 100644 index 0000000..e29f903 --- /dev/null +++ b/drivers/example/python/ev.py @@ -0,0 +1,104 @@ +################################################################################### +## MODULE : ev +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: Event interface of the driver connection layer +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +################################################################################ + +#******************************************************************************* +# SPELL imports +#******************************************************************************* +from spell.lib.exception import DriverException +from spell.lang.modifiers import * +from spell.lang.constants import * + +#******************************************************************************* +# Local imports +#******************************************************************************* + +#******************************************************************************* +# System imports +#******************************************************************************* +import sys,os + +############################################################################### +# Module import definition + +__all__ = ['EV'] + +############################################################################### +# Superclass +import spell.lib.adapter.ev.EvInterface as superClass + +############################################################################### +# The events interface is in charge of managing GCS events. +############################################################################### +class EvInterface(superClass): + + #========================================================================== + def __init__(self): + """ + Perform the initialization of Event Handling data here, after the + superclass initialization + """ + superClass.__init__(self) + # TODO Your initialization stuff here + + #========================================================================== + def setup(self, ctxConfig, drvConfig): + """ + Start the internal driver EV mechanisms + + ctxConfig : provides the current context information (S/C name and others) + drvConfig : provides the configuration parameters for this driver according + to the xml config file. + """ + superClass.setup(self, ctxConfig, drvConfig) + # TODO Your startup stuff here + + #========================================================================== + def cleanup(self): + """ + Perform the cleanup of the internal driver EV resources. + """ + superClass.cleanup(self) + # TODO Release resources and cleanup stuff here + + #========================================================================== + def _raiseEvent(self, message, config): + """ + Invoked by the system in order to inject an event into the GCS. + + message: string containing the event message + config: dictionary containing the event parameters: + - Severity modifier (INFORMATION/WARNING/ERROR/FATAL) + - Scope (SCOPE_PROC,SCOPE_SYS,SCOPE_CFG) + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the event injection + +################################################################################ +# Interface instance +EV = EvInterface() diff --git a/drivers/example/python/gcstime.py b/drivers/example/python/gcstime.py new file mode 100644 index 0000000..a0d8f0c --- /dev/null +++ b/drivers/example/python/gcstime.py @@ -0,0 +1,98 @@ +################################################################################### +## MODULE : gcstime +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: Time service interface of the driver connection layer +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +#******************************************************************************* +# SPELL imports +#******************************************************************************* +from spell.lib.exception import DriverException + +#******************************************************************************* +# Local imports +#******************************************************************************* + +#******************************************************************************* +# System imports +#******************************************************************************* +import datetime + +############################################################################### +# Module import definition + +__all__ = ['TIME'] + +############################################################################### +# Superclass +import spell.lib.adapter.gcstime.TimeInterface as superClass + +############################################################################### +# The time interface is in charge of managing GCS time. +############################################################################### +class TimeInterface(superClass): + + #========================================================================== + def __init__(self): + """ + Perform the initialization of time handling data here, after the + superclass initialization + """ + superClass.__init__(self) + # TODO Your initialization stuff here + + #========================================================================== + def setup(self, ctxConfig, drvConfig): + """ + Start the internal driver TIME mechanisms + + ctxConfig : provides the current context information (S/C name and others) + drvConfig : provides the configuration parameters for this driver according + to the xml config file. + """ + superClass.setup(self, ctxConfig, drvConfig) + # TODO Your startup stuff here + + #========================================================================== + def cleanup(self): + """ + Perform the cleanup of the internal driver TIME resources. + """ + superClass.cleanup(self) + # TODO Release resources and cleanup stuff here + + #========================================================================== + def _getUTC(self, config = {} ): + """ + Obtain the current UTC time according to the GCS time. If the present + example is not change, the interface provices the current system local + time. + + config: SPELL configuration dictionary. + """ + # Default implementation: get system local time + return datetime.datetime.utcnow() + +################################################################################ +# Interface handle +TIME = TimeInterface() diff --git a/drivers/example/python/modifiers.py b/drivers/example/python/modifiers.py new file mode 100644 index 0000000..5fc5fc6 --- /dev/null +++ b/drivers/example/python/modifiers.py @@ -0,0 +1,29 @@ +################################################################################### +## MODULE : modifiers +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: Driver-specific modifiers +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +#: Example modifier +ExampleModifier = 'ExampleModifier' +# MANDATORY: name and value strings shall match diff --git a/drivers/example/python/resources.py b/drivers/example/python/resources.py new file mode 100644 index 0000000..d3303e3 --- /dev/null +++ b/drivers/example/python/resources.py @@ -0,0 +1,183 @@ +################################################################################### +## MODULE : resources +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: Resource management interface of the driver connection layer +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +#******************************************************************************* +# SPELL imports +#******************************************************************************* +from spell.lib.exception import DriverException +from spell.lang.constants import * +from spell.lang.modifiers import * + +#******************************************************************************* +# Local imports +#******************************************************************************* + +#******************************************************************************* +# System imports +#******************************************************************************* + +############################################################################### +# Module import definition + +__all__ = ['RSC'] + +############################################################################### +# Superclass +import spell.lib.adapter.resources.ResourceInterface as superClass + +############################################################################### +# The resource management driver interface. This class is in charge of +# managing the underlying GCS resources like configuration parameters. +############################################################################### +class ResourceInterface(superClass): + + #========================================================================== + def __init__(self): + """ + Perform the initialization of resource handling data here, after the + superclass initialization + """ + superClass.__init__(self) + # TODO Your initialization stuff here + + #========================================================================== + def setup(self, ctxConfig, drvConfig): + """ + Start the internal driver resource mgmt mechanisms + + ctxConfig : provides the current context information (S/C name and others) + drvConfig : provides the configuration parameters for this driver according + to the xml config file. + """ + superClass.setup(self, ctxConfig, drvConfig) + # TODO Your startup stuff here + + #========================================================================== + def cleanup(self): + """ + Perform the cleanup of the internal driver mechanisms. + """ + superClass.cleanup(self) + # TODO Release resources and cleanup stuff here + + #========================================================================== + def _setResource(self, name, value, isLocal, config = {} ): + """ + Assign the value of one resource or configuration parameter in the GCS + + name: resource identifier + value: resource value + isLocal: decide whether to set local or global instance + config: configuration modifiers + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the resource assignment + + #========================================================================== + def _getResource(self, name, isLocal, config = {} ): + """ + Acquire the value of one resource or configuration parameter in the GCS + + name: resource identifier + isLocal: decide whether to get local or global instance + config: configuration modifiers + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the resource acquisition. Return the resource value: + # return theValue + + #========================================================================== + def _getResources(self, isLocal, config = {} ): + """ + Acquire the name-value map of all resources or configuration parameters + in the GCS + + isLocal: decide whether to get local or global instances + config: configuration modifiers + """ + raise DriverException("Service not available in this driver") + + #========================================================================== + def _getResourceStatus(self, name, config = {} ): + """ + Acquire the current status of one resource or configuration parameter + in the GCS + + name: resource identifier + config: configuration modifiers + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the resource acquisition. + # return theStatus + + #========================================================================== + def _isResourceOK(self, name, config = {} ): + """ + Check if the current value of one resource or configuration parameter + in the GCS is correct or incorrect + + name: resource identifier + config: configuration modifiers + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the resource acquisition. + # return True/False + + #========================================================================== + def _setLink(self, name, enable, config = {}): + """ + Enable or disable a GCS link (TM, TC or others) + + name: link identifier + enable: True/False, indicates if the link needs to be enabled or disabled + config: configuration modifiers + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the resource acquisition. + # return True/False depending on success + + #========================================================================== + def _checkLink(self, name): + """ + Check if a GCS link (TM, TC or others) is enabled or disabled + + name: link identifier + config: configuration modifiers + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the resource acquisition. + # return True/False if the link is enabled/disabled + + +################################################################################ +# Interface handle +RSC = ResourceInterface() diff --git a/drivers/example/python/task.py b/drivers/example/python/task.py new file mode 100644 index 0000000..9c12219 --- /dev/null +++ b/drivers/example/python/task.py @@ -0,0 +1,173 @@ +################################################################################### +## MODULE : task +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: Task management interface of the driver connection layer +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +#******************************************************************************* +# SPELL imports +#******************************************************************************* +from spell.lib.exception import DriverException +from spell.lang.constants import * +from spell.lang.modifiers import * + +#******************************************************************************* +# Local imports +#******************************************************************************* + +#******************************************************************************* +# System imports +#******************************************************************************* + +############################################################################### +# Module import definition + +__all__ = ['TASK'] + +############################################################################### +# Superclass +import spell.lib.adapter.task.TaskInterface as superClass + +############################################################################### +# Task management library interface. This class is in charge of +# managing the underlying system applications. +############################################################################### +class TaskInterface(superClass): + + #========================================================================== + def __init__(self): + """ + Perform the initialization of data here, after the + superclass initialization + """ + superClass.__init__(self) + # TODO Your initialization stuff here + + #========================================================================== + def setup(self, ctxConfig, drvConfig): + """ + Start the internal driver TASK mechanisms + + ctxConfig : provides the current context information (S/C name and others) + drvConfig : provides the configuration parameters for this driver according + to the xml config file. + """ + superClass.setup(self, ctxConfig, drvConfig) + # TODO Your startup stuff here + + #========================================================================== + def cleanup(self): + """ + Perform the cleanup of the internal driver TASK resources. + """ + superClass.cleanup(self) + # TODO Release resources and cleanup stuff here + + #========================================================================== + def _startTask(self, name, config = {} ): + """ + Invoked by the system in order to start a GCS task. + + name: string containing the task name + config: configuration dictionary with modifiers. + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the task start. Return True/False. + + #========================================================================== + def _stopTask(self, name, config = {} ): + """ + Invoked by the system in order to stop a GCS task. + + name: string containing the task name + config: configuration dictionary with modifiers. + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the task stop. Return True/False. + + #========================================================================== + def _checkTask(self, name, config = {} ): + """ + Invoked by the system in order to check the status of a GCS task. + + name: string containing the task name + config: configuration dictionary with modifiers. + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the task start. Return the status code. + + #========================================================================== + def _openDisplay(self, displayName, config = {} ): + """ + Invoked by the system in order to open a telemetry display on the GCS + + displayName: name or identifier of the display + config: configuration dictionary with modifiers. + + Relevant modifiers are: + + Host: the machine name where the display should be open. + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the operation. Return True on success. + + #========================================================================== + def _printDisplay(self, displayName, config = {} ): + """ + Invoked by the system in order to print a telemetry display from the GCS + + displayName: name or identifier of the display + config: configuration dictionary with modifiers. + + Relevant modifiers are: + + Printer: the printer name + Format: PS (postcript) or VECTOR (ASCII text, for alphanumeric displays only) + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the operation. Return True on success. + + #========================================================================== + def _closeDisplay(self, displayName, config = {} ): + """ + Invoked by the system in order to close a telemetry display on the GCS + + displayName: name or identifier of the display + config: configuration dictionary with modifiers. + + Relevant modifiers are: + + Host: the machine name where the display should be closed. + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the operation. Return True on success. + +################################################################################ +# Interface handle +TASK = TaskInterface() diff --git a/drivers/example/python/tc.py b/drivers/example/python/tc.py new file mode 100644 index 0000000..d452d2b --- /dev/null +++ b/drivers/example/python/tc.py @@ -0,0 +1,138 @@ +################################################################################### +## MODULE : tc +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: Telecommand interface of the driver connection layer +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +#******************************************************************************* +# SPELL imports +#******************************************************************************* +from spell.lib.exception import DriverException +from spell.lang.constants import * +from spell.lang.modifiers import * + +#******************************************************************************* +# Local imports +#******************************************************************************* + +#******************************************************************************* +# System imports +#******************************************************************************* + +############################################################################### +# Module import definition + +__all__ = ['TC'] + +############################################################################### +# Superclass +import spell.lib.adapter.tc.TcInterface as superClass + +############################################################################### +# Telecommand injection interface. +############################################################################### +class TcInterface(superClass): + + #========================================================================== + def __init__(self): + """ + Perform the initialization of data here, after the + superclass initialization + """ + superClass.__init__(self) + # TODO Your initialization stuff here + + #========================================================================== + def setup(self, ctxConfig, drvConfig): + """ + Start the internal driver TC mechanisms + + ctxConfig : provides the current context information (S/C name and others) + drvConfig : provides the configuration parameters for this driver according + to the xml config file. + """ + superClass.setup(self, ctxConfig, drvConfig) + # TODO Your startup stuff here + + #========================================================================== + def cleanup(self): + """ + Perform the cleanup of the internal driver TC resources. + """ + superClass.cleanup(self) + # TODO Release resources and cleanup stuff here + + #========================================================================== + def _createTcItem(self, mnenonic, description = "" ): + """ + Instantiate a telecommand (usually taking the information from GCS) + + The item shall be derived from TcItemClass class. + + If not overriden, the adapter class provides a generic TC item structure. + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the item creation. + # return theItem + + #========================================================================== + def _sendCommand(self, tcItem, config = {} ): + """ + Inject a TC item into the GCS. + + tcItem : TcItemClass instance with the command information. + config : configuration dictionary + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the command injection. Return True/False + + #========================================================================== + def _sendList(self, tcItemList, config = {} ): + """ + Inject a group of TC items into the GCS. + + tcItemList : list of TcItemClass instance with the command information. + config : configuration dictionary + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the command list injection. Return True/False + + #========================================================================== + def _sendBlock(self, tcItemList, config = {} ): + """ + Inject a block of TC items into the GCS. Blocked items are injected + and transmitted as a single TC frame. + + tcItemList : list of TcItemClass instance with the command information. + config : configuration dictionary + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the block injection. Return True/False + +################################################################################ +# Interface handle +TC = TcInterface() diff --git a/drivers/example/python/tm.py b/drivers/example/python/tm.py new file mode 100644 index 0000000..5e6cd83 --- /dev/null +++ b/drivers/example/python/tm.py @@ -0,0 +1,269 @@ +################################################################################### +## MODULE : tm +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: Telemetry interface of the driver connection layer +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +#******************************************************************************* +# SPELL imports +#******************************************************************************* +from spell.lib.exception import DriverException +from spell.lang.constants import * +from spell.lang.modifiers import * + +#******************************************************************************* +# Local imports +#******************************************************************************* + +#******************************************************************************* +# System imports +#******************************************************************************* +import sys,os + +############################################################################### +# Module import definition + +__all__ = ['TM'] + +############################################################################### +# Superclass +import spell.lib.adapter.tm.TmInterface as superClass + +############################################################################### +############################################################################### +class TmInterface( superClass ): + + #========================================================================== + def __init__(self): + """ + Perform the initialization of data here, after the + superclass initialization + """ + superClass.__init__(self) + # TODO Your initialization stuff here + + #========================================================================== + def setup(self, ctxConfig, drvConfig): + """ + Start the internal driver TM mechanisms + + ctxConfig : provides the current context information (S/C name and others) + drvConfig : provides the configuration parameters for this driver according + to the xml config file. + """ + superClass.setup(self, ctxConfig, drvConfig) + # TODO Your startup stuff here + + #========================================================================== + def cleanup(self): + """ + Perform the cleanup of the internal driver TM resources. + """ + superClass.cleanup(self) + # TODO Release resources and cleanup stuff here + + #=========================================================================== + def _createTmItem(self, mnemonic, description = ""): + """ + Instantiate a telemetry parameter (usually taking the information from GCS) + + The item shall be derived from TmItemClass class. + + If not overriden, the adapter class provides a generic TM item structure. + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the item creation. + # return theItem + + #========================================================================== + def _injectItem(self, tmItem, value, config = {} ): + """ + Inject a ground value for a TM parameter. + + tmItem : instance of TmItemClass with the parameter information + value : contains the required value + config : configuration dictionary with modifiers. + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the item injection. + # return True/False + + #========================================================================== + def _refreshItem(self, tmItem, config = {} ): + """ + Acquire the value for a TM parameter. + + tmItem : instance of TmItemClass with the parameter information + config : configuration dictionary with modifiers. + + Relevant modifiers are + + - Wait=True/False: when True, the system shall block the caller until + a new sample of the required parameter arrives to the GCS. If False, + the last recorded value of the parameter shall be returned immediately. + + - ValueFormat=RAW/ENG: if RAW is given, the raw or uncalibrated value + of the parameter shall be given. If ENG is used, the engineering or + calibrated value shall be returned. + + - Timeout=(TIME): maximum amount of time to wait for new samples, + before the parameter is declared as impossible to acquire. It only + makes sense when Wait=True. + + Returned value: a list with the value and True/False indicating the validity + of the parameter + """ + raise DriverException("Service not available in this driver") + # return [ theValue, theValidity ] + + #=========================================================================== + def _setLimit(self, param, limit, value, config ): + """ + Modify an Out Of Limits definition for a given telemetry parameter + + param: the telemetry parameter name + limit: the limit to be modified + value: the limit value + config: configuration dictionary with modifiers + + Relevant modifiers are: + + - Select=ACTIVE/ALL/: indicates which definitions should be affected + (all, only the active ones, or the one indicated by + the string) + + The limit to be modified may be one of the following: + + LoRed,LoYel,HiRed,HiYel: indicate the hard and soft limit values + + Nominal,Earning,Error,Ignore: the values are lists containing the values + assigned to each category, e.g. Nominal:['ValueA','ValueB'] + + Delta: set a step or spike limit + """ + raise DriverException("Service not available in this driver") + # return True/False + + #=========================================================================== + def _getLimit(self, param, limit, config ): + """ + Obtain an Out Of Limits definition for a given telemetry parameter + + param: the telemetry parameter name + limit: the limit to be modified + config: configuration dictionary with modifiers + + Relevant modifiers are: + + - Select=ACTIVE/ALL/: indicates which definitions should be considered + (all, only the active ones, or the one indicated by + the string) + + The limit to be obtained may be one of the following: + + LoRed,LoYel,HiRed,HiYel: indicate the hard and soft limit values + + Nominal,Earning,Error,Ignore: the values are lists containing the values + assigned to each category, e.g. Nominal:['ValueA','ValueB'] + + Delta: step or spike limit + """ + raise DriverException("Service not available in this driver") + # return the limit value or raise exception + + #=========================================================================== + def _getLimits(self, param, config ): + """ + Obtain an Out Of Limits definition for a given telemetry parameter + + param: the telemetry parameter name + config: configuration dictionary with modifiers + + Relevant modifiers are: + + - Select=ACTIVE/ALL/: indicates which definitions should be considered + (all, only the active ones, or the one indicated by + the string) + + The limit definition to be returned may be one of the following: + + {LoRed,LoYel,HiRed,HiYel}: indicate the hard and soft limit values + + {Nominal,Earning,Error,Ignore}: the values are lists containing the values + assigned to each category, e.g. Nominal:['ValueA','ValueB'] + + {Delta}: step or spike limit + """ + raise DriverException("Service not available in this driver") + # return the limit values or raise exception + + #=========================================================================== + def _setLimits(self, param, limits, config ): + """ + Modify an Out Of Limits definition for a given telemetry parameter + + param: the telemetry parameter name + limits: dictionary containing the limit parameters + config: configuration dictionary with modifiers + + Relevant modifiers are: + + - Select=ACTIVE/ALL/: indicates which definitions should be affected + (all, only the active ones, or the one indicated by + the string) + + Limit parameters dictionary may contain the following: + + LoRed,LoYel,HiRed,HiYel: indicate the hard and soft limit values + + Midpoint,Tolerance: indicate a middle limit point and a tolerance that is + used to calculate the upper and lower limits (M+T, M-T) + Hard and soft limits are considered equal. + + Nominal,Earning,Error,Ignore: the values are lists containing the values + assigned to each category, e.g. Nominal:['ValueA','ValueB'] + + Delta: set a step or spike limit + """ + raise DriverException("Service not available in this driver") + # return True/False + + #=========================================================================== + def _loadLimits(self, param, limits, config ): + """ + Load a set of limits definitions for a given parameter, from a given file. + + param: telemetry parameter name + limits: file with limit definitions + config: configuration parameters + + TBD + """ + raise DriverException("Service not available in this driver") + # return True/False + +################################################################################ +# Interface handle +TM = TmInterface() diff --git a/drivers/example/python/usr.py b/drivers/example/python/usr.py new file mode 100644 index 0000000..a5e3b23 --- /dev/null +++ b/drivers/example/python/usr.py @@ -0,0 +1,130 @@ +################################################################################### +## MODULE : usr +## DATE : Mar 18, 2011 +## PROJECT : SPELL +## DESCRIPTION: User management interface of the driver connection layer +## -------------------------------------------------------------------------------- +## +## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +## +## This file is part of SPELL. +## +## This component is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This software is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with SPELL. If not, see . +## +################################################################################### + +#******************************************************************************* +# SPELL imports +#******************************************************************************* +from spell.lib.exception import DriverException +from spell.lang.constants import * +from spell.lang.modifiers import * + +#******************************************************************************* +# Local imports +#******************************************************************************* + +#******************************************************************************* +# System imports +#******************************************************************************* + +############################################################################### +# Module import definition + +__all__ = ['USER'] + +############################################################################### +# Superclass +import spell.lib.adapter.usr.UserInterface as superClass + +############################################################################### +# User management interface. +############################################################################### +class UserInterface(superClass): + + #========================================================================== + def __init__(self): + """ + Perform the initialization of data here, after the + superclass initialization + """ + superClass.__init__(self) + # TODO Your initialization stuff here + + #========================================================================== + def setup(self, ctxConfig, drvConfig): + """ + Start the internal driver user mechanisms + + ctxConfig : provides the current context information (S/C name and others) + drvConfig : provides the configuration parameters for this driver according + to the xml config file. + """ + superClass.setup(self, ctxConfig, drvConfig) + # TODO Your startup stuff here + + #========================================================================== + def cleanup(self): + """ + Perform the cleanup of the internal driver user resources. + """ + superClass.cleanup(self) + # TODO Release resources and cleanup stuff here + + #========================================================================== + def _login(self, username, password, config = {} ): + """ + Login the given user in the GCS system. + + username: user name + password: the user password + config: configuration dictionary with modifiers. + + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the user login + # return True/False + + #========================================================================== + def _logout(self, username, config = {}): + """ + Logout the given user from the GCS system. + + username: user name + config: configuration dictionary with modifiers. + + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the user logout + # return True/False + + #========================================================================== + def _isLoggedIn(self, username, config = {}): + """ + Check if the given user is logged in the GCS system. + + username: user name + config: configuration dictionary with modifiers. + + """ + raise DriverException("Service not available in this driver") + # TODO if the service is supported remove the exception raise and + # implement the user login check + # return True/False + +############################################################################### +# Interface instance +USER = UserInterface() diff --git a/drivers/service/__init__.py b/drivers/service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/drivers/service/cif_client.py b/drivers/service/cif_client.py new file mode 100644 index 0000000..3a25d59 --- /dev/null +++ b/drivers/service/cif_client.py @@ -0,0 +1,47 @@ + +from spell.lib.registry import REGISTRY +from spell.utils.log import LOG + +debugOn = False +def debug(msg): + if debugOn: print(msg) + +# CIF interface +class CIF_Client(): + + def __init__(self): + self._ready = False + + def _setup(self, channel=None, options=None): + self._ready = True + LOG.setRedirectMethod(self.remoteLog) + + # Change CIF verbosity + def setVerbosity(self, *arg): + debug('CIF setVerbosity: %s' % repr(arg)) + + # Reset CIF verbosity + def resetVerbosity(self, *arg): + debug('CIF resetVerbosity: %s' % repr(arg)) + + # Write a message + def write(self, *arg): + debug('CIF write: %s' % repr(arg)) + + # Send a notification + def notify(self, notifyType = None, name = None, value = None, + status = None, reason = None, time = None, stack = None): + debug('CIF Notify: %s %s=%s (%s) %s' \ + % (notifyType, name, value, status, reason)) + + # Send a prompt + def prompt(self, *arg): + debug('CIF prompt: %s' % repr(arg)) + + def remoteLog(self, message, severity, level): + # return False: To prevent the LoggerClass from handling the logging itself (prevent double output in log file and console log) + # return True: Append log entry to configured log file and/or console output as configured + return True + +# init +REGISTRY['CIF'] = CIF_Client() diff --git a/drivers/service/driverserver.py b/drivers/service/driverserver.py new file mode 100644 index 0000000..fb57dd1 --- /dev/null +++ b/drivers/service/driverserver.py @@ -0,0 +1,130 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLExecutor_pb2_grpc import SPELLExecutorStub +from spell.stubs.SPELLDriver_pb2 import Interfaces +import spell.stubs.SPELLDriver_pb2 as SPELLDriver_pb2 +import spell.stubs.SPELLDriver_pb2_grpc as SPELLDriver_pb2_grpc + +from info_service import DriverService +from tm_service import SPELLDriverTMInterfaceServicer +from tc_service import SPELLDriverTCInterfaceServicer +from ev_service import SPELLDriverEVInterfaceServicer +from rsc_service import SPELLDriverRSCInterfaceServicer +from time_service import SPELLDriverTIMEInterfaceServicer +from task_service import SPELLDriverTASKInterfaceServicer +from user_service import SPELLDriverUSERInterfaceServicer +from rng_service import SPELLDriverRNGInterfaceServicer +from mem_service import SPELLDriverMEMInterfaceServicer +try: + from pcs_service import SPELLDriverPCSInterfaceServicer +except: + pass + +from spell.utils.grpc_utils import GRPCThreadPool +from spell.utils.log import LOG + +from concurrent import futures +from contextlib import closing +import grpc +from grpc import RpcError +import socket +import time +import signal + +KNOWN_INTERFACES = { + 'TM' : lambda server: (Interfaces.TM , SPELLDriverTMInterfaceServicer(server)), # @UndefinedVariable + 'TC' : lambda server: (Interfaces.TC , SPELLDriverTCInterfaceServicer(server)), # @UndefinedVariable + 'EV' : lambda server: (Interfaces.EV , SPELLDriverEVInterfaceServicer(server)), # @UndefinedVariable + 'RSC' : lambda server: (Interfaces.RSC , SPELLDriverRSCInterfaceServicer(server)), # @UndefinedVariable + 'TIME' : lambda server: (Interfaces.TIME , SPELLDriverTIMEInterfaceServicer(server)), # @UndefinedVariable + 'TASK' : lambda server: (Interfaces.TASK , SPELLDriverTASKInterfaceServicer(server)), # @UndefinedVariable + 'USER' : lambda server: (Interfaces.USER , SPELLDriverUSERInterfaceServicer(server)), # @UndefinedVariable +# 'CONFIG': lambda server: (Interfaces.CONFIG , SPELLDriverCONFIGInterfaceServicer(server)), # @UndefinedVariable + 'RNG' : lambda server: (Interfaces.RNG , SPELLDriverRNGInterfaceServicer(server)), # @UndefinedVariable + 'MEM' : lambda server: (Interfaces.MEM , SPELLDriverMEMInterfaceServicer(server)), # @UndefinedVariable + 'PCS' : lambda server: (Interfaces.PCS , SPELLDriverPCSInterfaceServicer(server)) # @UndefinedVariable + } + +# Global for signal handling +server = None + +def signal_handler(signal, frame): + global server + log('signal received: %s' % str(signal)) + if server != None: + server.stop(0) + server = None + REGISTRY['EXEC']._close() + +def log(msg): + LOG('[driverserver]: ' + msg) + +def find_free_port(): + with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: + s.bind(('', 0)) + return s.getsockname()[1] + +def serve(executorHost = None, executorPort = None): + global server + server = grpc.server(GRPCThreadPool('DRIVER', max_workers=50)) + port = find_free_port() + service = DriverService(port) + SPELLDriver_pb2_grpc.add_SPELLDriverInterfaceServicer_to_server(service, server) + endpoint = '[::]:' + str(port) + port = server.add_insecure_port(endpoint) + service._setPort(port) + + # install signal handler + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + log('starting gRPC server at ' + endpoint) + server.start() + + if executorHost and executorPort: + log('connecting to SPELL Executor') + + driverName = REGISTRY['CTX'].getDriver() + driverLogin = SPELLDriver_pb2.DriverInfo(driverName = driverName, + host =socket.getfqdn(), + port = port) + + driverInterfaces = REGISTRY['CONFIG'].getDriverConfig().getInterfaces() + log('registering the following interfaces for driver %s:' % driverName) + log(driverInterfaces) + for interface in driverInterfaces.split(','): + interface = interface.strip() + if interface in list(KNOWN_INTERFACES.keys()): + try: + log('creating driver interface %s' % interface) + ifcId, ifcService = KNOWN_INTERFACES[interface](server) + if ifcService: + driverLogin.interfaces.append(ifcId) + log('created driver interface %s for id %s ' \ + % (interface, ifcId)) + except: + log('could not create interface service for %s!' % interface) + import traceback + traceback.print_exc() + del traceback + + channel = grpc.insecure_channel('%s:%d' % (executorHost, executorPort)) + stub = SPELLExecutorStub(channel) + try: + response = stub.DriverLogin(driverLogin) + REGISTRY['CIF']._setup(channel, response) + REGISTRY['EXEC']._setup(channel, response) + log('login to SPELL Executor succeeded') + except RpcError as e: + log('login to SPELL Executor failed with error code %s' % e.code()) + log(e) + server.stop(0) + REGISTRY['EXEC']._close() + return + else: + REGISTRY['CIF']._setup() + REGISTRY['EXEC']._setup() + + log('started to serve requests, hit ctrl-c to stop') + while server != None: + time.sleep(1) diff --git a/drivers/service/ev_service.py b/drivers/service/ev_service.py new file mode 100644 index 0000000..bbcea53 --- /dev/null +++ b/drivers/service/ev_service.py @@ -0,0 +1,37 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_EVServicer,\ + add_SPELLDriverInterface_EVServicer_to_server +from spell.utils.grpc_utils import UnpackValue, LogFunctionInput + +from google.protobuf.empty_pb2 import Empty + +class SPELLDriverEVInterfaceServicer(SPELLDriverInterface_EVServicer): + + def __init__(self, server): + add_SPELLDriverInterface_EVServicer_to_server(self, server) + + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['EV'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + def Cleanup(self, request, context): + REGISTRY['EV'].cleanup() + return Empty() + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + return Empty() + + def RaiseEvent(self, request, context): + msg = str(request.message) + config = UnpackValue(request.config) + + REGISTRY['EV']._raiseEvent(msg, config) + + return Empty() diff --git a/drivers/service/exec_client.py b/drivers/service/exec_client.py new file mode 100644 index 0000000..4486f95 --- /dev/null +++ b/drivers/service/exec_client.py @@ -0,0 +1,130 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLExecutor_pb2_grpc import SPELLExecutorStub +from spell.utils.timing import RepeatingThread + +from google.protobuf.empty_pb2 import Empty +from grpc import RpcError +import os +from spell.config.reader import Config + +debugOn = False +def debug(msg): + if debugOn: print(msg) + +# EXEC interface +class EXEC_Client(SPELLExecutorStub): + + def __init__(self): + self._ready = False + self._ping = None + self._retryCount = 0 + self._spellAccess = False + + def _setup(self, channel=None, options=None): + self._ready = True + if not channel: + return + SPELLExecutorStub.__init__(self, channel) + self.createPingThread() + + def _close(self): + if self._ping is None: + return + self._ping.cancel() + self._ping = None + + def createPingThread(self): + self._ping = RepeatingThread(REGISTRY['CONFIG'].getDriverConfig().getGRPCPingTime(), + self.checkConnectionAlive) + self._ping.start() + + def checkConnectionAlive(self): + try: + self.Ping(Empty(), + timeout = REGISTRY['CONFIG'].getDriverConfig().getGRPCTimeout()) + self._retryCount = 0 + debug('[DRIVER] SPELL Executor is alive!') + except RpcError as e: + import traceback + excMsg = traceback.format_exception_only(RpcError, e) + self._retryCount += 1 + if self._retryCount <= REGISTRY['CONFIG'].getDriverConfig().getGRPCRetry(): + debug('[DRIVER] SPELL Executor does not react anymore! Retry %s/%s' \ + % (self._retryCount, REGISTRY['CONFIG'].getDriverConfig().getGRPCRetry())) + debug(str(excMsg)) + else: + debug('[DRIVER] SPELL Executor stopped reacting! Exiting SPELL Driver') + os._exit(0) + del traceback + + # Obtain executor status + def getStatus(self, *arg): + debug('EXEC: getStatus: %s' % repr(arg)) + + # Obtain execution environment + def getEnvironment(self, *arg): + debug('EXEC: getEnvironment: %s' % repr(arg)) + + # Set the language lock + def processLock(self, *arg): + debug('EXEC: processLock: %s' % repr(arg)) + + # Unset the language lock + def processUnlock(self, *arg): + debug('EXEC: processUnlock: %s' % repr(arg)) + + # Start waiting process + def startWait(self, *arg): + debug('EXEC: startWait: %s' % repr(arg)) + + # End waiting process + def finishWait(self, *arg): + debug('EXEC: finishWait: %s' % repr(arg)) + + # Start prompt + def startPrompt(self, *arg): + debug('EXEC: startPrompt: %s' % repr(arg)) + + # End prompt + def endPrompt(self, *arg): + debug('EXEC: endPrompt: %s' % repr(arg)) + + # Wait for event + def wait(self, *arg): + debug('EXEC: wait: %s' % repr(arg)) + + # Open child procedure + def openSubProcedure(self, *arg): + debug('EXEC: openSubProcedure: %s' % repr(arg)) + + # Close child procedure + def closeSubProcedure(self, *arg): + debug('EXEC: closeSubProcedure: %s' % repr(arg)) + + # Kill child procedure + def killSubProcedure(self, *arg): + debug('EXEC: killSubProcedure: %s' % repr(arg)) + + # Get child procedure status + def getChildStatus(self, *arg): + debug('EXEC: getChildStatus: %s' % repr(arg)) + + # Get child procedure error info + def getChildError(self, *arg): + debug('EXEC: getChildError: %s' % repr(arg)) + + # Is subprocedure in error + def isChildError(self, *arg): + debug('EXEC: isChildError: %s' % repr(arg)) + + # Is subprocedure finished + def isChildFinished(self, *arg): + debug('EXEC: isChildFinished: %s' % repr(arg)) + + # Abort execution + def abort(self, *arg): + debug('EXEC: abort: %s' % repr(arg)) + +# init +REGISTRY['EXEC'] = EXEC_Client() diff --git a/drivers/service/info_service.py b/drivers/service/info_service.py new file mode 100644 index 0000000..d725c59 --- /dev/null +++ b/drivers/service/info_service.py @@ -0,0 +1,35 @@ + +from spell.lib.registry import REGISTRY +import spell.stubs.SPELLDriver_pb2 as SPELLDriver_pb2 +import spell.stubs.SPELLDriver_pb2_grpc as SPELLDriver_pb2_grpc + +from google.protobuf.empty_pb2 import Empty +import socket +from threading import Timer + +class DriverService(SPELLDriver_pb2_grpc.SPELLDriverInterfaceServicer): + + def __init__(self, port): + self.driverName = REGISTRY['CTX'].getDriver() + self.host = socket.getfqdn() + self.port = port + + def _setPort(self, port): + self.port = port + + def GetDriverInfo(self, request, context): + return SPELLDriver_pb2.DriverInfo(driverName = self.driverName, + host = self.host, port = self.port) + + def Cleanup(self, request, context): + return request + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + # TODO: test + def doExit(): + exit(0) + exitTimer = Timer(2,doExit,[]).start() + return Empty() diff --git a/drivers/service/mem_service.py b/drivers/service/mem_service.py new file mode 100644 index 0000000..6cd15bb --- /dev/null +++ b/drivers/service/mem_service.py @@ -0,0 +1,103 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_MEMServicer,\ + add_SPELLDriverInterface_MEMServicer_to_server +from spell.utils.grpc_utils import UnpackValue, LogFunctionInput, PackValue + +from google.protobuf.empty_pb2 import Empty +from google.protobuf.wrappers_pb2 import BoolValue + +class SPELLDriverMEMInterfaceServicer(SPELLDriverInterface_MEMServicer): + + def __init__(self, server): + add_SPELLDriverInterface_MEMServicer_to_server(self, server) + + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['MEM'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + def Cleanup(self, request, context): + REGISTRY['MEM'].cleanup() + return Empty() + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + return Empty() + + def GenerateReport(self, request, context): + image = request.image + report_type = request.report_type + begin = request.begin + end = request.end + source = request.source + config = UnpackValue(request.config) + + result = REGISTRY['MEM']._generateReport(image, report_type, begin, + end, source, config) + + return BoolValue(value = result) + + def CompareImages(self, request, context): + image1 = request.image1 + image2 = request.image2 + report_type = request.report_type + begin = request.begin + end = request.end + source = request.source + config = UnpackValue(request.config) + + result = REGISTRY['MEM']._compareImages(image1, image2, report_type, + begin, end, source, config) + + return BoolValue(value = result) + + + def CreateGoldenImage(self, request, context): + scp = request.scp + filename = request.filename + config = UnpackValue(request.config) + + result = REGISTRY['MEM']._createGoldenImage(self, scp, filename, config) + + return BoolValue(value = result) + + + def MemoryLookup(self, request, context): + name = request.name + address = request.address + image = request.image + report_type = request.report_type + source = request.source + config = UnpackValue(request.config) + + result = REGISTRY['MEM']._memoryLookup(name, address, image, + report_type, source, config) + + return PackValue(result) + + + def DataObjectLookup(self, request, context): + name = request.name + ltype = request.type + config = UnpackValue(request.config) + + result = REGISTRY['MEM']._dataObjectLookup(name, ltype, config) + + return PackValue(result) + + + def DataItemLookup(self, request, context): + name = request.name + ltype = request.type + source = request.source + valformat = request.valformat + config = UnpackValue(request.config) + + result = REGISTRY['MEM']._dataItemLookup(name, ltype, source, valformat, config) + + return PackValue(result) diff --git a/drivers/service/pcs_service.py b/drivers/service/pcs_service.py new file mode 100644 index 0000000..7b14e4b --- /dev/null +++ b/drivers/service/pcs_service.py @@ -0,0 +1,166 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_PCSServicer,\ + add_SPELLDriverInterface_PCSServicer_to_server +from spell.stubs.SPELLDriver_pb2 import Names, PtcResult +from spell.utils.grpc_utils import UnpackValue, LogFunctionInput, PackValue + +from google.protobuf.empty_pb2 import Empty +from google.protobuf.wrappers_pb2 import BoolValue, StringValue +from spell.lang.functions import PCS_GetStatus + +class SPELLDriverPCSInterfaceServicer(SPELLDriverInterface_PCSServicer): + + def __init__(self, server): + self._ptcItemRegistry = {} + add_SPELLDriverInterface_PCSServicer_to_server(self, server) + + #========================================================================== + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['PCS'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + #========================================================================== + def Cleanup(self, request, context): + REGISTRY['PCS'].cleanup() + return Empty() + + #========================================================================== + def Ping(self, request, context): + return Empty() + + #========================================================================== + def Close(self, request, context): + return Empty() + + #========================================================================== + + def CreatePtcItem(self, request, context): + ptcId = request.id + if not ptcId or ptcId not in list(self._ptcItemRegistry.keys()): + ptcItem = REGISTRY['PCS']._createPtcItem(str(request.mnemonic), + str(request.description)) + ptcId = request.mnemonic + self._ptcItemRegistry[str(ptcId)] = ptcItem + request.id = ptcId + + return request + + #========================================================================== + def _findItem(self, request): + # RSA: do we need all these str conversions? + # strings coming from grpc are all in unicode. + # str and unicode have different hashes even if they got the same content. + # That's why we have to convert all values to str when using dicts. + if str(request.item.id) in self._ptcItemRegistry: + ptcItem = self._ptcItemRegistry[str(request.item.id)] + else: + ptcItem = REGISTRY['PCS']._createPtcItem(str(request.item.mnemonic), + str(request.item.description)) + request.item.id = str(request.item.mnemonic) + + return ptcItem + + #========================================================================== + def PCS_GetStatus(self, request, context): + answer = REGISTRY['PCS']._PCS_GetStatus(UnpackValue(request)) + + return PackValue(answer) + + #========================================================================== + def PCS_IsArqEnabled(self, request, context): + answer = REGISTRY['PCS']._PCS_IsArqEnabled(UnpackValue(request)) + + return answer.value + + #========================================================================== + def PCS_IsVerifyModeEnabled(self, request, context): + answer = REGISTRY['PCS']._PCS_IsVerifyModeEnabled(UnpackValue(request)) + + return answer.value + + #========================================================================== + def PCS_ReadyToCommand(self, request, context): + answer = REGISTRY['PCS']._PCS_ReadyToCommand(UnpackValue(request)) + + return answer.value + + #========================================================================== + def PCS_AbortPtc(self, request, context): + answer = REGISTRY['PCS']._PCS_AbortPtc(UnpackValue(request)) + + return answer.value + + #========================================================================== + def _extractPtc(self, request): + ptcItem = self._ptcItemRegistry[str(request.command.id)] + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + args = UnpackValue(request.args) + self._addArgsToPTC(ptcItem, args, config) + + return ptcItem + + #========================================================================== + def _addArgsToPTC(self, ptcItem, args, config): + ptcItem.clear() + # RSA: Is this correct? + for arg in args: + ptcItem[arg[0]] = arg[1:] + ptcItem.configure(config) + + #========================================================================== + def _createPtcResultAnswer(self,result): + answer = PtcResult(code = result['code'], + success = result['success'], + stage = result['stage'], + data = result['data'], + error = result['error']) + + return answer + + #========================================================================== + def PCS_Control(self, request, context): + ptcItem = self._extractPtc(request) + + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + result = REGISTRY['PCS']._PCS_Control(ptcItem, config) + + return self._createPtcResultAnswer(result) + #========================================================================== + def SendPtcCommand(self, request, context): + ptcItem = self._extractPtc(request) + + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + result = REGISTRY['PCS']._sendPtcCommand(ptcItem, config) + + return self._createPtcResultAnswer(result) + + #========================================================================== + def SendPtcList(self, request, context): + cmdList = [] + for cmd in request.commands: + cmdList += [self._extractPtc(cmd)] + + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + result = REGISTRY['PCS']._sendPtcList(cmdList, config) + + return self._createPtcResultAnswer(result) diff --git a/drivers/service/rng_service.py b/drivers/service/rng_service.py new file mode 100644 index 0000000..96f1246 --- /dev/null +++ b/drivers/service/rng_service.py @@ -0,0 +1,128 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_RNGServicer,\ + add_SPELLDriverInterface_RNGServicer_to_server +from spell.stubs.SPELLDriver_pb2 import Names +from spell.utils.grpc_utils import UnpackValue, LogFunctionInput + +from google.protobuf.empty_pb2 import Empty +from google.protobuf.wrappers_pb2 import BoolValue, StringValue + +class SPELLDriverRNGInterfaceServicer(SPELLDriverInterface_RNGServicer): + + def __init__(self, server): + add_SPELLDriverInterface_RNGServicer_to_server(self, server) + + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['RNG'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + def Cleanup(self, request, context): + REGISTRY['RNG'].cleanup() + return Empty() + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + return Empty() + + def EnableRanging(self, request, context): + config = UnpackValue(request.config) + + result = REGISTRY['RNG']._enableRanging(config) + + return BoolValue(value = result) + + def DisableRanging(self, request, context): + config = UnpackValue(request.config) + + result = REGISTRY['RNG']._disableRanging(config) + + return BoolValue(value = result) + + def AbortRanging(self, request, context): + config = UnpackValue(request.config) + + result = REGISTRY['RNG']._abortRanging(config) + + return BoolValue(value = result) + + + def StartRanging(self, request, context): + config = UnpackValue(request.config) + bbe = request.bbe + antenna = request.antenna + + result = REGISTRY['RNG']._startRanging(bbe, antenna, config) + + return BoolValue(value = result) + + + def StartCalibration(self, request, context): + config = UnpackValue(request.config) + bbe = request.bbe + antenna = request.antenna + + result = REGISTRY['RNG']._startCalibration(bbe, antenna, config) + + return BoolValue(value = result) + + def GetBasebandConfig(self, request, context): + config = UnpackValue(request.config) + bbe = request.bbe + param = request.param + + result = REGISTRY['RNG']._getBasebandConfig(bbe, param, config) + + request.value = str(result) + + return request + + def SetBasebandConfig(self, request, context): + config = UnpackValue(request.config) + bbe = request.bbe + param = request.param + value = request.value + + result = REGISTRY['RNG']._setBasebandConfig(bbe, param, value, config) + + return BoolValue(value = result) + + def GetAntennaNames(self, request, context): + config = UnpackValue(request) + + result = REGISTRY['RNG']._getAntennaNames(config) + + return Names(names = result) + + def GetRangingPaths(self, request, context): + config = UnpackValue(request) + + result = REGISTRY['RNG']._getRangingPaths(config) + + return Names(names = result) + + def GetBasebandNames(self, request, context): + config = UnpackValue(request) + + result = REGISTRY['RNG']._getBasebandNames(config) + + return Names(names = result) + + def GetRangingStatus(self, request, context): + config = UnpackValue(request) + + result = REGISTRY['RNG']._getRangingStatus(config) + + return StringValue(value = result) + + def UpdateCortexConf(self, request, context): + config = UnpackValue(request) + + result = REGISTRY['RNG']._updateCortexConf(config) + + return BoolValue(value = result) diff --git a/drivers/service/rsc_service.py b/drivers/service/rsc_service.py new file mode 100644 index 0000000..4e139c7 --- /dev/null +++ b/drivers/service/rsc_service.py @@ -0,0 +1,76 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_RSCServicer,\ + add_SPELLDriverInterface_RSCServicer_to_server +from spell.stubs.SPELLDriver_pb2 import ResourceRequest +from spell.utils.grpc_utils import UnpackValue, PackValue, unicode2string,\ + LogFunctionInput + +from google.protobuf.empty_pb2 import Empty +from google.protobuf.wrappers_pb2 import BoolValue + +class SPELLDriverRSCInterfaceServicer(SPELLDriverInterface_RSCServicer): + + def __init__(self, server): + self._tmItemRegistry = {} + add_SPELLDriverInterface_RSCServicer_to_server(self, server) + + def SetLink(self, request, context): + REGISTRY['RSC'].setLink(str(request.name), unicode2string(request.status), + UnpackValue(request.config)) + return BoolValue(value = True) + + def CheckLink(self, request, context): + result = REGISTRY['RSC'].checkLink(str(request.name)) + + return BoolValue(value = result) + + def SetResource(self, request, context): + result = REGISTRY['RSC']._setResource(str(request.name), + UnpackValue(request.value), + UnpackValue(request.config)) + + return BoolValue(value = result) + + def GetResource(self, request, context): + result = REGISTRY['RSC']._getResource(str(request.name), + UnpackValue(request.config)) + + return ResourceRequest(value = PackValue(result)) + + def GetResources(self, request, context): + # FIXME: What about isLocal? + result = REGISTRY['RSC']._getResources(UnpackValue(request.config)) + + return ResourceRequest(value = PackValue(result)) + + def GetResourceStatus(self, request, context): + result = REGISTRY['RSC']._getResourceStatus(str(request.name), + UnpackValue(request.config)) + + return ResourceRequest(value = PackValue(result)) + + def IsResourceOK(self, request, context): + result = REGISTRY['RSC']._isResourceOK(str(request.name), + UnpackValue(request.config)) + + return BoolValue(value = result) + + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['RSC'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + def Cleanup(self, request, context): + REGISTRY['RSC'].cleanup() + + return Empty() + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + # TODO + return Empty() diff --git a/drivers/service/task_service.py b/drivers/service/task_service.py new file mode 100644 index 0000000..6dea479 --- /dev/null +++ b/drivers/service/task_service.py @@ -0,0 +1,74 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_TASKServicer,\ + add_SPELLDriverInterface_TASKServicer_to_server +from spell.utils.grpc_utils import UnpackValue, LogFunctionInput + +from google.protobuf.empty_pb2 import Empty +from google.protobuf.wrappers_pb2 import BoolValue + +class SPELLDriverTASKInterfaceServicer(SPELLDriverInterface_TASKServicer): + + def __init__(self, server): + add_SPELLDriverInterface_TASKServicer_to_server(self, server) + + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['TASK'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + def Cleanup(self, request, context): + REGISTRY['TASK'].cleanup() + + return Empty() + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + return Empty() + + def StartTask(self, request, context): + name = request.name + args = UnpackValue(request.args) + config = UnpackValue(request.config) + answer = REGISTRY['TASK']._startTask(name, args, config) + + return BoolValue(value = answer) + + def StopTask(self, request, context): + name = request.name + config = UnpackValue(request.config) + answer = REGISTRY['TASK']._stopTask(name, config) + + return BoolValue(value = answer) + + def CheckTask(self, request, context): + name = request.name + config = UnpackValue(request.config) + answer = REGISTRY['TASK']._checkTask(name, config) + + return BoolValue(value = answer) + + def OpenDisplay(self, request, context): + name = request.name + config = UnpackValue(request.config) + REGISTRY['TASK']._openDisplay(name, config) + + return Empty() + + def CloseDisplay(self, request, context): + name = request.name + config = UnpackValue(request.config) + REGISTRY['TASK']._closeDisplay(name, config) + + return Empty() + + def PrintDisplay(self, request, context): + name = request.name + config = UnpackValue(request.config) + REGISTRY['TASK']._printDisplay(name, config) + + return Empty() diff --git a/drivers/service/tc_service.py b/drivers/service/tc_service.py new file mode 100644 index 0000000..2b06272 --- /dev/null +++ b/drivers/service/tc_service.py @@ -0,0 +1,102 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_TCServicer,\ + add_SPELLDriverInterface_TCServicer_to_server +from spell.utils.grpc_utils import UnpackValue, LogFunctionInput + +from google.protobuf.empty_pb2 import Empty +from google.protobuf.wrappers_pb2 import BoolValue + +class SPELLDriverTCInterfaceServicer(SPELLDriverInterface_TCServicer): + + def __init__(self, server): + self._tcItemRegistry = {} + add_SPELLDriverInterface_TCServicer_to_server(self, server) + + def CreateTcItem(self, request, context): + tcId = request.id + if not tcId or tcId not in list(self._tcItemRegistry.keys()): + tcItem = REGISTRY['TC']._createTcItem(str(request.mnemonic), + str(request.description)) + tcId = id(tcItem) + self._tcItemRegistry[str(tcId)] = tcItem + request.id = tcId + + return request + + def _extractCommand(self, request): + tcItem = self._tcItemRegistry[str(request.command.id)] + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + args = UnpackValue(request.args) + self._addArgsToTC(tcItem, args, config) + + return tcItem + + def _addArgsToTC(self, tcItem, args, config): + tcItem.clear() + # RSA: Is this correct? + for arg in args: + tcItem[arg[0]] = arg[1:] + tcItem.configure(config) + + def SendCommand(self, request, context): + tcItem = self._extractCommand(request) + + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + result = REGISTRY['TC']._sendCommand(tcItem, config) + + return BoolValue(value = result) + + def SendList(self, request, context): + cmdList = [] + for cmd in request.commands: + cmdList += [self._extractCommand(cmd)] + + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + result = REGISTRY['TC']._sendList(cmdList, config) + + return BoolValue(value = result) + + def SendBlock(self, request, context): + cmdList = [] + for cmd in request.commands: + cmdList += [self._extractCommand(cmd)] + + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + result = REGISTRY['TC']._sendBlock(cmdList, config) + + return BoolValue(value = result) + + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['TC'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + def Cleanup(self, request, context): + REGISTRY['TC'].cleanup() + return Empty() + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + # TODO + return Empty() diff --git a/drivers/service/time_service.py b/drivers/service/time_service.py new file mode 100644 index 0000000..78648ef --- /dev/null +++ b/drivers/service/time_service.py @@ -0,0 +1,37 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_TIMEServicer,\ + add_SPELLDriverInterface_TIMEServicer_to_server +from spell.stubs.SPELLDriver_pb2 import Time +from spell.utils.grpc_utils import UnpackValue, LogFunctionInput + +from google.protobuf.empty_pb2 import Empty + +class SPELLDriverTIMEInterfaceServicer(SPELLDriverInterface_TIMEServicer): + + def __init__(self, server): + add_SPELLDriverInterface_TIMEServicer_to_server(self, server) + + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['TIME'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + def Cleanup(self, request, context): + REGISTRY['TIME'].cleanup() + + return Empty() + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + return Empty() + + def GetUTC(self, request, context): + config = UnpackValue(request) + answer = REGISTRY['TIME']._getUTC(config) + + return Time(timeMsg = str(answer)) diff --git a/drivers/service/tm_service.py b/drivers/service/tm_service.py new file mode 100644 index 0000000..747ad62 --- /dev/null +++ b/drivers/service/tm_service.py @@ -0,0 +1,142 @@ + +from spell.lib.registry import REGISTRY +from spell.stubs.SPELLDriver_pb2 import LookupAnswer, LimitSet +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_TMServicer,\ + add_SPELLDriverInterface_TMServicer_to_server +from spell.utils.grpc_utils import UnpackValue, PackValue, LogFunctionInput + +from google.protobuf.empty_pb2 import Empty +from google.protobuf.wrappers_pb2 import BoolValue + +class SPELLDriverTMInterfaceServicer(SPELLDriverInterface_TMServicer): + + def __init__(self, server): + self._tmItemRegistry = {} + add_SPELLDriverInterface_TMServicer_to_server(self, server) + + def CreateTmItem(self, request, context): + tmId = request.id + if not tmId or tmId not in list(self._tmItemRegistry.keys()): + tmItem = REGISTRY['TM']._createTmItem(str(request.mnemonic), + str(request.description)) + tmId = request.mnemonic + self._tmItemRegistry[str(tmId)] = tmItem + request.id = tmId + + return request + + def _findItem(self, request): + # RSA: do we need all these str conversions? + if str(request.item.id) in self._tmItemRegistry: + tmItem = self._tmItemRegistry[str(request.item.id)] + else: + tmItem = REGISTRY['TM']._createTmItem(str(request.item.mnemonic), + str(request.item.description)) + request.item.id = str(request.item.mnemonic) + + return tmItem + + def RefreshItem(self, request, context): + tmItem = self._findItem(request) + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + _, validity = REGISTRY['TM']._refreshItem(tmItem, config) + + timestamp = str(tmItem.time()) + request.engValue.CopyFrom(PackValue(tmItem.eng())) + request.rawValue.CopyFrom(PackValue(tmItem.raw())) + + if timestamp and tmItem.time() is not None: + request.timestamp = timestamp + + request.validity = bool(validity) + + return request + + def DatabaseLookup(self, request, context): + answer = REGISTRY['TM']._databaseLookup(str(request.name), + str(request.type), + str(request.source)) + + return LookupAnswer(lookup = PackValue(answer)) + + def GetLimits(self, request, context): + tmItem = self._findItem(request) + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + answer = REGISTRY['TM']._getLimits(tmItem,config) + + return LimitSet(limitset = PackValue(answer)) + + def SetLimits(self, request, context): + tmItem = self._findItem(request) + if request.HasField('set'): + limitset = UnpackValue(request.set.limitset) + else: + limitset = {} + + answer = REGISTRY['TM']._setLimits(tmItem,limitset) + if answer is None: + answer = True + + return BoolValue(value = answer) + + def IsAlarmed(self, request, context): + tmItem = self._findItem(request) + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + + answer = REGISTRY['TM']._isAlarmed(tmItem, config) + if answer is None: + answer = False + + return BoolValue(value = answer) + + def InjectItem(self, request, context): + tmItem = self._findItem(request) + if request.HasField('config'): + config = UnpackValue(request.config) + else: + config = {} + value = UnpackValue(request.engValue) + + answer = REGISTRY['TM']._injectItem(tmItem, value, config) + + if answer is None: + answer = False + + return BoolValue(value = answer) + + def RestoreNormalLimits(self, request, context): + answer = REGISTRY['TM']._restoreNormalLimits(UnpackValue(request)) + + if answer is None: + answer = False + + return BoolValue(value = answer) + + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['TM'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + def Cleanup(self, request, context): + REGISTRY['TM'].cleanup() + + return Empty() + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + # TODO + return Empty() diff --git a/drivers/service/user_service.py b/drivers/service/user_service.py new file mode 100644 index 0000000..8d0338b --- /dev/null +++ b/drivers/service/user_service.py @@ -0,0 +1,57 @@ + +from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_USERServicer,\ + add_SPELLDriverInterface_USERServicer_to_server +from spell.lib.registry import REGISTRY +from spell.utils.grpc_utils import UnpackValue, LogFunctionInput + +from google.protobuf.empty_pb2 import Empty +from google.protobuf.wrappers_pb2 import BoolValue + +class SPELLDriverUSERInterfaceServicer(SPELLDriverInterface_USERServicer): + + def __init__(self, server): + add_SPELLDriverInterface_USERServicer_to_server(self, server) + + def Setup(self, request, context): + from spell.lib.drivermgr import DriverManager + mgr = DriverManager.instance() + REGISTRY['USER'].setup(mgr.contextConfig,mgr.driverConfig) + del DriverManager + return request + + def Cleanup(self, request, context): + REGISTRY['USER'].cleanup() + + return Empty() + + def Ping(self, request, context): + return Empty() + + def Close(self, request, context): + return Empty() + + def Login(self, request, context): + name = request.username + pwd = request.password + config = UnpackValue(request.config) + + result = REGISTRY['USER']._login(name, pwd, config) + + return BoolValue(value = result) + + def Logout(self, request, context): + name = request.username + config = UnpackValue(request.config) + + result = REGISTRY['USER']._logout(name, config) + + return BoolValue(value = result) + + + def IsLoggedIn(self, request, context): + name = request.username + config = UnpackValue(request.config) + + result = REGISTRY['USER']._isLoggedIn(name, config) + + return BoolValue(value = result) diff --git a/include/SPELL_CFG/SPELLbrowsableLibMode.H b/include/SPELL_CFG/SPELLbrowsableLibMode.H index f85ca7f..49e2d19 100644 --- a/include/SPELL_CFG/SPELLbrowsableLibMode.H +++ b/include/SPELL_CFG/SPELLbrowsableLibMode.H @@ -5,7 +5,7 @@ // DESCRIPTION: Browsable modes // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CFG/SPELLconfiguration.H b/include/SPELL_CFG/SPELLconfiguration.H index b758501..1f51510 100644 --- a/include/SPELL_CFG/SPELLconfiguration.H +++ b/include/SPELL_CFG/SPELLconfiguration.H @@ -5,7 +5,7 @@ // DESCRIPTION: Wrapper to configuration reader instance // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CFG/SPELLcontextConfig.H b/include/SPELL_CFG/SPELLcontextConfig.H index 7d8500f..0cf6571 100644 --- a/include/SPELL_CFG/SPELLcontextConfig.H +++ b/include/SPELL_CFG/SPELLcontextConfig.H @@ -5,7 +5,7 @@ // DESCRIPTION: Wrapper for context configuration // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -76,6 +76,7 @@ public: //-------------------------------------------------------------------- // STATIC //////////////////////////////////////////////////////////////// static const std::string ExecutorProgram; + static const std::string ServiceProgram; static const std::string ExecutorStartTimeout; static const std::string ExecutorLoginTimeout; static const std::string UseDriverTime; @@ -137,6 +138,12 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// std::string getProcPath() const { return m_procPath; }; + /** Obtain the current procedure path. + * + * \returns The procedure search path. + **//////////////////////////////////////////////////////////////////// + std::string getServicePath() const { return m_servicePath; }; + ////////////////////////////////////////////////////////////////////// /** Obtain the current library path. * @@ -292,6 +299,8 @@ private: //------------------------------------------------------------------- std::string m_procPath; /** Holds the library path */ std::string m_libPath; + /** Holds the service path */ + std::string m_servicePath; /** Holds the output data directory */ std::string m_outputDir; /** Holds the input data directory */ diff --git a/include/SPELL_CFG/SPELLdriverConfig.H b/include/SPELL_CFG/SPELLdriverConfig.H index a6f60dd..cee0254 100644 --- a/include/SPELL_CFG/SPELLdriverConfig.H +++ b/include/SPELL_CFG/SPELLdriverConfig.H @@ -5,7 +5,7 @@ // DESCRIPTION: Wrapper for driver configuration // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CFG/SPELLexecutorDefaults.H b/include/SPELL_CFG/SPELLexecutorDefaults.H index e92022b..a59b9cf 100644 --- a/include/SPELL_CFG/SPELLexecutorDefaults.H +++ b/include/SPELL_CFG/SPELLexecutorDefaults.H @@ -5,7 +5,7 @@ // DESCRIPTION: Context default values for Executors // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -32,7 +32,7 @@ // Project includes ---------------------------------------------------------- #include "SPELL_WRP/SPELLconstants.H" #include "SPELL_CFG/SPELLbrowsableLibMode.H" - +#include "SPELL_UTIL/SPELLutils.H" /** \addtogroup SPELL_CFG */ /*@{*/ @@ -59,7 +59,20 @@ public: //-------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** Constructor. **//////////////////////////////////////////////////////////////////// - SPELLexecutorDefaults() {}; + SPELLexecutorDefaults() + { + m_browsableLib = OFF; + m_byStep = false; + m_execDelay = 0; + m_watchVariables = false; + m_resourcesDisplay = false; + m_localResourceSupport = false; + m_forcePromptConfirm = false; + m_forceTcConfirm = false; + m_maxVerbosity = 0; + m_runInto = false; + m_promptWarningDelay = 0; + }; ////////////////////////////////////////////////////////////////////// /** Destructor. @@ -74,58 +87,71 @@ public: //-------------------------------------------------------------------- // METHODS /////////////////////////////////////////////////////////////// // Member variables getters - int getExecDelay() + int getExecDelay() const { return m_execDelay; } - int getPromptWarningDelay() + int getPromptWarningDelay() const { return m_promptWarningDelay; } - bool isRunInto() + bool isRunInto() const { return m_runInto; } - bool isByStep() + bool isByStep() const { return m_byStep; } - SPELLbrowsableLibMode getBrowsableLib() + SPELLbrowsableLibMode getBrowsableLib() const { return m_browsableLib; } - std::string getBrowsableLibStr() + std::string getBrowsableLibStr() const { return browsableLibModeToString(m_browsableLib); } - int getMaxVerbosity() + int getMaxVerbosity() const { return m_maxVerbosity; } - bool isForceTcConfirm() + bool isForceTcConfirm() const { return m_forceTcConfirm; } - - std::string getSaveStateMode() + bool isForcePromptConfirm() const + { + return m_forcePromptConfirm; + } + std::string getSaveStateMode() const { return m_saveStateMode; } //getSaveStateMode - bool isWatchVariables() + bool isWatchVariables() const { return m_watchVariables; } - std::string getCtxName() + bool isResourcesDisplay() const + { + return m_resourcesDisplay; + } + + bool isLocalResourcesSupported() const + { + return m_localResourceSupport; + } + + std::string getCtxName() const { return m_ctxName; } @@ -173,7 +199,10 @@ public: //-------------------------------------------------------------------- { m_forceTcConfirm = forceTcConfirm; } - + void setForcePromptConfirm(bool forcePromptConfirm) + { + m_forcePromptConfirm = forcePromptConfirm; + } void setSaveStateMode(std::string saveModeStr) { m_saveStateMode = saveModeStr; @@ -184,6 +213,16 @@ public: //-------------------------------------------------------------------- m_watchVariables = watchVariables; } + void setResourcesDisplay(bool resourcesDisplay) + { + m_resourcesDisplay = resourcesDisplay; + } + + void setLocalResourcesSupported(bool localResourceSupport) + { + m_localResourceSupport = localResourceSupport; + } + void setCtxName( std::string ctxName) { m_ctxName = ctxName; @@ -199,7 +238,10 @@ public: //-------------------------------------------------------------------- str.append("BrowsableLib: ").append( browsableLibModeToString(m_browsableLib) ).append("\n"); str.append("MaxVerbosity: ").append(ISTR(m_maxVerbosity)).append("\n"); str.append("ForceTcConfirm: ").append(BSTR(m_forceTcConfirm)).append("\n"); + str.append("ForcePromptConfirm: ").append(BSTR(m_forcePromptConfirm)).append("\n"); str.append("WatchVariables: ").append(BSTR(m_watchVariables)).append("\n"); + str.append("ResourcesDisplay: ").append(BSTR(m_resourcesDisplay)).append("\n"); + str.append("LocalResourcesSupported: ").append(BSTR(m_localResourceSupport)).append("\n"); str.append("SaveStateMode: ").append(m_saveStateMode).append("\n"); return str; @@ -218,15 +260,18 @@ private: //------------------------------------------------------------------- // DATA MEMBERS ////////////////////////////////////////////////////////// int m_execDelay; - int m_promptWarningDelay; + int m_promptWarningDelay; bool m_runInto; bool m_byStep; //bool m_browsableLib; SPELLbrowsableLibMode m_browsableLib; int m_maxVerbosity; bool m_forceTcConfirm; + bool m_forcePromptConfirm; std::string m_saveStateMode; bool m_watchVariables; + bool m_resourcesDisplay; + bool m_localResourceSupport; std::string m_ctxName; }; diff --git a/include/SPELL_CFG/SPELLxmlConfigReader.H b/include/SPELL_CFG/SPELLxmlConfigReader.H index 7131b89..eedf53c 100644 --- a/include/SPELL_CFG/SPELLxmlConfigReader.H +++ b/include/SPELL_CFG/SPELLxmlConfigReader.H @@ -5,7 +5,7 @@ // DESCRIPTION: Wrapper for the XML configuration reader // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CFG/SPELLxmlConfigReaderFactory.H b/include/SPELL_CFG/SPELLxmlConfigReaderFactory.H index 6f6f0da..50c3251 100644 --- a/include/SPELL_CFG/SPELLxmlConfigReaderFactory.H +++ b/include/SPELL_CFG/SPELLxmlConfigReaderFactory.H @@ -5,7 +5,7 @@ // DESCRIPTION: Factory for XML configuration readers // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CFG/SPELLxmlConfigReaderXC.H b/include/SPELL_CFG/SPELLxmlConfigReaderXC.H index bc3074c..c012458 100644 --- a/include/SPELL_CFG/SPELLxmlConfigReaderXC.H +++ b/include/SPELL_CFG/SPELLxmlConfigReaderXC.H @@ -5,7 +5,7 @@ // DESCRIPTION: Xerces-C based implementation of the XML config. reader // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CFG/SPELLxmlNode.H b/include/SPELL_CFG/SPELLxmlNode.H index 993fd65..eaf6f2e 100644 --- a/include/SPELL_CFG/SPELLxmlNode.H +++ b/include/SPELL_CFG/SPELLxmlNode.H @@ -5,7 +5,7 @@ // DESCRIPTION: Wrapper for XML configuration node // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIF/SPELLasRun.H b/include/SPELL_CIF/SPELLasRun.H index e27df9f..6245b32 100644 --- a/include/SPELL_CIF/SPELLasRun.H +++ b/include/SPELL_CIF/SPELLasRun.H @@ -5,7 +5,7 @@ // DESCRIPTION: As-Run file interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIF/SPELLcif.H b/include/SPELL_CIF/SPELLcif.H index 8eb3d0c..809a0b0 100644 --- a/include/SPELL_CIF/SPELLcif.H +++ b/include/SPELL_CIF/SPELLcif.H @@ -5,7 +5,7 @@ // DESCRIPTION: Main CIF object interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -37,6 +37,7 @@ #include "SPELL_CIF/SPELLcifStartupInfo.H" // Project includes -------------------------------------------------------- #include "SPELL_EXC/SPELLvarInfo.H" +#include "SPELL_EXC/SPELLresourceInfo.H" #include "SPELL_PRD/SPELLprocedureSourceCode.H" #include "SPELL_SYN/SPELLevent.H" @@ -226,6 +227,8 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void setVerbosity( int verbosity ); + void setForcePromptConfirm( bool force ); + ////////////////////////////////////////////////////////////////////// /** Set the current verbosity to the maximum allowed value **//////////////////////////////////////////////////////////////////// @@ -344,7 +347,7 @@ public: //-------------------------------------------------------------------- * \param definition IN: prompt parameters **//////////////////////////////////////////////////////////////////// //virtual std::string prompt( const SPELLpromptDefinition& definition ) = 0; - virtual std::string prompt( const SPELLpromptDefinition& definition ); + virtual std::string prompt( const SPELLpromptDefinition& definition,bool doPromptConfirm = true ); ////////////////////////////////////////////////////////////////////// /** Notify a variable change. @@ -360,6 +363,18 @@ public: //-------------------------------------------------------------------- const std::vector& globals, const std::vector& locals ); + + ////////////////////////////////////////////////////////////////////// + /** Notify a resource change. + **//////////////////////////////////////////////////////////////////// + virtual void notifyResourceChange( const std::vector& changed ); + + ////////////////////////////////////////////////////////////////////// + /** Notify a resource list. + **//////////////////////////////////////////////////////////////////// + virtual void notifyResourceList( const std::vector& resources ); + + ////////////////////////////////////////////////////////////////////// /** Substitute the current ASRUN file by the given one * @@ -535,6 +550,16 @@ protected: //----------------------------------------------------------------- const std::vector& locals ) {;}; + ////////////////////////////////////////////////////////////////////// + /** See Notify a resource change. + **//////////////////////////////////////////////////////////////////// + virtual void specificNotifyResourceChange( const std::vector& changed ) {;}; + + ////////////////////////////////////////////////////////////////////// + /** See Notify a resource list. + **//////////////////////////////////////////////////////////////////// + virtual void specificNotifyResourceList( const std::vector& resources ) {;}; + ////////////////////////////////////////////////////////////////////// /** See OpenSubprocedure **//////////////////////////////////////////////////////////////////// @@ -595,6 +620,8 @@ private: //------------------------------------------------------------------- std::string m_procId; /** True if manual mode is enabled */ bool m_manualMode; + + bool m_forcePromptConfirm; /** Current verbosity level */ int m_verbosity; diff --git a/include/SPELL_CIF/SPELLcifHelper.H b/include/SPELL_CIF/SPELLcifHelper.H index eeeef63..8c58a17 100644 --- a/include/SPELL_CIF/SPELLcifHelper.H +++ b/include/SPELL_CIF/SPELLcifHelper.H @@ -5,7 +5,7 @@ // DESCRIPTION: Utilities for CIF // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIF/SPELLcifStartupInfo.H b/include/SPELL_CIF/SPELLcifStartupInfo.H index 298bf7a..31126d1 100644 --- a/include/SPELL_CIF/SPELLcifStartupInfo.H +++ b/include/SPELL_CIF/SPELLcifStartupInfo.H @@ -5,7 +5,7 @@ // DESCRIPTION: Information for CIF startup // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIF/SPELLnotifications.H b/include/SPELL_CIF/SPELLnotifications.H index 8d5e09a..aa4471d 100644 --- a/include/SPELL_CIF/SPELLnotifications.H +++ b/include/SPELL_CIF/SPELLnotifications.H @@ -5,7 +5,7 @@ // DESCRIPTION: Notification data structures // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIF/SPELLpromptDefinition.H b/include/SPELL_CIF/SPELLpromptDefinition.H index c81a9ab..ca4246f 100644 --- a/include/SPELL_CIF/SPELLpromptDefinition.H +++ b/include/SPELL_CIF/SPELLpromptDefinition.H @@ -5,7 +5,7 @@ // DESCRIPTION: Parameters defining a prompt // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIF/SPELLstatusInfo.H b/include/SPELL_CIF/SPELLstatusInfo.H index fb23a21..a54c545 100644 --- a/include/SPELL_CIF/SPELLstatusInfo.H +++ b/include/SPELL_CIF/SPELLstatusInfo.H @@ -5,7 +5,7 @@ // DESCRIPTION: Executor status information structure // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIFC/SPELLautomaticCif.H b/include/SPELL_CIFC/SPELLautomaticCif.H index 7d66e6b..97fa047 100644 --- a/include/SPELL_CIFC/SPELLautomaticCif.H +++ b/include/SPELL_CIFC/SPELLautomaticCif.H @@ -5,7 +5,7 @@ // DESCRIPTION: Automatic (non-interactive) client interface implementation // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -146,6 +146,16 @@ public: //-------------------------------------------------------------------- const std::vector& locals ); + ////////////////////////////////////////////////////////////////////// + /** Notify a resource change. + **//////////////////////////////////////////////////////////////////// + void specificNotifyResourceChange( const std::vector& changed ); + + ////////////////////////////////////////////////////////////////////// + /** Notify a resource list. + **//////////////////////////////////////////////////////////////////// + void specificNotifyResourceList( const std::vector& resources ); + ////////////////////////////////////////////////////////////////////// /** Open subprocedure. * diff --git a/include/SPELL_CIFC/SPELLncursesShell.H b/include/SPELL_CIFC/SPELLncursesShell.H index e992f27..1c87c3e 100644 --- a/include/SPELL_CIFC/SPELLncursesShell.H +++ b/include/SPELL_CIFC/SPELLncursesShell.H @@ -5,7 +5,7 @@ // DESCRIPTION: Command line shell for standalone execution (NCurses) // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -31,8 +31,7 @@ // System includes --------------------------------------------------------- #include #include -#include -#include +#include // Local includes ---------------------------------------------------------- // Project includes -------------------------------------------------------- #include "SPELL_SYN/SPELLthread.H" diff --git a/include/SPELL_CIFC/SPELLstandaloneCif.H b/include/SPELL_CIFC/SPELLstandaloneCif.H index 31a56b9..b6346b2 100644 --- a/include/SPELL_CIFC/SPELLstandaloneCif.H +++ b/include/SPELL_CIFC/SPELLstandaloneCif.H @@ -5,7 +5,7 @@ // DESCRIPTION: Standalone execution client interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIFS/SPELLcifPromptHelper.H b/include/SPELL_CIFS/SPELLcifPromptHelper.H index 17f7711..559e757 100644 --- a/include/SPELL_CIFS/SPELLcifPromptHelper.H +++ b/include/SPELL_CIFS/SPELLcifPromptHelper.H @@ -5,7 +5,7 @@ // DESCRIPTION: Helper for prompt processing // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIFS/SPELLdisplayBuffer.H b/include/SPELL_CIFS/SPELLdisplayBuffer.H index 8b3bd1b..2d8432b 100644 --- a/include/SPELL_CIFS/SPELLdisplayBuffer.H +++ b/include/SPELL_CIFS/SPELLdisplayBuffer.H @@ -5,7 +5,7 @@ // DESCRIPTION: Buffer for Display() messages // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CIFS/SPELLrequestProcessor.H b/include/SPELL_CIFS/SPELLrequestProcessor.H index 6df9f83..2bade15 100644 --- a/include/SPELL_CIFS/SPELLrequestProcessor.H +++ b/include/SPELL_CIFS/SPELLrequestProcessor.H @@ -5,7 +5,7 @@ // DESCRIPTION: Processing code for client requests // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -161,6 +161,33 @@ protected: //----------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void processCheckVariablesEnabled( const SPELLipcMessage& msg, SPELLipcMessage& response ); + ////////////////////////////////////////////////////////////////////// + /** Process a request to get current resource names. + * + * \param msg IN: IPC request. + * \param response INOUT: IPC response to complete. + * + **//////////////////////////////////////////////////////////////////// + void processGetResources( const SPELLipcMessage& msg, SPELLipcMessage& response ); + + ////////////////////////////////////////////////////////////////////// + /** Process a request to change a resource value + * + * \param msg IN: IPC request. + * \param response INOUT: IPC response to complete. + * + **//////////////////////////////////////////////////////////////////// + void processChangeResource( const SPELLipcMessage& msg, SPELLipcMessage& response ); + + ////////////////////////////////////////////////////////////////////// + /** Process a request to check if resource analysis is enabled + * + * \param msg IN: IPC request. + * \param response INOUT: IPC response to complete. + * + **//////////////////////////////////////////////////////////////////// + void processCheckResourcesEnabled( const SPELLipcMessage& msg, SPELLipcMessage& response ); + ////////////////////////////////////////////////////////////////////// /** Process a request to get global dictionary contents * diff --git a/include/SPELL_CIFS/SPELLresourceBuffer.H b/include/SPELL_CIFS/SPELLresourceBuffer.H new file mode 100644 index 0000000..6950743 --- /dev/null +++ b/include/SPELL_CIFS/SPELLresourceBuffer.H @@ -0,0 +1,146 @@ +// ################################################################################ +// FILE : SPELLresourceBuffer.H +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Buffer for Resource Display of TC Options (RDOTCO) messages +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_RESOURCE_BUFFER_H__ +#define __SPELL_RESOURCE_BUFFER_H__ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +// Local includes ---------------------------------------------------------- +// Project includes -------------------------------------------------------- +#include "SPELL_EXC/SPELLresourceInfo.H" +#include "SPELL_SYN/SPELLthread.H" +#include "SPELL_SYN/SPELLthread.H" +#include "SPELL_IPC/SPELLipcMessage.H" +#include "SPELL_SYN/SPELLmutex.H" + +/** \addtogroup SPELL_CIFS */ +/*@{*/ + + +// FORWARD REFERENCES ////////////////////////////////////////////////////// +class SPELLserverCif; +// TYPES /////////////////////////////////////////////////////////////////// +// DEFINES ///////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief Buffer for RDOTCO messages + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLresourceBuffer : public SPELLthread +{ +public: //-------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor. + **//////////////////////////////////////////////////////////////////// + SPELLresourceBuffer( const std::string& procId, SPELLserverCif& cif ); + + ////////////////////////////////////////////////////////////////////// + /** Destructor. + **//////////////////////////////////////////////////////////////////// + ~SPELLresourceBuffer(); + + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Main thread method + **//////////////////////////////////////////////////////////////////// + void run(); + + ////////////////////////////////////////////////////////////////////// + /** Stop the buffer + **//////////////////////////////////////////////////////////////////// + void stop(); + + ////////////////////////////////////////////////////////////////////// + /** Send a resource update message + **//////////////////////////////////////////////////////////////////// + void resourceChange( const std::vector& changed ); + + ////////////////////////////////////////////////////////////////////// + /** Send a resource list message + **//////////////////////////////////////////////////////////////////// + void resourceList( const std::vector& resources ); + + ////////////////////////////////////////////////////////////////////// + /** Collect the accumulated information and send the IPC message. + **//////////////////////////////////////////////////////////////////// + void flush(); + +protected: //----------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // STATIC //////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + +private: //------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // STATIC //////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Check if data available + **//////////////////////////////////////////////////////////////////// + bool hasDataToSend(); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + + /** Holds the reference to the CIF */ + SPELLserverCif& m_cif; + /** Working flag */ + bool m_working; + /** Synchronization lock */ + SPELLmutex m_lock; + /** Notification message skeletons */ + SPELLipcMessage m_resourceMessage; + /** List of added, updated and removed resources + * Note that it is a map, so updates overwrite: + * if a resource is added, then right away modified, then right away removed, + * only the removal effect will remain + * */ + std::map m_resources; + /** Accumulation of notifications */ + unsigned int m_total; + /** state whether the flush contain result of GetResources */ + bool m_bufferHasListResources; +}; + +/*@}*/ +#endif diff --git a/include/SPELL_CIFS/SPELLserverCif.H b/include/SPELL_CIFS/SPELLserverCif.H index 115ebea..d69a900 100644 --- a/include/SPELL_CIFS/SPELLserverCif.H +++ b/include/SPELL_CIFS/SPELLserverCif.H @@ -5,7 +5,7 @@ // DESCRIPTION: Client interface for server environment // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -33,6 +33,7 @@ #include "SPELL_CIFS/SPELLrequestProcessor.H" #include "SPELL_CIFS/SPELLdisplayBuffer.H" #include "SPELL_CIFS/SPELLvariableBuffer.H" +#include "SPELL_CIFS/SPELLresourceBuffer.H" // Project includes -------------------------------------------------------- #include "SPELL_SYN/SPELLthread.H" #include "SPELL_SYN/SPELLevent.H" @@ -164,6 +165,16 @@ public: //-------------------------------------------------------------------- const std::vector& globals, const std::vector& locals ); + ////////////////////////////////////////////////////////////////////// + /** Notify a resource change. + **//////////////////////////////////////////////////////////////////// + void specificNotifyResourceChange( const std::vector& changed ); + + ////////////////////////////////////////////////////////////////////// + /** Notify a resource list. + **//////////////////////////////////////////////////////////////////// + void specificNotifyResourceList( const std::vector& resources ); + ////////////////////////////////////////////////////////////////////// /** See openSubprocedure **//////////////////////////////////////////////////////////////////// @@ -184,7 +195,9 @@ public: //-------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** Get prompt information if any **//////////////////////////////////////////////////////////////////// - SPELLpromptDefinition getPromptInfo() { return m_promptDef; } + SPELLpromptDefinition getPromptInfo() { return m_promptDef; }; + + SPELLipcMessage getPingMessage(); //==================================================================== // Python bindings end @@ -196,6 +209,7 @@ protected: //----------------------------------------------------------------- friend class SPELLdisplayBuffer; friend class SPELLvariableBuffer; + friend class SPELLresourceBuffer; // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// @@ -248,7 +262,7 @@ protected: //----------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** Wait acknowledge from client *//////////////////////////////////////////////////////////////////// - void waitAcknowledge( const SPELLipcMessage& msg ); + bool waitAcknowledge( const SPELLipcMessage& msg ); //==================================================================== // Shared data handling @@ -341,7 +355,6 @@ protected: //----------------------------------------------------------------- *//////////////////////////////////////////////////////////////////// void prepareMessage( SPELLipcMessage& msg, const std::string dataType, SPELLipcMessageType_ msgType ); - // DATA MEMBERS ////////////////////////////////////////////////////////// private: //------------------------------------------------------------------- @@ -408,6 +421,8 @@ private: //------------------------------------------------------------------- SPELLdisplayBuffer* m_buffer; /** Buffer to accumulate WOV messages */ SPELLvariableBuffer* m_wovBuffer; + /** Buffer to accumulate RDOTCO messages */ + SPELLresourceBuffer* m_rdotcoBuffer; /** True when the CIF is ready to work */ @@ -437,6 +452,8 @@ private: //------------------------------------------------------------------- /** IPC synchronization */ SPELLmutex m_ipcLock; + /** Promp synchronization */ + SPELLmutex m_promptLock; /** Close synchronization */ SPELLmutex m_closeLock; /** Closing flag */ diff --git a/include/SPELL_CIFS/SPELLvariableBuffer.H b/include/SPELL_CIFS/SPELLvariableBuffer.H index d59bd2c..899e7ec 100644 --- a/include/SPELL_CIFS/SPELLvariableBuffer.H +++ b/include/SPELL_CIFS/SPELLvariableBuffer.H @@ -5,7 +5,7 @@ // DESCRIPTION: Buffer for WOV messages // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLclient.H b/include/SPELL_CTX/SPELLclient.H index bf4d23e..3efe632 100644 --- a/include/SPELL_CTX/SPELLclient.H +++ b/include/SPELL_CTX/SPELLclient.H @@ -5,7 +5,7 @@ // DESCRIPTION: Client manager and controller // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLclientIPC.H b/include/SPELL_CTX/SPELLclientIPC.H index c2eaf29..12f6ee4 100644 --- a/include/SPELL_CTX/SPELLclientIPC.H +++ b/include/SPELL_CTX/SPELLclientIPC.H @@ -5,7 +5,7 @@ // DESCRIPTION: IPC interface for clients // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLclientInterestList.H b/include/SPELL_CTX/SPELLclientInterestList.H index 2cef023..7784308 100644 --- a/include/SPELL_CTX/SPELLclientInterestList.H +++ b/include/SPELL_CTX/SPELLclientInterestList.H @@ -5,7 +5,7 @@ // DESCRIPTION: List of the entities interested on a given client // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLclientListener.H b/include/SPELL_CTX/SPELLclientListener.H index 371422a..07b7aa8 100644 --- a/include/SPELL_CTX/SPELLclientListener.H +++ b/include/SPELL_CTX/SPELLclientListener.H @@ -5,7 +5,7 @@ // DESCRIPTION: The implementing class is interested on client messages // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLclientManager.H b/include/SPELL_CTX/SPELLclientManager.H index 74c172e..a2cab8b 100644 --- a/include/SPELL_CTX/SPELLclientManager.H +++ b/include/SPELL_CTX/SPELLclientManager.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL client manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLclientMode.H b/include/SPELL_CTX/SPELLclientMode.H index f25bf30..1e89cd6 100644 --- a/include/SPELL_CTX/SPELLclientMode.H +++ b/include/SPELL_CTX/SPELLclientMode.H @@ -5,7 +5,7 @@ // DESCRIPTION: Client mode definition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLclientNotifier.H b/include/SPELL_CTX/SPELLclientNotifier.H index 60c72a1..81222a1 100644 --- a/include/SPELL_CTX/SPELLclientNotifier.H +++ b/include/SPELL_CTX/SPELLclientNotifier.H @@ -5,7 +5,7 @@ // DESCRIPTION: Client notifier for monitoring mode // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLclientOperation.H b/include/SPELL_CTX/SPELLclientOperation.H index dc9e1f1..faca460 100644 --- a/include/SPELL_CTX/SPELLclientOperation.H +++ b/include/SPELL_CTX/SPELLclientOperation.H @@ -5,7 +5,7 @@ // DESCRIPTION: Definition of the client operations // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLcontext.H b/include/SPELL_CTX/SPELLcontext.H index 2571ec0..a4e1073 100644 --- a/include/SPELL_CTX/SPELLcontext.H +++ b/include/SPELL_CTX/SPELLcontext.H @@ -5,7 +5,7 @@ // DESCRIPTION: Main class of the context process // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -53,7 +53,9 @@ // FORWARD REFERENCES //////////////////////////////////////////////////////// // TYPES ///////////////////////////////////////////////////////////////////// // DEFINES /////////////////////////////////////////////////////////////////// - +extern "C" { + void checkService( std::string& serviceId ); +} ////////////////////////////////////////////////////////////////////////////// /** ** \brief @@ -127,6 +129,7 @@ public: //-------------------------------------------------------------------- //==================================================================== SPELLipcMessage openExecutor( const SPELLipcMessage& msg, SPELLclient* controllingClient ); + bool openService( const std::string serviceName ); SPELLipcMessage getInstanceId(const SPELLipcMessage& msg); SPELLipcMessage getCurrentTime(const SPELLipcMessage& msg); SPELLipcMessage closeExecutor(const SPELLipcMessage& msg); @@ -136,10 +139,12 @@ public: //-------------------------------------------------------------------- SPELLipcMessage setExecutorInBackground( const SPELLipcMessage& msg ); SPELLipcMessage getProcedureList( const SPELLipcMessage& msg ); SPELLipcMessage getExecutorList( const SPELLipcMessage& msg ); + SPELLipcMessage getServiceList( const SPELLipcMessage& msg ); SPELLipcMessage getProcedureProperties( const SPELLipcMessage& msg ); SPELLipcMessage getProcedureCode( const SPELLipcMessage& msg ); SPELLipcMessage getExecutorInfo(const SPELLipcMessage& msg); - SPELLipcMessage attachExecutor(const SPELLipcMessage& msg, SPELLclient* client ); + SPELLipcMessage getServiceInfo(const SPELLipcMessage& msg); + SPELLipcMessage attachExecutor(const SPELLipcMessage& msg, SPELLclient* client ); SPELLipcMessage detachExecutor(const SPELLipcMessage& msg, SPELLclient* client ); SPELLipcMessage getClientInfo(const SPELLipcMessage& msg); SPELLipcMessage getServerFilePath(const SPELLipcMessage& msg); @@ -169,6 +174,8 @@ public: //-------------------------------------------------------------------- //==================================================================== void clientLost( int clientKey ); void executorLost( const std::string& procId ); + void serviceLost( const std::string& procId ); + // STATIC //////////////////////////////////////////////////////////////// diff --git a/include/SPELL_CTX/SPELLcontextConfiguration.H b/include/SPELL_CTX/SPELLcontextConfiguration.H index 5ec5c1a..bfc7798 100644 --- a/include/SPELL_CTX/SPELLcontextConfiguration.H +++ b/include/SPELL_CTX/SPELLcontextConfiguration.H @@ -5,7 +5,7 @@ // DESCRIPTION: Configuration for the context process // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLdataHelper.H b/include/SPELL_CTX/SPELLdataHelper.H index 0288af5..d03885d 100644 --- a/include/SPELL_CTX/SPELLdataHelper.H +++ b/include/SPELL_CTX/SPELLdataHelper.H @@ -5,7 +5,7 @@ // DESCRIPTION: Utilities for data handling // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLdataTable.H b/include/SPELL_CTX/SPELLdataTable.H index 223366a..3b64e8f 100644 --- a/include/SPELL_CTX/SPELLdataTable.H +++ b/include/SPELL_CTX/SPELLdataTable.H @@ -5,7 +5,7 @@ // DESCRIPTION: Shared data table // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLexecutor.H b/include/SPELL_CTX/SPELLexecutor.H index 5d60e63..b083f88 100644 --- a/include/SPELL_CTX/SPELLexecutor.H +++ b/include/SPELL_CTX/SPELLexecutor.H @@ -5,7 +5,7 @@ // DESCRIPTION: Executor manager and controller // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -46,7 +46,9 @@ // FORWARD REFERENCES //////////////////////////////////////////////////////// + class LoginMonitor; + // TYPES ///////////////////////////////////////////////////////////////////// // DEFINES /////////////////////////////////////////////////////////////////// @@ -55,7 +57,7 @@ class LoginMonitor; ** \brief ** **//////////////////////////////////////////////////////////////////////////// -class SPELLexecutor : public SPELLexecutorListener, SPELLprocessListener +class SPELLexecutor : public SPELLexecutorListener,public SPELLprocessListener { public: //-------------------------------------------------------------------- @@ -79,126 +81,126 @@ public: //-------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** Start the executor process **//////////////////////////////////////////////////////////////////// - void start(); + virtual void start(); ////////////////////////////////////////////////////////////////////// /** Close the executor process **//////////////////////////////////////////////////////////////////// - void close(); + virtual void close(); ////////////////////////////////////////////////////////////////////// /** Kill the executor process **//////////////////////////////////////////////////////////////////// - void kill(); + virtual void kill(); ////////////////////////////////////////////////////////////////////// /** Wait for a given executor status * * \returns True on timeout **//////////////////////////////////////////////////////////////////// - bool waitStatus( const SPELLexecutorStatus& status, unsigned int timeoutSec ); + virtual bool waitStatus( const SPELLexecutorStatus& status, unsigned int timeoutSec ); ////////////////////////////////////////////////////////////////////// /** Wait for executor login * * \returns True if logged in **//////////////////////////////////////////////////////////////////// - bool waitLogin( unsigned int timeoutMsec ); + virtual bool waitLogin( unsigned int timeoutMsec ); ////////////////////////////////////////////////////////////////////// /** Check for executor login * * \returns True if logged in **//////////////////////////////////////////////////////////////////// - bool isLoggedIn() { return m_loggedIn; }; + virtual bool isLoggedIn() { return m_loggedIn; }; ////////////////////////////////////////////////////////////////////// /** Get the status of the executor * * \returns The status **//////////////////////////////////////////////////////////////////// - SPELLexecutorStatus getStatus(); + virtual SPELLexecutorStatus getStatus(); ////////////////////////////////////////////////////////////////////// /** Check if the executor is active * * \returns True if active **//////////////////////////////////////////////////////////////////// - bool isActive(); + virtual bool isActive(); ////////////////////////////////////////////////////////////////////// /** Check if the executor has a parent procedure * * \returns True if has a parent **//////////////////////////////////////////////////////////////////// - bool hasParent() { return m_model.getParentInstanceId() != ""; } ; + virtual bool hasParent() { return m_model.getParentInstanceId() != ""; } ; ////////////////////////////////////////////////////////////////////// /** Get the executor parent procedure * * \returns The parent procedure id **//////////////////////////////////////////////////////////////////// - std::string getParentInstanceId() { return m_model.getParentInstanceId(); } ; + virtual std::string getParentInstanceId() { return m_model.getParentInstanceId(); } ; ////////////////////////////////////////////////////////////////////// /** Send a command to the executor **//////////////////////////////////////////////////////////////////// - void command( const ExecutorCommand& command ); + virtual void command( const ExecutorCommand& command ); ////////////////////////////////////////////////////////////////////// /** Set the controlling client **//////////////////////////////////////////////////////////////////// - void setControllingClient( SPELLclient* client ); + virtual void setControllingClient( SPELLclient* client ); ////////////////////////////////////////////////////////////////////// /** Set the procedure to headless (background) mode **//////////////////////////////////////////////////////////////////// - void setBackground(); + virtual void setBackground(); ////////////////////////////////////////////////////////////////////// /** Check whether the procedure is in headless (background) mode **//////////////////////////////////////////////////////////////////// - bool isBackground() { return m_clientConnection == CLI_BACKGROUND; }; + virtual bool isBackground() { return m_clientConnection == CLI_BACKGROUND; }; ////////////////////////////////////////////////////////////////////// /** Remove the controlling client **//////////////////////////////////////////////////////////////////// - void removeControllingClient( bool clientLost ); + virtual void removeControllingClient( bool clientLost ); ////////////////////////////////////////////////////////////////////// /** Check if it has controlling client **//////////////////////////////////////////////////////////////////// - bool hasControllingClient(); + virtual bool hasControllingClient(); ////////////////////////////////////////////////////////////////////// /** Check if it has controlling client **//////////////////////////////////////////////////////////////////// - SPELLclient* getControllingClient(); + virtual SPELLclient* getControllingClient(); ////////////////////////////////////////////////////////////////////// /** Send a message to the executor process **//////////////////////////////////////////////////////////////////// - void sendMessageToExecutor( const SPELLipcMessage& msg ); + virtual void sendMessageToExecutor( const SPELLipcMessage& msg ); ////////////////////////////////////////////////////////////////////// /** Send a request to the executor process **//////////////////////////////////////////////////////////////////// - SPELLipcMessage sendRequestToExecutor( const SPELLipcMessage& msg ); + virtual SPELLipcMessage sendRequestToExecutor( const SPELLipcMessage& msg ); ////////////////////////////////////////////////////////////////////// /** Get the executor model **//////////////////////////////////////////////////////////////////// - SPELLexecutorModel& getModel() { return m_model; }; + SPELLexecutorModel& getModel() { return m_model; }; ////////////////////////////////////////////////////////////////////// /** Register executor notifier for monitoring mode **//////////////////////////////////////////////////////////////////// - void registerNotifier( std::string id, SPELLexecutorListener* listener ); + virtual void registerNotifier( std::string id, SPELLexecutorListener* listener ); ////////////////////////////////////////////////////////////////////// /** Deregister executor notifier **//////////////////////////////////////////////////////////////////// - void deregisterNotifier( std::string id ); + virtual void deregisterNotifier( std::string id ); // DATA MEMBERS ////////////////////////////////////////////////////////// @@ -207,7 +209,7 @@ protected: //----------------------------------------------------------------- friend class SPELLexecutorInterestList; friend class SPELLprocessManager; friend class SPELLexecutorIPC; - + //friend class SPELLservice; // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// // TYPES ///////////////////////////////////////////////////////////////// @@ -219,9 +221,9 @@ protected: //----------------------------------------------------------------- // EXECUTOR REQUEST HANDLING //==================================================================== - SPELLipcMessage executorLogin( const SPELLipcMessage& msg ); + virtual SPELLipcMessage executorLogin( const SPELLipcMessage& msg ); - void executorNotification( const SPELLipcMessage& msg ); + virtual void executorNotification( const SPELLipcMessage& msg ); //==================================================================== // INTERNAL IPC METHODS @@ -230,27 +232,27 @@ protected: //----------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** \see SPELLexecutorListener. **//////////////////////////////////////////////////////////////////// - void processMessageFromExecutor( SPELLipcMessage msg ); + virtual void processMessageFromExecutor( SPELLipcMessage msg ); ////////////////////////////////////////////////////////////////////// /** \see SPELLexecutorListener. **//////////////////////////////////////////////////////////////////// - SPELLipcMessage processRequestFromExecutor( SPELLipcMessage msg ); + virtual SPELLipcMessage processRequestFromExecutor( SPELLipcMessage msg ); ////////////////////////////////////////////////////////////////////// /** Forward a message from the executor to the client **//////////////////////////////////////////////////////////////////// - void forwardMessageToClient( const SPELLipcMessage& msg ); + virtual void forwardMessageToClient( const SPELLipcMessage& msg ); ////////////////////////////////////////////////////////////////////// /** Forward a request from the executor to the client **//////////////////////////////////////////////////////////////////// - SPELLipcMessage forwardRequestToClient( const SPELLipcMessage& msg ); + virtual SPELLipcMessage forwardRequestToClient( const SPELLipcMessage& msg ); ////////////////////////////////////////////////////////////////////// /** Force an executor pause **//////////////////////////////////////////////////////////////////// - void forcePause(); + virtual void forcePause(); //==================================================================== // INTERNAL PROCESS CONTROL METHODS @@ -261,36 +263,36 @@ protected: //----------------------------------------------------------------- * * \returns True if active **//////////////////////////////////////////////////////////////////// - bool processOk(); + virtual bool processOk(); ////////////////////////////////////////////////////////////////////// /** Wait until the executor process has finished **//////////////////////////////////////////////////////////////////// - void waitFinish(); + virtual void waitFinish(); ////////////////////////////////////////////////////////////////////// /** \see SPELLprocessListener. **//////////////////////////////////////////////////////////////////// - void processStarted( const std::string& identifier ); + virtual void processStarted( const std::string identifier ); ////////////////////////////////////////////////////////////////////// /** \see SPELLprocessListener. **//////////////////////////////////////////////////////////////////// - void processFinished( const std::string& identifier, const int& retValue ); + virtual void processFinished( const std::string identifier, const int& retValue ); ////////////////////////////////////////////////////////////////////// /** \see SPELLprocessListener. **//////////////////////////////////////////////////////////////////// - void processKilled( const std::string& identifier ); + virtual void processKilled( const std::string identifier ); ////////////////////////////////////////////////////////////////////// /** \see SPELLprocessListener. **//////////////////////////////////////////////////////////////////// - void processFailed( const std::string& identifier ); + virtual void processFailed( const std::string identifier ); private: //------------------------------------------------------------------- - + friend class SPELLservice; // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// // TYPES ///////////////////////////////////////////////////////////////// @@ -347,6 +349,19 @@ private: //------------------------------------------------------------------- }; +class LoginMonitor : public SPELLthread +{ +public: + LoginMonitor( SPELLexecutor& exec ) + : SPELLthread("login-" + exec.getModel().getInstanceId() ), + m_exec( exec ) + {} + + void run(); + +private: + SPELLexecutor& m_exec; +}; /*@}*/ #endif diff --git a/include/SPELL_CTX/SPELLexecutorIPC.H b/include/SPELL_CTX/SPELLexecutorIPC.H index ab15f8e..16bf9a7 100644 --- a/include/SPELL_CTX/SPELLexecutorIPC.H +++ b/include/SPELL_CTX/SPELLexecutorIPC.H @@ -5,7 +5,7 @@ // DESCRIPTION: IPC interface for executors // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLexecutorListener.H b/include/SPELL_CTX/SPELLexecutorListener.H index 48d9570..96834fa 100644 --- a/include/SPELL_CTX/SPELLexecutorListener.H +++ b/include/SPELL_CTX/SPELLexecutorListener.H @@ -5,7 +5,7 @@ // DESCRIPTION: The implementing class is interested on executor messages // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLexecutorManager.H b/include/SPELL_CTX/SPELLexecutorManager.H index 7028c58..0fbdc45 100644 --- a/include/SPELL_CTX/SPELLexecutorManager.H +++ b/include/SPELL_CTX/SPELLexecutorManager.H @@ -5,7 +5,7 @@ // DESCRIPTION: Manages the executor operations interacts with clients // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -225,8 +225,6 @@ private: //------------------------------------------------------------------- void addInstanceNumber( const std::string& procId, int instanceNum ); - void removeInstanceNumber( const std::string& procId, int instanceNum ); - void clearModels(); // DATA MEMBERS ////////////////////////////////////////////////////////// diff --git a/include/SPELL_CTX/SPELLexecutorModel.H b/include/SPELL_CTX/SPELLexecutorModel.H index 131bce2..ed1bd8b 100644 --- a/include/SPELL_CTX/SPELLexecutorModel.H +++ b/include/SPELL_CTX/SPELLexecutorModel.H @@ -5,7 +5,7 @@ // DESCRIPTION: Information of a given executor // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -136,7 +136,8 @@ public: //-------------------------------------------------------------------- protected: //----------------------------------------------------------------- - friend class SPELLexecutor; + friend class SPELLexecutor; + friend class SPELLservice; // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// diff --git a/include/SPELL_CTX/SPELLexecutorOperation.H b/include/SPELL_CTX/SPELLexecutorOperation.H index 8bd716e..bec7136 100644 --- a/include/SPELL_CTX/SPELLexecutorOperation.H +++ b/include/SPELL_CTX/SPELLexecutorOperation.H @@ -5,7 +5,7 @@ // DESCRIPTION: Definition of the executor operations // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLexecutorStartupParams.H b/include/SPELL_CTX/SPELLexecutorStartupParams.H index cedb0b6..7e241ee 100644 --- a/include/SPELL_CTX/SPELLexecutorStartupParams.H +++ b/include/SPELL_CTX/SPELLexecutorStartupParams.H @@ -5,7 +5,7 @@ // DESCRIPTION: Configuration for the executor process // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -126,7 +126,7 @@ public: //-------------------------------------------------------------------- void setRecoveryFile( const std::string& recoveryFile ) { m_recoveryFile = recoveryFile; }; private: //------------------------------------------------------------------- - + friend class SPELLserviceStartupParams; // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// // TYPES ///////////////////////////////////////////////////////////////// diff --git a/include/SPELL_CTX/SPELLlistenerIPC.H b/include/SPELL_CTX/SPELLlistenerIPC.H index 1ed02d0..7902e27 100644 --- a/include/SPELL_CTX/SPELLlistenerIPC.H +++ b/include/SPELL_CTX/SPELLlistenerIPC.H @@ -5,7 +5,7 @@ // DESCRIPTION: IPC interface for listener // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLopenMode.H b/include/SPELL_CTX/SPELLopenMode.H index 330e9d7..792390e 100644 --- a/include/SPELL_CTX/SPELLopenMode.H +++ b/include/SPELL_CTX/SPELLopenMode.H @@ -5,7 +5,7 @@ // DESCRIPTION: Executor open mode definition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLpersistencyTable.H b/include/SPELL_CTX/SPELLpersistencyTable.H index b7912dc..9b59cee 100644 --- a/include/SPELL_CTX/SPELLpersistencyTable.H +++ b/include/SPELL_CTX/SPELLpersistencyTable.H @@ -5,7 +5,7 @@ // DESCRIPTION: Keeps persistency of open executors // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLserverFile.H b/include/SPELL_CTX/SPELLserverFile.H index 9dbcfc8..c5e013c 100644 --- a/include/SPELL_CTX/SPELLserverFile.H +++ b/include/SPELL_CTX/SPELLserverFile.H @@ -5,7 +5,7 @@ // DESCRIPTION: Type of server file definition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_CTX/SPELLservice.H b/include/SPELL_CTX/SPELLservice.H new file mode 100644 index 0000000..1b8c3d0 --- /dev/null +++ b/include/SPELL_CTX/SPELLservice.H @@ -0,0 +1,89 @@ +// ################################################################################ +// FILE : SPELLservice.H +// DATE : Apr 11, 2011 +// PROJECT : SPELL +// DESCRIPTION: Executor manager and controller +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_SERVICE_H__ +#define __SPELL_SERVICE_H__ + +// FILES TO INCLUDE ////////////////////////////////////////////////////////// +// Local includes ------------------------------------------------------------ +#include "SPELL_CTX/SPELLserviceListener.H" +#include "SPELL_CTX/SPELLserviceStartupParams.H" +#include "SPELL_CTX/SPELLclient.H" +#include "SPELL_CTX/SPELLexecutor.H" +// Project includes ---------------------------------------------------------- +#include "SPELL_PRC/SPELLprocessManager.H" +#include "SPELL_EXC/SPELLcommand.H" +#include "SPELL_EXC/SPELLexecutorStatus.H" +#include "SPELL_SYN/SPELLevent.H" +#include "SPELL_SYN/SPELLmutex.H" + +/** \addtogroup SPELL_CTX */ +/*@{*/ + + +// FORWARD REFERENCES //////////////////////////////////////////////////////// + +// TYPES ///////////////////////////////////////////////////////////////////// +// DEFINES /////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLservice : public SPELLexecutor +{ +public: //-------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor. + **//////////////////////////////////////////////////////////////////// + SPELLservice( const SPELLserviceStartupParams& config ); + + ////////////////////////////////////////////////////////////////////// + /** Destructor. + **//////////////////////////////////////////////////////////////////// + virtual ~SPELLservice(); + + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Start the executor process + **//////////////////////////////////////////////////////////////////// + void start(); + + + +}; + + +/*@}*/ +#endif diff --git a/include/SPELL_CTX/SPELLserviceListener.H b/include/SPELL_CTX/SPELLserviceListener.H new file mode 100644 index 0000000..a2a6b56 --- /dev/null +++ b/include/SPELL_CTX/SPELLserviceListener.H @@ -0,0 +1,109 @@ +// ################################################################################ +// FILE : SPELLserviceListener.H +// DATE : Apr 11, 2011 +// PROJECT : SPELL +// DESCRIPTION: The implementing class is interested on executor messages +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_SERVICE_LISTENER_H__ +#define __SPELL_SERVICE_LISTENER_H__ + +// FILES TO INCLUDE ////////////////////////////////////////////////////////// +// Local includes ------------------------------------------------------------ +// Project includes ---------------------------------------------------------- +#include "SPELL_IPC/SPELLipcMessage.H" + +/** \addtogroup SPELL_CTX */ +/*@{*/ + + +// FORWARD REFERENCES //////////////////////////////////////////////////////// +// TYPES ///////////////////////////////////////////////////////////////////// +// DEFINES /////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLserviceListener +{ +public: //-------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor. + **//////////////////////////////////////////////////////////////////// + SPELLserviceListener() {}; + + ////////////////////////////////////////////////////////////////////// + /** Destructor. + **//////////////////////////////////////////////////////////////////// + virtual ~SPELLserviceListener() {}; + + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Process an incoming message. + * + * \param msg IN: the message to be processed. + **//////////////////////////////////////////////////////////////////// + virtual void processMessageFromService( SPELLipcMessage msg ) = 0; + + ////////////////////////////////////////////////////////////////////// + /** Process an incoming request. + * + * \param msg IN: request to be processed. + * + * \return The request response. + **//////////////////////////////////////////////////////////////////// + virtual SPELLipcMessage processRequestFromService( SPELLipcMessage msg ) = 0; + + // DATA MEMBERS ////////////////////////////////////////////////////////// + +protected: //----------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // STATIC //////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + +private: //------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // STATIC //////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + // DATA MEMBERS ////////////////////////////////////////////////////////// + +}; + +/*@}*/ +#endif diff --git a/include/SPELL_CTX/SPELLserviceManager.H b/include/SPELL_CTX/SPELLserviceManager.H new file mode 100644 index 0000000..a472b90 --- /dev/null +++ b/include/SPELL_CTX/SPELLserviceManager.H @@ -0,0 +1,250 @@ +// ################################################################################ +// FILE : SPELLexecutorManager.H +// DATE : Apr 11, 2011 +// PROJECT : SPELL +// DESCRIPTION: Manages the executor operations interacts with clients +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_SERVICE_MANAGER_H__ +#define __SPELL_SERVICE_MANAGER_H__ + +// FILES TO INCLUDE ////////////////////////////////////////////////////////// +// Local includes ------------------------------------------------------------ +#include "SPELL_CTX/SPELLservice.H" +#include "SPELL_CTX/SPELLclient.H" +#include "SPELL_CTX/SPELLserviceStartupParams.H" + +#include "SPELL_CTX/SPELLpersistencyTable.H" +// Project includes ---------------------------------------------------------- +#include "SPELL_EXC/SPELLcommand.H" +#include "SPELL_SYN/SPELLmutex.H" +#include "SPELL_IPC/SPELLipcMessage.H" + +/** \addtogroup SPELL_CTX */ +/*@{*/ + + +// FORWARD REFERENCES //////////////////////////////////////////////////////// +// TYPES ///////////////////////////////////////////////////////////////////// +// DEFINES /////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief + ** + ** \par Description: + ** + ** \par Usage: + ** + ** \par Synchronization: + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLserviceManager +{ +public: //-------------------------------------------------------------------- + + // ENUMS ///////////////////////////////////////////////////////////////// + + typedef enum ErrorCode_ + { + UNKNOWN_PROC_ID, + SERVICE_FAILED_STARTUP, + SERVICE_CRASHED, + UNKNOWN + } + ErrorCode; + + // EXCEPTIONS //////////////////////////////////////////////////////////// + + typedef struct OperationError_ + { + std::string message; + ErrorCode errorCode; + } + OperationError; + + // TYPES ///////////////////////////////////////////////////////////////// + + typedef std::list ServiceList; + + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor. + **//////////////////////////////////////////////////////////////////// + SPELLserviceManager(); + + ////////////////////////////////////////////////////////////////////// + /** Destructor. + **//////////////////////////////////////////////////////////////////// + ~SPELLserviceManager(); + + // STATIC //////////////////////////////////////////////////////////////// + + static SPELLserviceManager& instance(); + + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Start a service + **//////////////////////////////////////////////////////////////////// + void startService( SPELLserviceStartupParams& config ); + + ////////////////////////////////////////////////////////////////////// + /** Stop an executor + **//////////////////////////////////////////////////////////////////// + void closeService(std::string& serviceId ); + + ////////////////////////////////////////////////////////////////////// + /** Kill an executor + **//////////////////////////////////////////////////////////////////// + void killService( const std::string& serviceId ); + + ////////////////////////////////////////////////////////////////////// + /** Kill all executors + **//////////////////////////////////////////////////////////////////// + void killAll(); + + ////////////////////////////////////////////////////////////////////// + /** Check for active executors + **//////////////////////////////////////////////////////////////////// + unsigned int getNumActiveServices(); + + ////////////////////////////////////////////////////////////////////// + /** Obtain an available instance identifier + **//////////////////////////////////////////////////////////////////// + std::string getInstanceId( const std::string& serviceId ); + + ////////////////////////////////////////////////////////////////////// + /** Initialize the manager + **//////////////////////////////////////////////////////////////////// + void setup( const std::string& contextName ); + + ////////////////////////////////////////////////////////////////////// + /** Cleanup the manager + **//////////////////////////////////////////////////////////////////// + void cleanup(); + + ////////////////////////////////////////////////////////////////////// + /** Obtain a given executor + **//////////////////////////////////////////////////////////////////// + SPELLservice* getService( const std::string& serviceId ); + + ////////////////////////////////////////////////////////////////////// + /** Obtain list of existing executors + **//////////////////////////////////////////////////////////////////// + ServiceList getServiceList(); + + ////////////////////////////////////////////////////////////////////// + /** Report an executor lost + **//////////////////////////////////////////////////////////////////// + void serviceLost( SPELLservice& service ); + + ////////////////////////////////////////////////////////////////////// + /** Mark executor to be cleared + **//////////////////////////////////////////////////////////////////// + void clearService( const std::string& instanceId ); + + ////////////////////////////////////////////////////////////////////// + /** Closes a service + **//////////////////////////////////////////////////////////////////// + void closeService( const std::string& instanceId ); + + ////////////////////////////////////////////////////////////////////// + /** Complete the message with executor information + **//////////////////////////////////////////////////////////////////// + void buildServiceInfo( const std::string& serviceId, SPELLipcMessage& msg ); + + ////////////////////////////////////////////////////////////////////// + /** Delete files corresponding to the given executor + **//////////////////////////////////////////////////////////////////// + void deleteServiceFiles( const SPELLserviceStartupParams& config ); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + +protected: //----------------------------------------------------------------- + + friend class ServiceLoginMonitor; + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + void callback_serviceReconnected( const std::string& instanceId ); + void callback_serviceNotReconnected( const std::string& instanceId ); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + +private: //------------------------------------------------------------------- + friend class SPELLexecutorManager; + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + + typedef std::map ServiceMap; + typedef std::list InstanceList; + typedef std::map InstanceMap; + typedef std::list IdentifierList; + + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Prepare to executor reconnection in case of starting after crash + **//////////////////////////////////////////////////////////////////// + void reconnectServices(); + + void addServiceModel( SPELLservice* exec ); + + void removeServiceModel( const std::string& instanceId ); + + bool hasInstanceNumber( const std::string& serviceId, int instanceNum ); + + void addInstanceNumber( const std::string& serviceId, int instanceNum ); + + void clearModels(); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + + /** Synchronization lock */ + SPELLmutex m_lock; + /** Holds the singleton instance */ + static SPELLserviceManager* s_instance; + /** Holds the map of existing executors */ + ServiceMap m_services; + /** Holds the map of existing instance numbers */ + InstanceMap m_instances; + /** Holds the context name */ + std::string m_contextName; + /** Holds the list of executors to be cleared next time */ + IdentifierList m_toClear; + /** Holds the persistency table for executors */ + SPELLpersistencyTable* m_persisTable; + /** Orphan executors pending login */ + ServiceMap m_pendingLogin; + +}; + +/*@}*/ +#endif diff --git a/include/SPELL_CTX/SPELLserviceStartupParams.H b/include/SPELL_CTX/SPELLserviceStartupParams.H new file mode 100644 index 0000000..e999a08 --- /dev/null +++ b/include/SPELL_CTX/SPELLserviceStartupParams.H @@ -0,0 +1,143 @@ +// ################################################################################ +// FILE : SPELLexecutorStartupParams.H +// DATE : Feb 13, 2014 +// PROJECT : SPELL +// DESCRIPTION: Configuration for the executor process +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_SERVICE_STARTUP_PARAMS_H__ +#define __SPELL_SERVICE_STARTUP_PARAMS_H__ + +// FILES TO INCLUDE ////////////////////////////////////////////////////////// +// Local includes ------------------------------------------------------------ +#include "SPELL_CTX/SPELLclientMode.H" +#include "SPELL_CTX/SPELLopenMode.H" +#include "SPELL_CTX/SPELLexecutorStartupParams.H" +// Project includes ---------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" +#include "SPELL_UTIL/SPELLutils.H" + +/** \addtogroup SPELL_CTX */ +/*@{*/ + + +// FORWARD REFERENCES //////////////////////////////////////////////////////// +// TYPES ///////////////////////////////////////////////////////////////////// +// DEFINES /////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLserviceStartupParams : public SPELLexecutorStartupParams +{ +public: //-------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor. + **//////////////////////////////////////////////////////////////////// + SPELLserviceStartupParams( const std::string& instanceId, const std::string& timeId, bool reconnecting = false ) : + SPELLexecutorStartupParams(instanceId,timeId,reconnecting) + { + int idx = instanceId.find("#"); + m_procId = instanceId.substr(0, idx); + m_timeId = timeId; + m_instanceNum = STRI(instanceId.substr(idx+1,instanceId.size()-idx)); + m_instanceId = instanceId; + m_arguments = ""; + m_condition = ""; + m_clientMode = CLIENT_MODE_UNKNOWN; + m_openMode = OPEN_MODE_UNKNOWN; + m_parentInstanceId = ""; + m_groupId = ""; + m_originId = ""; + m_parentCallingLine = 0; + m_configFile = ""; + m_contextName = ""; + m_recoveryFile = ""; + m_ipcPort = 0; + m_PID = 0; + m_reconnecting = reconnecting; + } + + ////////////////////////////////////////////////////////////////////// + /** Destructor. + **//////////////////////////////////////////////////////////////////// + ~SPELLserviceStartupParams() {}; + + // METHODS /////////////////////////////////////////////////////////////// + + std::string getProcId() const { return m_procId; }; + std::string getTimeId() const { return m_timeId; }; + std::string getInstanceId() const { return m_instanceId; }; + std::string getOriginId() const { return m_originId; }; + std::string getGroupId() const { return m_groupId; }; + unsigned int getInstanceNum() const { return m_instanceNum; }; + + pid_t getPID() const { return m_PID; }; + int getIpcPort() const { return m_ipcPort; }; + bool isReconnecting() const { return m_reconnecting; } + + std::string getArguments() const { return m_arguments; }; + std::string getCondition() const { return m_condition; }; + SPELLclientMode getClientMode() const { return m_clientMode; }; + SPELLopenMode getOpenMode() const { return m_openMode; }; + std::string getParentInstanceId() const { return m_parentInstanceId; }; + int getParentCallingLine() const { return m_parentCallingLine; }; + std::string getConfigFile() const { return m_configFile; }; + std::string getContextName() const { return m_contextName; }; + std::string getRecoveryFile() const { return m_recoveryFile; }; + + void setPID( pid_t pid ) { m_PID = pid; }; + void setIpcPort( int ipcPort ) { m_ipcPort = ipcPort; }; + void setArguments( const std::string& arguments ) { m_arguments = arguments; }; + void setCondition( const std::string& condition ) { m_condition = condition; }; + void setClientMode( const SPELLclientMode& mode ) { m_clientMode = mode; }; + void setOpenMode( const SPELLopenMode& mode ) { m_openMode = mode; }; + void setParentInstanceId( const std::string& parentInstanceId ) { m_parentInstanceId = parentInstanceId; }; + void setGroupId( const std::string& groupId ) { m_groupId = groupId; }; + void setOriginId( const std::string& originId ) { m_originId = originId; }; + void setParentCallingLine( int lineNo ) { m_parentCallingLine = lineNo; }; + void setConfigFile( const std::string& configFile ) { m_configFile = configFile; }; + void setContextName( const std::string& ctxName ) { m_contextName = ctxName; }; + void setRecoveryFile( const std::string& recoveryFile ) { m_recoveryFile = recoveryFile; }; + +private: //------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // STATIC //////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + // DATA MEMBERS ////////////////////////////////////////////////////////// + +}; + +/*@}*/ +#endif diff --git a/include/SPELL_CTX/SPELLsharedData.H b/include/SPELL_CTX/SPELLsharedData.H index 31ba17d..8011f5f 100644 --- a/include/SPELL_CTX/SPELLsharedData.H +++ b/include/SPELL_CTX/SPELLsharedData.H @@ -5,7 +5,7 @@ // DESCRIPTION: Shared data blackboard // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -161,7 +161,7 @@ public: //-------------------------------------------------------------------- protected: //----------------------------------------------------------------- - friend class SPELLclientInterestList; + //friend class SPELLclientInterestList; // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// diff --git a/include/SPELL_CTX/SPELLsharedDataOperation.H b/include/SPELL_CTX/SPELLsharedDataOperation.H index dd181cc..afe09eb 100644 --- a/include/SPELL_CTX/SPELLsharedDataOperation.H +++ b/include/SPELL_CTX/SPELLsharedDataOperation.H @@ -5,7 +5,7 @@ // DESCRIPTION: Definition of the shared data operations // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_DTA/SPELLdtaContainer.H b/include/SPELL_DTA/SPELLdtaContainer.H index 09f8f80..7c05ac8 100644 --- a/include/SPELL_DTA/SPELLdtaContainer.H +++ b/include/SPELL_DTA/SPELLdtaContainer.H @@ -5,7 +5,7 @@ // DESCRIPTION: Data variable container implementation // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_DTA/SPELLdtaContainerObject.H b/include/SPELL_DTA/SPELLdtaContainerObject.H index ae7c792..6c65183 100644 --- a/include/SPELL_DTA/SPELLdtaContainerObject.H +++ b/include/SPELL_DTA/SPELLdtaContainerObject.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL data dictionary // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_DTA/SPELLdtaVariable.H b/include/SPELL_DTA/SPELLdtaVariable.H index 2b3047c..500ef67 100644 --- a/include/SPELL_DTA/SPELLdtaVariable.H +++ b/include/SPELL_DTA/SPELLdtaVariable.H @@ -5,7 +5,7 @@ // DESCRIPTION: Data variable implementation // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_DTA/SPELLdtaVariableObject.H b/include/SPELL_DTA/SPELLdtaVariableObject.H index 0040be3..dd02d3e 100644 --- a/include/SPELL_DTA/SPELLdtaVariableObject.H +++ b/include/SPELL_DTA/SPELLdtaVariableObject.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL variable // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLastAnalyzer.H b/include/SPELL_EXC/SPELLastAnalyzer.H index 54aa0a8..dd2bacb 100644 --- a/include/SPELL_EXC/SPELLastAnalyzer.H +++ b/include/SPELL_EXC/SPELLastAnalyzer.H @@ -6,7 +6,7 @@ // procedure execution. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLbreakpoint.H b/include/SPELL_EXC/SPELLbreakpoint.H index 13e1a2f..058d71f 100644 --- a/include/SPELL_EXC/SPELLbreakpoint.H +++ b/include/SPELL_EXC/SPELLbreakpoint.H @@ -5,7 +5,7 @@ // DESCRIPTION: Management of breakpoints in the current procedure // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLbreakpointType.H b/include/SPELL_EXC/SPELLbreakpointType.H index d3dd559..8820a66 100644 --- a/include/SPELL_EXC/SPELLbreakpointType.H +++ b/include/SPELL_EXC/SPELLbreakpointType.H @@ -5,7 +5,7 @@ // DESCRIPTION: Types of breakpoints // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLbytecode.H b/include/SPELL_EXC/SPELLbytecode.H index 67eab6a..2211a32 100644 --- a/include/SPELL_EXC/SPELLbytecode.H +++ b/include/SPELL_EXC/SPELLbytecode.H @@ -6,7 +6,7 @@ // that affect the executor features at runtime. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -28,6 +28,11 @@ #ifndef __SPELL_BCODE_H__ #define __SPELL_BCODE_H__ +#ifndef JUMP_IF_TRUE +#define JUMP_IF_TRUE JUMP_IF_TRUE_OR_POP +#define JUMP_IF_FALSE JUMP_IF_FALSE_OR_POP +#endif + // FILES TO INCLUDE //////////////////////////////////////////////////////// // System includes --------------------------------------------------------- // Local includes ---------------------------------------------------------- diff --git a/include/SPELL_EXC/SPELLcallstack.H b/include/SPELL_EXC/SPELLcallstack.H index 9b62aa9..1af56e6 100644 --- a/include/SPELL_EXC/SPELLcallstack.H +++ b/include/SPELL_EXC/SPELLcallstack.H @@ -5,7 +5,7 @@ // DESCRIPTION: Call stack model. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -90,7 +90,7 @@ public: //-------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** \see SPELLcallstackIF. **//////////////////////////////////////////////////////////////////// - const std::string& getStack(); + const std::string getStack(); ////////////////////////////////////////////////////////////////////// /** \see SPELLcallstackIF. @@ -105,7 +105,7 @@ public: //-------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** \see SPELLcallstackIF. **//////////////////////////////////////////////////////////////////// - const std::string& getCodeName(); + const std::string getCodeName(); ////////////////////////////////////////////////////////////////////// /** \see SPELLcallstackIF. diff --git a/include/SPELL_EXC/SPELLcallstackIF.H b/include/SPELL_EXC/SPELLcallstackIF.H index 79c022e..cebb586 100644 --- a/include/SPELL_EXC/SPELLcallstackIF.H +++ b/include/SPELL_EXC/SPELLcallstackIF.H @@ -5,7 +5,7 @@ // DESCRIPTION: Call stack interface. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -85,7 +85,7 @@ public: //-------------------------------------------------------------------- * * \returns The current callstack string. **//////////////////////////////////////////////////////////////////// - virtual const std::string& getStack() = 0; + virtual const std::string getStack() = 0; ////////////////////////////////////////////////////////////////////// /** Obtain the current callstack string. @@ -106,7 +106,7 @@ public: //-------------------------------------------------------------------- * * \returns The current code name string. **//////////////////////////////////////////////////////////////////// - virtual const std::string& getCodeName() = 0; + virtual const std::string getCodeName() = 0; ////////////////////////////////////////////////////////////////////// /** Set the step over mode. diff --git a/include/SPELL_EXC/SPELLchildManager.H b/include/SPELL_EXC/SPELLchildManager.H index 7f14e24..f1ca33d 100644 --- a/include/SPELL_EXC/SPELLchildManager.H +++ b/include/SPELL_EXC/SPELLchildManager.H @@ -5,7 +5,7 @@ // DESCRIPTION: Child procedure controller. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLcodeTreeLine.H b/include/SPELL_EXC/SPELLcodeTreeLine.H index caa4716..c060247 100644 --- a/include/SPELL_EXC/SPELLcodeTreeLine.H +++ b/include/SPELL_EXC/SPELLcodeTreeLine.H @@ -5,7 +5,7 @@ // DESCRIPTION: Code tree line model implementation // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLcodeTreeLineIF.H b/include/SPELL_EXC/SPELLcodeTreeLineIF.H index f8c6adf..9f4765d 100644 --- a/include/SPELL_EXC/SPELLcodeTreeLineIF.H +++ b/include/SPELL_EXC/SPELLcodeTreeLineIF.H @@ -5,7 +5,7 @@ // DESCRIPTION: Code tree line interface definition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLcodeTreeNode.H b/include/SPELL_EXC/SPELLcodeTreeNode.H index 44b022c..69c3b97 100644 --- a/include/SPELL_EXC/SPELLcodeTreeNode.H +++ b/include/SPELL_EXC/SPELLcodeTreeNode.H @@ -5,7 +5,7 @@ // DESCRIPTION: Code tree node implementation // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLcodeTreeNodeIF.H b/include/SPELL_EXC/SPELLcodeTreeNodeIF.H index 112ef22..5f4422b 100644 --- a/include/SPELL_EXC/SPELLcodeTreeNodeIF.H +++ b/include/SPELL_EXC/SPELLcodeTreeNodeIF.H @@ -5,7 +5,7 @@ // DESCRIPTION: Code tree node interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLcommand.H b/include/SPELL_EXC/SPELLcommand.H index 13c9feb..e64423d 100644 --- a/include/SPELL_EXC/SPELLcommand.H +++ b/include/SPELL_EXC/SPELLcommand.H @@ -5,7 +5,7 @@ // DESCRIPTION: Executor command definition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -86,6 +86,8 @@ ExecutorCommand; #define CMD_ACTION "CMD_ACTION" /** Identifier for the FINISH command */ #define CMD_FINISH "CMD_FINISH" +/** Identifier for the RESOURCE DISPLAY command */ +#define CMD_RESOURCES "CMD_RESOURCES" /*@}*/ #endif diff --git a/include/SPELL_EXC/SPELLcommandMailbox.H b/include/SPELL_EXC/SPELLcommandMailbox.H index d45a9d5..c3c0c9c 100644 --- a/include/SPELL_EXC/SPELLcommandMailbox.H +++ b/include/SPELL_EXC/SPELLcommandMailbox.H @@ -6,7 +6,7 @@ // processing. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLcontroller.H b/include/SPELL_EXC/SPELLcontroller.H index 9d87f78..374057b 100644 --- a/include/SPELL_EXC/SPELLcontroller.H +++ b/include/SPELL_EXC/SPELLcontroller.H @@ -5,7 +5,7 @@ // DESCRIPTION: Controls the command processing in a separate thread. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -268,6 +268,12 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void removeControllerListener( SPELLcontrollerListener* listener ); + void refreshStatus(); + + ////////////////////////////////////////////////////////////////////// + /** Inject a information event message to GCS + **//////////////////////////////////////////////////////////////////// + void raiseInformationEventToGCS( const std::string& message ); // DATA MEMBERS ////////////////////////////////////////////////////////// protected: //----------------------------------------------------------------- diff --git a/include/SPELL_EXC/SPELLcontrollerIF.H b/include/SPELL_EXC/SPELLcontrollerIF.H index b863230..885c4a0 100644 --- a/include/SPELL_EXC/SPELLcontrollerIF.H +++ b/include/SPELL_EXC/SPELLcontrollerIF.H @@ -5,7 +5,7 @@ // DESCRIPTION: Defines the controller interface. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -253,6 +253,13 @@ public: //-------------------------------------------------------------------- /** Remove a controller listener **//////////////////////////////////////////////////////////////////// virtual void removeControllerListener( SPELLcontrollerListener* listener ) {;}; + + virtual void refreshStatus() {;}; + + ////////////////////////////////////////////////////////////////////// + /** Inject a information event message to GCS + **//////////////////////////////////////////////////////////////////// + virtual void raiseInformationEventToGCS( const std::string& message ) = 0; }; /*@}*/ diff --git a/include/SPELL_EXC/SPELLcontrollerListener.H b/include/SPELL_EXC/SPELLcontrollerListener.H index 1fec2cb..d56caf5 100644 --- a/include/SPELL_EXC/SPELLcontrollerListener.H +++ b/include/SPELL_EXC/SPELLcontrollerListener.H @@ -5,7 +5,7 @@ // DESCRIPTION: Controller listener interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLdispatchListener.H b/include/SPELL_EXC/SPELLdispatchListener.H index 7c4a1cd..534a7bc 100644 --- a/include/SPELL_EXC/SPELLdispatchListener.H +++ b/include/SPELL_EXC/SPELLdispatchListener.H @@ -5,7 +5,7 @@ // DESCRIPTION: Dispatch listener interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLexecutionMode.H b/include/SPELL_EXC/SPELLexecutionMode.H index 7302303..7ec92f4 100644 --- a/include/SPELL_EXC/SPELLexecutionMode.H +++ b/include/SPELL_EXC/SPELLexecutionMode.H @@ -5,7 +5,7 @@ // DESCRIPTION: Defines the diferent execution modes. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLexecutionModel.H b/include/SPELL_EXC/SPELLexecutionModel.H index af74db4..33f6708 100644 --- a/include/SPELL_EXC/SPELLexecutionModel.H +++ b/include/SPELL_EXC/SPELLexecutionModel.H @@ -5,7 +5,7 @@ // DESCRIPTION: Composite of all models and analyzers associated to a given frame. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLexecutionTrace.H b/include/SPELL_EXC/SPELLexecutionTrace.H index c1cdb21..1036253 100644 --- a/include/SPELL_EXC/SPELLexecutionTrace.H +++ b/include/SPELL_EXC/SPELLexecutionTrace.H @@ -5,7 +5,7 @@ // DESCRIPTION: Keeps trace of the visited and executed procedure lines. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLexecutor.H b/include/SPELL_EXC/SPELLexecutor.H index e7ccc45..225a30f 100644 --- a/include/SPELL_EXC/SPELLexecutor.H +++ b/include/SPELL_EXC/SPELLexecutor.H @@ -5,7 +5,7 @@ // DESCRIPTION: Singleton factory for the executor // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -108,12 +108,17 @@ public: //-------------------------------------------------------------------- * * \return The executor implementation instance. **//////////////////////////////////////////////////////////////////// - static SPELLexecutorIF& instance() + static inline SPELLexecutorIF& instance() { assert(s_instance != NULL); return *s_instance; } + static inline bool isInitialized() + { + return s_instance != NULL; + } + ////////////////////////////////////////////////////////////////////// /** Set the executor instance * diff --git a/include/SPELL_EXC/SPELLexecutorConfiguration.H b/include/SPELL_EXC/SPELLexecutorConfiguration.H index f7b4634..e0ca174 100644 --- a/include/SPELL_EXC/SPELLexecutorConfiguration.H +++ b/include/SPELL_EXC/SPELLexecutorConfiguration.H @@ -5,7 +5,7 @@ // DESCRIPTION: Executor configuration parameters // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -218,7 +218,14 @@ public: //-------------------------------------------------------------------- bool isForceTcConfirm() const { return m_forceTcConfirm; }; - + ////////////////////////////////////////////////////////////////////// + /** Obtain the force Prompt confirmation flag + * + * \returns The flag value + **//////////////////////////////////////////////////////////////////// + bool isForcePromptConfirm() const { + return m_forcePromptConfirm; + }; ////////////////////////////////////////////////////////////////////// /** Obtain the executor condition. * @@ -256,6 +263,43 @@ public: //-------------------------------------------------------------------- }; + ////////////////////////////////////////////////////////////////////// + /** set resources display is enablement. + * + * \returns The status. + **//////////////////////////////////////////////////////////////////// + void setResourcesDisplayEnabled( bool enabled ) { + m_resourcesDisplay = enabled; + }; + + ////////////////////////////////////////////////////////////////////// + /** Chekc if resource display is enabled or not. + * + * \returns The status. + **//////////////////////////////////////////////////////////////////// + const bool isResourcesDisplayEnabled() const { + return m_resourcesDisplay; + }; + + ////////////////////////////////////////////////////////////////////// + /** Obtain the local resource support flag flag. + * + * \returns The flag value + **//////////////////////////////////////////////////////////////////// + const bool isLocalResourcesSupported() const { + return m_localResourceSupport; + }; + + ////////////////////////////////////////////////////////////////////// + /** Set the local resource support flag. + * + * \param enabled IN: the flag value. + **//////////////////////////////////////////////////////////////////// + void setLocalResourcesSupported( const bool enabled ) { + m_localResourceSupport = enabled; + }; + + ////////////////////////////////////////////////////////////////////// /** Set the run-into flag. * @@ -374,6 +418,9 @@ public: //-------------------------------------------------------------------- void setForceTcConfirm( bool force ) { m_forceTcConfirm = force; }; + void setForcePromptConfirm( bool force ) { + m_forcePromptConfirm = force; + }; ////////////////////////////////////////////////////////////////////// /** Set the executor condition. @@ -544,8 +591,11 @@ private: //------------------------------------------------------------------- SPELLwsWorkingMode m_saveStateMode; /** True if watch variables is enabled */ bool m_watchVariables; + /** True if resources display is enabled */ + bool m_resourcesDisplay; /** True if all TCs should be confirmed */ bool m_forceTcConfirm; + bool m_forcePromptConfirm; /** Identifier of the controlling client if any */ std::string m_controlClient; /** Host of the controlling GUI */ @@ -556,6 +606,8 @@ private: //------------------------------------------------------------------- int m_maxVerbosity; /** Context name */ std::string m_contextName; + /** Support for local resources flag */ + bool m_localResourceSupport; }; /*@}*/ diff --git a/include/SPELL_EXC/SPELLexecutorIF.H b/include/SPELL_EXC/SPELLexecutorIF.H index c2bcc5c..9bb04ce 100644 --- a/include/SPELL_EXC/SPELLexecutorIF.H +++ b/include/SPELL_EXC/SPELLexecutorIF.H @@ -5,7 +5,7 @@ // DESCRIPTION: Executor interface definition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -38,6 +38,7 @@ #include "SPELL_EXC/SPELLcallstackIF.H" #include "SPELL_EXC/SPELLbreakpointType.H" #include "SPELL_EXC/SPELLvariableManager.H" +#include "SPELL_EXC/SPELLresourceManager.H" #include "SPELL_EXC/SPELLdispatchListener.H" @@ -136,6 +137,7 @@ public: //-------------------------------------------------------------------- * \returns The controller reference **//////////////////////////////////////////////////////////////////// virtual SPELLcontrollerIF& getController() const = 0; + virtual bool hasController() const { return true;}; ////////////////////////////////////////////////////////////////////// /** Obtain the scheduler reference @@ -156,7 +158,7 @@ public: //-------------------------------------------------------------------- * * \returns The configuration object. **//////////////////////////////////////////////////////////////////// - virtual SPELLexecutorConfig& getConfiguration() const = 0; + virtual SPELLexecutorConfig& getConfiguration() = 0; ////////////////////////////////////////////////////////////////////// /** Obtain variable manager. @@ -165,6 +167,13 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// virtual SPELLvariableManager& getVariableManager() const = 0; + ////////////////////////////////////////////////////////////////////// + /** Obtain resource manager. + * + * \returns The resource manager object. + **//////////////////////////////////////////////////////////////////// + virtual SPELLresourceManager& getResourceManager() const = 0; + ////////////////////////////////////////////////////////////////////// /** Obtain execution frame. * @@ -374,7 +383,7 @@ public: //-------------------------------------------------------------------- * \param force IN: the flag value **//////////////////////////////////////////////////////////////////// virtual void setForceTcConfirm( const bool force ) = 0; - + virtual void setForcePromptConfirm( const bool force ) = 0; // ******************************************************************* // LANGUAGE INTERLOCK // ******************************************************************* @@ -515,6 +524,7 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// virtual void displayStage( const std::string& id, const std::string& title ) = 0; + virtual void refreshStatus() {;}; }; /*@}*/ diff --git a/include/SPELL_EXC/SPELLexecutorImpl.H b/include/SPELL_EXC/SPELLexecutorImpl.H index 0e62777..2a34ee4 100644 --- a/include/SPELL_EXC/SPELLexecutorImpl.H +++ b/include/SPELL_EXC/SPELLexecutorImpl.H @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the Executor. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -113,6 +113,7 @@ public: //-------------------------------------------------------------------- /** \see SPELLexecutorIF. **//////////////////////////////////////////////////////////////////// SPELLcontrollerIF& getController() const { return *m_controller; }; + bool hasController() const { return m_controller != NULL; }; ////////////////////////////////////////////////////////////////////// /** \see SPELLexecutorIF. @@ -127,13 +128,18 @@ public: //-------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** \see SPELLexecutorIF. **//////////////////////////////////////////////////////////////////// - SPELLexecutorConfig& getConfiguration() const; + SPELLexecutorConfig& getConfiguration(); ////////////////////////////////////////////////////////////////////// /** \see SPELLexecutorIF. **//////////////////////////////////////////////////////////////////// SPELLvariableManager& getVariableManager() const { return *m_varManager; }; + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLresourceManager& getResourceManager() const { return *m_resourceManager; }; + ////////////////////////////////////////////////////////////////////// /** \see SPELLexecutorIF. **//////////////////////////////////////////////////////////////////// @@ -286,7 +292,7 @@ public: //-------------------------------------------------------------------- /** \see SPELLexecutorIF. **//////////////////////////////////////////////////////////////////// void setForceTcConfirm( const bool force ); - + void setForcePromptConfirm( const bool force ); // ******************************************************************* // LANGUAGE INTERLOCK // ******************************************************************* @@ -377,6 +383,7 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void displayStage( const std::string& id, const std::string& title ); + void refreshStatus(); // DATA MEMBERS ////////////////////////////////////////////////////////// protected: //----------------------------------------------------------------- @@ -524,9 +531,12 @@ private: //------------------------------------------------------------------- /** Change the force TC flag on the adapter layer **//////////////////////////////////////////////////////////////////// void setForceTcConfirmInternal( bool force ); + void setForcePromptConfirmInternal( bool force ); // DATA MEMBERS ////////////////////////////////////////////////////////// + /** Empty configuration */ + SPELLexecutorConfig m_emptyConfig; /** True if the initial configuration parameters have been set */ bool m_initialized; /** Holds the procedure instance identifier */ @@ -570,6 +580,8 @@ private: //------------------------------------------------------------------- SPELLimportChecker m_importChecker; /** Holds the variable manager */ SPELLvariableManager* m_varManager; + /** Holds the resource manager */ + SPELLresourceManager* m_resourceManager; /** Command synchronization lock */ SPELLmutex m_cmdLock; diff --git a/include/SPELL_EXC/SPELLexecutorStatus.H b/include/SPELL_EXC/SPELLexecutorStatus.H index 711ae6b..14f161e 100644 --- a/include/SPELL_EXC/SPELLexecutorStatus.H +++ b/include/SPELL_EXC/SPELLexecutorStatus.H @@ -5,7 +5,7 @@ // DESCRIPTION: Executor status definition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLexecutorUtils.H b/include/SPELL_EXC/SPELLexecutorUtils.H index a78ecc2..bf63ccc 100644 --- a/include/SPELL_EXC/SPELLexecutorUtils.H +++ b/include/SPELL_EXC/SPELLexecutorUtils.H @@ -5,7 +5,7 @@ // DESCRIPTION: Executor utilities // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLframeManager.H b/include/SPELL_EXC/SPELLframeManager.H index f186e69..6567268 100644 --- a/include/SPELL_EXC/SPELLframeManager.H +++ b/include/SPELL_EXC/SPELLframeManager.H @@ -5,7 +5,7 @@ // DESCRIPTION: Operations in relation with the current Python frame (runtime) // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -30,6 +30,7 @@ // FILES TO INCLUDE //////////////////////////////////////////////////////// // Local includes ---------------------------------------------------------- #include "SPELL_EXC/SPELLexecutionModel.H" +#include "SPELL_EXC/SPELLresourceMonitor.H" #include "SPELL_EXC/SPELLexecutionTrace.H" #include "SPELL_EXC/SPELLcallstackIF.H" #include "SPELL_EXC/SPELLbreakpoint.H" @@ -94,7 +95,7 @@ public: //-------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** Destructor. **//////////////////////////////////////////////////////////////////// - ~SPELLframeManager(); + virtual ~SPELLframeManager(); // METHODS /////////////////////////////////////////////////////////////// @@ -130,6 +131,13 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// SPELLexecutionModel& getModel( const std::string& code_id ); + ////////////////////////////////////////////////////////////////////// + /** Get the resources monitor. + * + * \return Reference to the resources monitor. + **//////////////////////////////////////////////////////////////////// + SPELLresourceMonitor& getResourceMonitor() { return m_resourceMonitor; }; + ////////////////////////////////////////////////////////////////////// /** Replay the frame structure in the given stack **//////////////////////////////////////////////////////////////////// @@ -332,7 +340,7 @@ protected: //------------------------------------------------------------------- // METHODS /////////////////////////////////////////////////////////////// private: //------------------------------------------------------------------- - + friend class SPELLserviceFrameManager; // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// // TYPES ///////////////////////////////////////////////////////////////// @@ -356,7 +364,7 @@ private: //------------------------------------------------------------------- * \throws SPELLcoreException if the file cannot be found, or the * compilation fails. **//////////////////////////////////////////////////////////////////// - void compile(); + virtual void compile(); ////////////////////////////////////////////////////////////////////// /** Compile the given script and obtain the bytecode. @@ -368,7 +376,7 @@ private: //------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** Create initial frame out of the current code **//////////////////////////////////////////////////////////////////// - void createInitialFrame(); + virtual void createInitialFrame(); ////////////////////////////////////////////////////////////////////// /** Create frame model for a new frame @@ -401,7 +409,7 @@ private: //------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** Update data for watch of variables when a new frame arrives **//////////////////////////////////////////////////////////////////// - void updateVariables( PyFrameObject* frame ); + virtual void updateVariables( PyFrameObject* frame ); ////////////////////////////////////////////////////////////////////// /** Update SPELL builtins using the given frames @@ -435,6 +443,8 @@ private: //------------------------------------------------------------------- PyObject* m_definitions; /** Holds the currently active execution model */ SPELLexecutionModel* m_model; + /** Monitor of resources */ + SPELLresourceMonitor m_resourceMonitor; /** Holds the AST analyzer */ SPELLastAnalyzer m_ast; /** Map of model objects per code object */ diff --git a/include/SPELL_EXC/SPELLgoto.H b/include/SPELL_EXC/SPELLgoto.H index af804a7..b826750 100644 --- a/include/SPELL_EXC/SPELLgoto.H +++ b/include/SPELL_EXC/SPELLgoto.H @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the Goto mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLimportChecker.H b/include/SPELL_EXC/SPELLimportChecker.H index 143f084..782d01e 100644 --- a/include/SPELL_EXC/SPELLimportChecker.H +++ b/include/SPELL_EXC/SPELLimportChecker.H @@ -5,7 +5,7 @@ // DESCRIPTION: Special check for import statements // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLinterpreter.H b/include/SPELL_EXC/SPELLinterpreter.H index 15e13fe..0f796a8 100644 --- a/include/SPELL_EXC/SPELLinterpreter.H +++ b/include/SPELL_EXC/SPELLinterpreter.H @@ -5,7 +5,7 @@ // DESCRIPTION: Main entry point of the executor. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLlnotab.H b/include/SPELL_EXC/SPELLlnotab.H index 3177db1..1709abb 100644 --- a/include/SPELL_EXC/SPELLlnotab.H +++ b/include/SPELL_EXC/SPELLlnotab.H @@ -5,7 +5,7 @@ // DESCRIPTION: LNotab analyzer. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLresourceInfo.H b/include/SPELL_EXC/SPELLresourceInfo.H new file mode 100644 index 0000000..56e0956 --- /dev/null +++ b/include/SPELL_EXC/SPELLresourceInfo.H @@ -0,0 +1,115 @@ +// ################################################################################ +// FILE : SPELLresourceInfo.H +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Procedure resource information +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_RESOURCE_INFO_H__ +#define __SPELL_RESOURCE_INFO_H__ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// Local includes ---------------------------------------------------------- +// Project includes -------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" + +/** \addtogroup SPELL_EXC */ +/*@{*/ + + +// FORWARD REFERENCES ////////////////////////////////////////////////////// +// TYPES /////////////////////////////////////////////////////////////////// +// DEFINES ///////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief Resource information + ** +**//////////////////////////////////////////////////////////////////////////// +typedef struct SPELLresourceInfo_ +{ + SPELLresourceInfo_() + { + resourceName = ""; + resourceType = ""; + resourceGlobalValue = ""; + resourceLocalValue = ""; + resourceValueRange.clear(); + resourceGCSName = ""; + } + + SPELLresourceInfo_( const std::string& name, + const std::string& type, + const std::string& globalValue, + const std::string& localValue, + const std::vector >& valueRange, + const std::string& gcsName ) + { + resourceName = name; + resourceType = type; + resourceGlobalValue = globalValue; + resourceLocalValue = localValue; + resourceValueRange.assign(valueRange.begin(), valueRange.end()); + resourceGCSName = gcsName; + } + + SPELLresourceInfo_& operator=( const SPELLresourceInfo_& other ) + { + if (this != &other) + { + resourceName = other.resourceName; + resourceType = other.resourceType; + resourceGlobalValue = other.resourceGlobalValue; + resourceLocalValue = other.resourceLocalValue; + resourceValueRange.assign(other.resourceValueRange.begin(), other.resourceValueRange.end()); + resourceGCSName = other.resourceGCSName; + } + return *this; + } + + SPELLresourceInfo_( const SPELLresourceInfo_& other ) + { + resourceName = other.resourceName; + resourceType = other.resourceType; + resourceGlobalValue = other.resourceGlobalValue; + resourceLocalValue = other.resourceLocalValue; + resourceValueRange.assign(other.resourceValueRange.begin(), other.resourceValueRange.end()); + resourceGCSName = other.resourceGCSName; + } + + /** Holds the resource name */ + std::string resourceName; + /** Holds the resource type string */ + std::string resourceType; + /** Holds the resource global value */ + std::string resourceGlobalValue; + /** Holds the resource local value */ + std::string resourceLocalValue; + /** List of values that the resource can have. Empty means any value */ + std::vector > resourceValueRange; + /** Holds the resource GCS name */ + std::string resourceGCSName; +} +SPELLresourceInfo; + +/*@}*/ +#endif diff --git a/include/SPELL_EXC/SPELLresourceManager.H b/include/SPELL_EXC/SPELLresourceManager.H new file mode 100644 index 0000000..5cf6d36 --- /dev/null +++ b/include/SPELL_EXC/SPELLresourceManager.H @@ -0,0 +1,147 @@ +// ################################################################################ +// FILE : SPELLresourceManager.H +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Manager of procedure runtime resources +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_RESOURCE_MANAGER_H__ +#define __SPELL_RESOURCE_MANAGER_H__ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +// Local includes ---------------------------------------------------------- +#include "SPELL_EXC/SPELLframeManager.H" +// Project includes -------------------------------------------------------- +#include "SPELL_SYN/SPELLqueue.H" + +/** \addtogroup SPELL_EXC */ +/*@{*/ + + +// FORWARD REFERENCES ////////////////////////////////////////////////////// +// TYPES /////////////////////////////////////////////////////////////////// +// DEFINES ///////////////////////////////////////////////////////////////// + +#define RESOURCE_MONITOR_CHANGE_RESOURCE "changeResource" +#define RESOURCE_MONITOR_GET_RESOURCES "getResources" + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief Resource manager + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLresourceManager +{ +public: //-------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor. + **//////////////////////////////////////////////////////////////////// + SPELLresourceManager( SPELLframeManager& frameManager ); + + ////////////////////////////////////////////////////////////////////// + /** Destructor. + **//////////////////////////////////////////////////////////////////// + ~SPELLresourceManager(); + + // STATIC //////////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Enable or disable the manager. + **//////////////////////////////////////////////////////////////////// + void setEnabled( bool enabled ); + + ////////////////////////////////////////////////////////////////////// + /** Check enabled + **//////////////////////////////////////////////////////////////////// + bool isEnabled(); + + ////////////////////////////////////////////////////////////////////// + /** Analysis on demand + **//////////////////////////////////////////////////////////////////// + void analyze(); + + ////////////////////////////////////////////////////////////////////// + /** Get available resources. + * + * \return The list of resources. + **//////////////////////////////////////////////////////////////////// + void getResources(); + + ////////////////////////////////////////////////////////////////////// + /** Change a resource value. + * + * \param resource IN: the resource data. + * + **//////////////////////////////////////////////////////////////////// + void changeResource( SPELLresourceInfo& resource ); + + ////////////////////////////////////////////////////////////////////// + /** Check if the internal executor status is valid to process + * resource manipulation. + * + * \returns True if the status is valid. + **//////////////////////////////////////////////////////////////////// + bool isStatusValid(); + + ////////////////////////////////////////////////////////////////////// + /** Call resource monitor method. + * + * \param moitorTask IN: name of the method to call. + * + **//////////////////////////////////////////////////////////////////// + void callResourceMonitorFromClient(std::string monitorTask); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + +protected: //----------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + // DATA MEMBERS ////////////////////////////////////////////////////////// + +private: //------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + // DATA MEMBERS ////////////////////////////////////////////////////////// + /** Holds reference to the frame manager */ + SPELLframeManager& m_frameManager; + /** Queue to store resources to change */ + SPELLqueue m_changeResourceQueue; +}; + +/*@}*/ +#endif diff --git a/include/SPELL_EXC/SPELLresourceMonitor.H b/include/SPELL_EXC/SPELLresourceMonitor.H new file mode 100644 index 0000000..b924b4d --- /dev/null +++ b/include/SPELL_EXC/SPELLresourceMonitor.H @@ -0,0 +1,199 @@ +// ################################################################################ +// FILE : SPELLresourceMonitor.H +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Monitor for runtime procedure resources +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_RESOURCE_MONITOR_H__ +#define __SPELL_RESOURCE_MONITOR_H__ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +// Local includes ---------------------------------------------------------- +#include "SPELL_EXC/SPELLresourceInfo.H" +// Project includes -------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" + +/** \addtogroup SPELL_EXC */ +/*@{*/ + + +// FORWARD REFERENCES ////////////////////////////////////////////////////// +// TYPES /////////////////////////////////////////////////////////////////// +// DEFINES ///////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief Listener for resource changes. + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLresourceChangeListener +{ +public: + + ////////////////////////////////////////////////////////////////////// + /** Notify about a resource change. + * + * \param changed IN: list of changed resources. + * + **//////////////////////////////////////////////////////////////////// + void resourceChanged( const std::vector& changed ); + + ////////////////////////////////////////////////////////////////////// + /** Notify about a resource list. + * + * \param changed IN: list of resources. + * + **//////////////////////////////////////////////////////////////////// + void resourceList( const std::vector& resources ); +}; + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief Monitor of resources + ** + ** \par Description and usage: + ** + ** Used to implement the display-of-resurces mechanism + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLresourceMonitor: public SPELLresourceChangeListener +{ +public: //-------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + + /** Type for resource name-value map */ + typedef std::map ResourceMap; + + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor. + **//////////////////////////////////////////////////////////////////// + SPELLresourceMonitor( SPELLresourceChangeListener* listener ); + + ////////////////////////////////////////////////////////////////////// + /** Destructor. + **//////////////////////////////////////////////////////////////////// + ~SPELLresourceMonitor(); + + // STATIC //////////////////////////////////////////////////////////////// + + static bool s_enabled; + + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Get available resources. + * + * \return The list of resources. + **//////////////////////////////////////////////////////////////////// + void getResources(); + + ////////////////////////////////////////////////////////////////////// + /** Change resource + * + * \param resource IN: the resource to change. + * + **//////////////////////////////////////////////////////////////////// + void changeResource( SPELLresourceInfo& resource ); + + ////////////////////////////////////////////////////////////////////// + /** Get resource value. + * + * \param resourceName IN: resource name + * + * \return The resource information. + **//////////////////////////////////////////////////////////////////// + void getResource( SPELLresourceInfo& resource ); + + ////////////////////////////////////////////////////////////////////// + /** Analyze resource dictionary to detect changes. + **//////////////////////////////////////////////////////////////////// + void analyze(); + + ////////////////////////////////////////////////////////////////////// + /** Initialize the resource dictionary + **//////////////////////////////////////////////////////////////////// + void initialize(); + +protected: //----------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + // DATA MEMBERS ////////////////////////////////////////////////////////// + +private: //------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Retrieve existing resources, local or global + * \param resultingMap OUT: map of resource information to fill. + * \param isLocal IN: whether to retrieve local resources (true) or global (false). + * \param onlyLocal IN: whether to ONLY retrieve the values of local resources + * Neither the type, global value or ValueRange are retrieved + * + **//////////////////////////////////////////////////////////////////// + void retrieveResources( ResourceMap &resultingMap, bool onlyLocal=false ); + + ////////////////////////////////////////////////////////////////////// + /** Retrieve resource value range and name map + **//////////////////////////////////////////////////////////////////// + void retrieveResourceValueRangeAndNameMap( ); + + ////////////////////////////////////////////////////////////////////// + /** Check if a resource should not be monitored + **//////////////////////////////////////////////////////////////////// + bool shouldDiscard( const std::string& name ); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + + /** Reference to the frame */ + PyFrameObject* m_frame; + /** Scope name */ + std::string m_scopeName; + /** Initialized flag */ + bool m_initialized; + /** Reference to the single change listener */ + SPELLresourceChangeListener* m_listener; + /** Map of resources */ + ResourceMap m_resources; + /** Resources accepted values */ + std::map > > m_resourceAcceptedValues; + /** Resources SPELL/GCS name mapping */ + std::map m_resourceNameMapping; +}; + +/*@}*/ +#endif diff --git a/include/SPELL_EXC/SPELLscheduleCondition.H b/include/SPELL_EXC/SPELLscheduleCondition.H index 3ff3d93..86b7487 100644 --- a/include/SPELL_EXC/SPELLscheduleCondition.H +++ b/include/SPELL_EXC/SPELLscheduleCondition.H @@ -5,7 +5,7 @@ // DESCRIPTION: Defines a scheduler condition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -92,6 +92,7 @@ public: //-------------------------------------------------------------------- period.set(0,0,false); message = ""; m_tmVerificationExpression = NULL; + promptUser = false; } ////////////////////////////////////////////////////////////////////// diff --git a/include/SPELL_EXC/SPELLscheduler.H b/include/SPELL_EXC/SPELLscheduler.H index 841e858..ab1881a 100644 --- a/include/SPELL_EXC/SPELLscheduler.H +++ b/include/SPELL_EXC/SPELLscheduler.H @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor scheduler. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -163,6 +163,11 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void setPromptWarningDelay( unsigned int secs ); + ////////////////////////////////////////////////////////////////////// + /** Inject a warning event message to GCS + **//////////////////////////////////////////////////////////////////// + void raiseWarningEventToGCS( const std::string& message ); + // DATA MEMBERS ////////////////////////////////////////////////////////// protected: //----------------------------------------------------------------- @@ -188,6 +193,11 @@ private: //------------------------------------------------------------------- // LIFECYCLE ///////////////////////////////////////////////////////////// // METHODS /////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + /** Finish a wait condition (no check lock) + **//////////////////////////////////////////////////////////////////// + void finishWaitInternal( bool setStatus, bool keepLock ); + ////////////////////////////////////////////////////////////////////// /** Release the lock which may be blocking procedure execution **//////////////////////////////////////////////////////////////////// diff --git a/include/SPELL_EXC/SPELLschedulerIF.H b/include/SPELL_EXC/SPELLschedulerIF.H index 507df79..74df657 100644 --- a/include/SPELL_EXC/SPELLschedulerIF.H +++ b/include/SPELL_EXC/SPELLschedulerIF.H @@ -5,7 +5,7 @@ // DESCRIPTION: Defines the interface of the executor scheduler // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -172,6 +172,11 @@ public: //-------------------------------------------------------------------- /** Set default delay for prompt warnings **//////////////////////////////////////////////////////////////////// virtual void setPromptWarningDelay( unsigned int secs ) = 0; + + ////////////////////////////////////////////////////////////////////// + /** Inject a warning event message to GCS + **//////////////////////////////////////////////////////////////////// + virtual void raiseWarningEventToGCS( const std::string& message ) = 0; }; /*@}*/ diff --git a/include/SPELL_EXC/SPELLserviceImpl.H b/include/SPELL_EXC/SPELLserviceImpl.H new file mode 100644 index 0000000..7061d69 --- /dev/null +++ b/include/SPELL_EXC/SPELLserviceImpl.H @@ -0,0 +1,599 @@ +// ################################################################################ +// FILE : SPELLexecutorImpl.H +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the Executor. +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_SERVICE_IMPL_H__ +#define __SPELL_SERVICE_IMPL_H__ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// Local includes ---------------------------------------------------------- +#include "SPELL_EXC/SPELLexecutorIF.H" +#include "SPELL_EXC/SPELLimportChecker.H" +#include "SPELL_EXC/SPELLbreakpointType.H" +// Project includes -------------------------------------------------------- +#include "SPELL_CFG/SPELLbrowsableLibMode.H" +// System includes --------------------------------------------------------- + + +/** \addtogroup SPELL_EXC */ +/*@{*/ + + +// FORWARD REFERENCES ////////////////////////////////////////////////////// +// TYPES /////////////////////////////////////////////////////////////////// +// DEFINES ///////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief Main implementation of the procedure executor + ** + ** \par Description and usage: + ** + ** Main implementation of the SPELLexecutorIF interface for the SPELL + ** Executor process. + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLserviceImpl: public SPELLexecutorIF +{ +public: //-------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor + **//////////////////////////////////////////////////////////////////// + SPELLserviceImpl(); + + ////////////////////////////////////////////////////////////////////// + /** Destructor. + **//////////////////////////////////////////////////////////////////// + virtual ~SPELLserviceImpl(); + + // STATIC //////////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + // ******************************************************************* + // INITIALIZATION + // ******************************************************************* + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void initialize( SPELLcif* cif, + SPELLcontrollerIF* controller, + SPELLschedulerIF* scheduler, + SPELLcallstackIF* callstack, + SPELLframeManager* frameManager ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void prepare( const std::string& serviceId, const SPELLcontextConfig& ctxConfig ); + + // ******************************************************************* + // COMPONENT ACCESSORS + // ******************************************************************* + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLcif& getCIF() const { return *m_cif; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLcallstackIF& getCallstack() const { return *m_callstack; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLcontrollerIF& getController() const { return *m_controller; }; + bool hasController() const { return m_controller != NULL; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLschedulerIF& getScheduler() const { return *m_scheduler; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLchildManager& getChildManager() const { return *m_childMgr; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLexecutorConfig& getConfiguration(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLvariableManager& getVariableManager() const { return *m_varManager; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLresourceManager& getResourceManager() const { return *m_resourceManager; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + SPELLframeManager& getFrameManager() const { return *m_frameManager; }; + + // ******************************************************************* + // EXECUTION ENTRY POINTS + // ******************************************************************* + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void execute(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void recover(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void finalize(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void save(); + + // ******************************************************************* + // MAIN EXECUTION CONTROL + // ******************************************************************* + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void addDispatchListener( SPELLdispatchListener* listener ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void removeDispatchListener( SPELLdispatchListener* listener ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + int dispatch( PyObject* obj, PyFrameObject* frame, int what, PyObject* args ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void command( const ExecutorCommand& cmd, const bool high_priority ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void abort( const std::string& message, bool systemAborted ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void finish( const std::string& message ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void pause(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void interrupt(); + + // ******************************************************************* + // STATUS INFORMATION + // ******************************************************************* + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const SPELLexecutorStatus getStatus() const; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const std::string getContextName() const; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const std::string getInstanceId() const; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setControllingClient( const std::string& clientId ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setControllingHost( const std::string& hostName ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const std::string getControllingHost() const; + + // ******************************************************************* + // EXECUTION CONFIGURATION PARAMETERS + // ******************************************************************* + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setProcedurePath( const std::string& servicePath ) { m_servicePath = servicePath; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setLibraryPath( const std::string& libPath ) { m_libPath = libPath; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setRunInto( const bool enabled ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setByStep( const bool enabled ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setBrowsableLib( const SPELLbrowsableLibMode& browsableLib ); + + void setBrowsableLibStr( const std::string& browsableLibStr ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setExecDelay( const int delay ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setPromptWarningDelay( const int delay ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setForceTcConfirm( const bool force ); + void setForcePromptConfirm( const bool force ); + // ******************************************************************* + // LANGUAGE INTERLOCK + // ******************************************************************* + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void processLock(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void processUnlock(); + + // ******************************************************************* + // EXECUTION MANIPULATION + // ******************************************************************* + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const bool canSkip(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const bool goNextLine(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const bool goLabel( const std::string& label, bool programmed ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const bool goLine( const int line ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const bool setBreakpoint( const std::string& file, + const unsigned int line, + const SPELLbreakpointType type ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void clearBreakpoints(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const bool runScript( const std::string& script ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void executeUserAction(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void setUserAction( const SPELLuserAction& action ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void enableUserAction( const bool enable ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void dismissUserAction(); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + const SPELLuserAction getUserAction() const { return m_userAction; }; + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void stageReached( const std::string& id, const std::string& title ); + + ////////////////////////////////////////////////////////////////////// + /** \see SPELLexecutorIF. + **//////////////////////////////////////////////////////////////////// + void displayStage( const std::string& id, const std::string& title ); + + void refreshStatus(); + // DATA MEMBERS ////////////////////////////////////////////////////////// + +protected: //----------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + /** Identifies the status after an error recovery */ + typedef enum AfterError_ + { + CANNOT_RECOVER, // Will not recover because there is no ws support + CANCEL_RECOVER, // Will not recover because the user does not want + RECOVER_SUCCESS,// Recovery ok + RECOVER_FAILED // Recovery failed + } + AfterError; + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Listener notifications + **//////////////////////////////////////////////////////////////////// + void notifyLineEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name ); + void notifyCallEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name ); + void notifyReturnEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name ); + void notifyErrorEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name ); + + ////////////////////////////////////////////////////////////////////// + /** Process a dispatched exception + * + * \return True if the dispatch processing shall not continue + **//////////////////////////////////////////////////////////////////// + bool processException( PyObject* data, int lineno ); + + ////////////////////////////////////////////////////////////////////// + /** Internal implementation of the execute() method + **//////////////////////////////////////////////////////////////////// + void executeInternal( bool reset ); + + ////////////////////////////////////////////////////////////////////// + /** By-Step implementation. If the feature is enabled and the current + * procedure line is a Step, pause the execution. + * + * \param frameLine IN: the current line in the procedure. + **//////////////////////////////////////////////////////////////////// + const bool checkByStep( const int& frameLine ); + + ////////////////////////////////////////////////////////////////////// + /** INIT step feature checker + * + * \param frameLine IN: the current line in the procedure. + * + * \returns True if the dispatching shall be aborted and control + * returned to Python side immediately. + **//////////////////////////////////////////////////////////////////// + const bool checkInitStep( const int& frameLine ); + + ////////////////////////////////////////////////////////////////////// + /** Breakpoint checker. If a breakpoint is set, pause the execution. + * + * \param file IN: current file name. + * \param lineNo IN: the current line in the procedure. + * + **//////////////////////////////////////////////////////////////////// + void checkBreakpoint( const std::string& file, unsigned int lineNo ); + + ////////////////////////////////////////////////////////////////////// + /** Error recovery implementation + * + * \returns True if the error can be recovered + **//////////////////////////////////////////////////////////////////// + const AfterError handleExecutionError(); + + ////////////////////////////////////////////////////////////////////// + /** Load execution environment data and instances + **//////////////////////////////////////////////////////////////////// + void loadExecutionEnvironment(); + + ////////////////////////////////////////////////////////////////////// + /** Load SPELL driver + **//////////////////////////////////////////////////////////////////// + void loadDriver(); + + ////////////////////////////////////////////////////////////////////// + /** Unload SPELL driver. + * + * \param shutdown IN: If true, unload completely all data. If false, + * just cleanup the driver, but do not remove it completely (this + * is handled on driver side, not in executor) + **//////////////////////////////////////////////////////////////////// + void unloadDriver( bool shutdown ); + + ////////////////////////////////////////////////////////////////////// + /** Called when the execution finishes with errors. The behavior + * depends on the recovery mechanism status and user's choice. + * + * \return True if the execution shall be started over. + **//////////////////////////////////////////////////////////////////// + bool executorFinishedWithErrors(); + + ////////////////////////////////////////////////////////////////////// + /** Called when the execution finishes sucessfully. The behavior + * depends on the user's choice. + * + * \return True if the execution shall be started over. + **//////////////////////////////////////////////////////////////////// + bool executorFinishedRight(); + + ////////////////////////////////////////////////////////////////////// + /** Called when the execution is aborted. The behavior + * depends on the user's choice. + * + * \return True if the execution shall be started over. + **//////////////////////////////////////////////////////////////////// + bool executorAborted(); + + ////////////////////////////////////////////////////////////////////// + /** Waits for the user's choice: close the procedure or reload it. + * + * \return True if the execution shall be started over. + **//////////////////////////////////////////////////////////////////// + bool reloadOrClose(); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + +private: //------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Install the calling arguments data container on the main scope. + **//////////////////////////////////////////////////////////////////// + void installCallingArguments(); + + ////////////////////////////////////////////////////////////////////// + /** Install the internal variables data container on the main scope. + **//////////////////////////////////////////////////////////////////// + void installInternalVariables(); + + ////////////////////////////////////////////////////////////////////// + /** Change the force TC flag on the adapter layer + **//////////////////////////////////////////////////////////////////// + void setForceTcConfirmInternal( bool force ); + void setForcePromptConfirmInternal( bool force ); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + + /** Empty configuration */ + SPELLexecutorConfig m_emptyConfig; + /** True if the initial configuration parameters have been set */ + bool m_initialized; + /** Holds the procedure instance identifier */ + std::string m_instanceId; + /** Holds the parent procedure, if any */ + + std::string m_parentId; + /** Holds the child procedure, if any */ + std::string m_childId; + + /** Used for dispatching filter (procedures) */ + std::string m_servicePath; + /** Used for dispatching filter (user library) */ + std::string m_libPath; + /** Output directory location */ + std::string m_outputDir; + /** Input directory location */ + std::string m_inputDir; + + /** True when the INIT step, if any, has been reached */ + bool m_initStepDone; + /** Holds the lines in the main procedure that are executed during INIT mode */ + std::list m_initLines; + + /** Holds the user action data if any */ + SPELLuserAction m_userAction; + + /** Holds the command controller */ + SPELLcontrollerIF* m_controller; + /** Holds the scheduler controller */ + SPELLschedulerIF* m_scheduler; + /** Holds the callstack model */ + SPELLcallstackIF* m_callstack; + /** Holds the reference to client interface */ + SPELLcif* m_cif; + /** Holds the child procedure manager */ + SPELLchildManager* m_childMgr; + /** Holds the execution control frame */ + SPELLframeManager* m_frameManager; + /** Holds the module import checker */ + SPELLimportChecker m_importChecker; + /** Holds the variable manager */ + SPELLvariableManager* m_varManager; + /** Holds the resource manager */ + SPELLresourceManager* m_resourceManager; + + /** Command synchronization lock */ + SPELLmutex m_cmdLock; + /** Dispatch synchronization lock */ + SPELLmutex m_dspLock; + + /** Next programmed goto target */ + std::string m_gotoTarget; + + /** Dispatch event listeners */ + SPELLdispatchListeners m_listeners; +}; + +/*@}*/ +#endif diff --git a/include/SPELL_EXC/SPELLserviceInterpreter.H b/include/SPELL_EXC/SPELLserviceInterpreter.H new file mode 100644 index 0000000..91d0d61 --- /dev/null +++ b/include/SPELL_EXC/SPELLserviceInterpreter.H @@ -0,0 +1,249 @@ +// ################################################################################ +// FILE : SPELLinterpreter.H +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Main entry point of the executor. +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_SERVICE_INTERPRETER_H__ +#define __SPELL_SERVICE_INTERPRETER_H__ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// Local includes ---------------------------------------------------------- +#include "SPELL_EXC/SPELLexecutorIF.H" +#include "SPELL_EXC/SPELLserviceImpl.H" +#include "SPELL_EXC/SPELLframeManager.H" +// Project includes -------------------------------------------------------- +// System includes --------------------------------------------------------- + + +/** \addtogroup SPELL_EXC */ +/*@{*/ + +// FORWARD REFERENCES ////////////////////////////////////////////////////// +// ENUMS /////////////////////////////////////////////////////////////////// +// TYPES /////////////////////////////////////////////////////////////////// + +/** Configuration parameters for the interpreter */ +typedef struct SPELLinterpreterConfig_ +{ + /** If true, WS is enabled and the given persistent file is used */ + bool warmstart; + /** If true, the given persistent file is used to recover status */ + bool recover; + /** If true, the given procId corresponds to a script, not a proc id */ + bool script; + /** Path to main configuration file */ + std::string configFile; + /** Procedure identifier or script path */ + std::string procId; + /** SPELL context to be used */ + std::string ctxName; + /** Context listening port */ + int ctxPort; + /** Time string to be used in generated files */ + std::string timeId; + /** If given, holds the path to the file where WS data is stored */ + std::string persis; +} +SPELLinterpreterConfig; + +// DEFINES ///////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief Encapsulates the Python interpreter framework in a single object. + ** + ** \par Description and usage: + ** + ** The interpreter is the main class of the executor + ** process. It creates all the pieces needed to execute a given script + ** or procedure. It provides also the ability of recovering a proc + ** execution by using a given WS information file. + ** + ** Singleton used in the main program function. + ** +**//////////////////////////////////////////////////////////////////////////// +class SPELLserviceInterpreter +{ +public: //-------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Destructor. + **//////////////////////////////////////////////////////////////////// + ~SPELLserviceInterpreter(); + + // STATIC //////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Access to the singleton instance + **//////////////////////////////////////////////////////////////////// + static SPELLserviceInterpreter& instance(); + + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Main interpreter program loop. Will first prepare the control + * objects (controller, scheduler, callstack, etc), \see prepareObjects + * method. Then, execution environment will be set up (\see prepareExecution + * method). If both operations are success, the methods recover() or + * execute() are invoked depending on the command line arguments of + * the executor application. Once these finish, it waits for the signal + * to cleanup all things in order to exit the executor process. + **//////////////////////////////////////////////////////////////////// + void mainLoop(); + + ////////////////////////////////////////////////////////////////////// + /** Initialize the interpreter with the given configuration + ** + ** \param config IN: Configuration data + ** \param cif IN: SPELL client interface instance to use. + **//////////////////////////////////////////////////////////////////// + void initialize( const SPELLinterpreterConfig& config, SPELLcif* cif ); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + +protected: //----------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor. + **//////////////////////////////////////////////////////////////////// + SPELLserviceInterpreter(); + + // METHODS /////////////////////////////////////////////////////////////// + // DATA MEMBERS ////////////////////////////////////////////////////////// + +private: //------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Prepare the CIF component + **//////////////////////////////////////////////////////////////////// + void prepareCIF( const SPELLcontextConfig& ctxConfig ); + + ////////////////////////////////////////////////////////////////////// + /** Recover the CIF component information + **//////////////////////////////////////////////////////////////////// + void recoverCIF( const SPELLcontextConfig& ctxConfig ); + + ////////////////////////////////////////////////////////////////////// + /** Prepare the warm start / error recovery support mechanism. It will + * build the warmstart persistence file name, create the SPELLwarmStart + * object and initialize the execution frame with their references. MAy + * fail if SPELL_DATA environment variable is not set, or the persistent + * file cannot be created. + **//////////////////////////////////////////////////////////////////// + void prepareWarmStart( const SPELLcontextConfig& ctxConfig ); + + ////////////////////////////////////////////////////////////////////// + /** If initial preparation succeeds, additional mechanisms are intialized + * configured and/or installed: + * + * 1. Install special exceptions on Python side + * 2. Install the executor instance on the SPELL registry + * 3. Install the go-to mechanism on Python side + * 4. Install the CIF instance on the SPELL registry + * 5. Get procedure and User Library search paths + * 6. Compile the procedure code and prepare the execution frame. + * + * \returns False in case of failure. + **//////////////////////////////////////////////////////////////////// + const bool prepareExecution(); + + ////////////////////////////////////////////////////////////////////// + /** Prepare objects neede for the execution of the procedure/script. + * The following steps are performed: + * + * 1. Initialize Python API + * 2. Install Log mechanism on Python side + * 3. Import SPELL framework on Python side. + * 4. Load configuration from XML files + * 5. Setup the client interface to connect to the client + * 6. Create control objects (controller, scheduler, frame, etc) + * 7. Prepare the warm start support + * 8. Initialize and configure the executor object + * 9. Start the command controller. + * + * \returns False in case of failure. + **//////////////////////////////////////////////////////////////////// + const bool prepareObjects(); + + ////////////////////////////////////////////////////////////////////// + /** Execute the script/procedure. Basically invoke the execute() method + * of the executor object and catch any error taking place. + **//////////////////////////////////////////////////////////////////// + void execute(); + + ////////////////////////////////////////////////////////////////////// + /** Recover script/procedure execution from persistent file. Invoke + * the recover() method of the executor object. + **//////////////////////////////////////////////////////////////////// + void recover(); + + ////////////////////////////////////////////////////////////////////// + /** Handle errors raised during the initialization performed by the + * prepareExecution method. + **//////////////////////////////////////////////////////////////////// + void handleStartupError(); + + // DATA MEMBERS ////////////////////////////////////////////////////////// + /** Interpreter configuration */ + SPELLinterpreterConfig m_config; + /** Executor instance */ + SPELLserviceImpl* m_serviceImpl; + /** Warm start mechanism */ + SPELLwarmStart* m_warmStart; + /** Client interface */ + SPELLcif* m_cif; + /** Execution controller */ + SPELLcontrollerIF* m_controller; + /** Execution scheduler */ + SPELLschedulerIF* m_scheduler; + /** Callstack manager */ + SPELLcallstackIF* m_callstack; + /** Execution frame */ + SPELLframeManager* m_frameManager; + /** Current procedure or file name */ + std::string m_service; + /** Current procedures path */ + std::string m_servicePath; + /** Current library path */ + std::string m_libPath; +}; + +/*@}*/ +#endif diff --git a/include/SPELL_EXC/SPELLstepOverMode.H b/include/SPELL_EXC/SPELLstepOverMode.H index adeb7eb..de295b1 100644 --- a/include/SPELL_EXC/SPELLstepOverMode.H +++ b/include/SPELL_EXC/SPELLstepOverMode.H @@ -5,7 +5,7 @@ // DESCRIPTION: Defines the step over modes // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLuserAction.H b/include/SPELL_EXC/SPELLuserAction.H index 39f511e..f7d779f 100644 --- a/include/SPELL_EXC/SPELLuserAction.H +++ b/include/SPELL_EXC/SPELLuserAction.H @@ -5,7 +5,7 @@ // DESCRIPTION: Defines a user action // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLvarInfo.H b/include/SPELL_EXC/SPELLvarInfo.H index 357897a..d355712 100644 --- a/include/SPELL_EXC/SPELLvarInfo.H +++ b/include/SPELL_EXC/SPELLvarInfo.H @@ -5,7 +5,7 @@ // DESCRIPTION: Procedure variable information // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLvariableManager.H b/include/SPELL_EXC/SPELLvariableManager.H index fc0a63c..a8c490f 100644 --- a/include/SPELL_EXC/SPELLvariableManager.H +++ b/include/SPELL_EXC/SPELLvariableManager.H @@ -5,7 +5,7 @@ // DESCRIPTION: Manager of procedure runtime variables // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_EXC/SPELLvariableMonitor.H b/include/SPELL_EXC/SPELLvariableMonitor.H index 3d4c58a..4ce695a 100644 --- a/include/SPELL_EXC/SPELLvariableMonitor.H +++ b/include/SPELL_EXC/SPELLvariableMonitor.H @@ -5,7 +5,7 @@ // DESCRIPTION: Monitor for runtime procedure variables // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_IPC/SPELLipc.H b/include/SPELL_IPC/SPELLipc.H index 42f4554..0e046b6 100644 --- a/include/SPELL_IPC/SPELLipc.H +++ b/include/SPELL_IPC/SPELLipc.H @@ -5,7 +5,7 @@ // DESCRIPTION: Inter process communication, data definitions // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_IPC/SPELLipcChannel.H b/include/SPELL_IPC/SPELLipcChannel.H index ecfa0b5..065d413 100644 --- a/include/SPELL_IPC/SPELLipcChannel.H +++ b/include/SPELL_IPC/SPELLipcChannel.H @@ -5,7 +5,7 @@ // DESCRIPTION: Inter-process communication - IPC channel // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -43,6 +43,7 @@ // FORWARD REFERENCES ////////////////////////////////////////////////////// class SPELLipcInterface; +class SPELLipcInput; // TYPES /////////////////////////////////////////////////////////////////// // DEFINES ///////////////////////////////////////////////////////////////// diff --git a/include/SPELL_IPC/SPELLipcClientInterface.H b/include/SPELL_IPC/SPELLipcClientInterface.H index 687e0f8..d24154b 100644 --- a/include/SPELL_IPC/SPELLipcClientInterface.H +++ b/include/SPELL_IPC/SPELLipcClientInterface.H @@ -5,7 +5,7 @@ // DESCRIPTION: IPC - Interface for clients // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -269,6 +269,8 @@ protected: //----------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void incomingResponse( const SPELLipcMessage& msg ); + SPELLipcMessage getPingMessage(); + // DATA MEMBERS ////////////////////////////////////////////////////////// diff --git a/include/SPELL_IPC/SPELLipcDataChunk.H b/include/SPELL_IPC/SPELLipcDataChunk.H index c8cbc81..8119831 100644 --- a/include/SPELL_IPC/SPELLipcDataChunk.H +++ b/include/SPELL_IPC/SPELLipcDataChunk.H @@ -5,7 +5,7 @@ // DESCRIPTION: Mechanism for transferring big data // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_IPC/SPELLipcError.H b/include/SPELL_IPC/SPELLipcError.H index 2df1b2c..f5596fa 100644 --- a/include/SPELL_IPC/SPELLipcError.H +++ b/include/SPELL_IPC/SPELLipcError.H @@ -5,7 +5,7 @@ // DESCRIPTION: IPC error defintions // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_IPC/SPELLipcHelper.H b/include/SPELL_IPC/SPELLipcHelper.H index 8cef46b..3fe969d 100644 --- a/include/SPELL_IPC/SPELLipcHelper.H +++ b/include/SPELL_IPC/SPELLipcHelper.H @@ -5,7 +5,7 @@ // DESCRIPTION: Utilities for IPC // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_IPC/SPELLipcIncoming.H b/include/SPELL_IPC/SPELLipcIncoming.H index 02c660e..9758650 100644 --- a/include/SPELL_IPC/SPELLipcIncoming.H +++ b/include/SPELL_IPC/SPELLipcIncoming.H @@ -5,7 +5,7 @@ // DESCRIPTION: Handler for incoming IPC messages // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -30,13 +30,13 @@ // FILES TO INCLUDE //////////////////////////////////////////////////////// // System includes --------------------------------------------------------- // Local includes ---------------------------------------------------------- +#include "SPELL_IPC/SPELLipcChannel.H" #include "SPELL_IPC/SPELLipcInterfaceListener.H" // Project includes -------------------------------------------------------- #include "SPELL_SYN/SPELLthread.H" #include "SPELL_SYN/SPELLevent.H" #include "SPELL_SYN/SPELLthreadWork.H" - /** \addtogroup SPELL_IPC */ /*@{*/ @@ -44,6 +44,7 @@ // FORWARD REFERENCES ////////////////////////////////////////////////////// class SPELLipcInterface; class SPELLipcOutput; + // TYPES /////////////////////////////////////////////////////////////////// // DEFINES ///////////////////////////////////////////////////////////////// @@ -201,7 +202,7 @@ private: //------------------------------------------------------------------- /** Holds the listener to be notified */ SPELLipcInterfaceListener& m_listener; /** The message to be processed */ - const SPELLipcMessage m_message; + SPELLipcMessage m_message; /** Event set when the processing finishes */ SPELLevent m_processingFinishEvent; /** Event set when the processing starts */ @@ -294,7 +295,8 @@ public: //-------------------------------------------------------------------- SPELLipcIncomingRequest( const std::string& requestId, const std::string& ifcName, SPELLipcMessage msg, - SPELLipcOutput& writer, + SPELLmutex& mutex, + SPELLipcChannel** channel, SPELLipcInterfaceListener& listener ); ////////////////////////////////////////////////////////////////////// @@ -322,7 +324,8 @@ private: //------------------------------------------------------------------- // DATA MEMBERS ////////////////////////////////////////////////////////// /** Holds the writer to use to send the response */ - SPELLipcOutput& m_writer; + SPELLipcChannel** m_channel; + SPELLmutex& m_mutex; }; /*@}*/ diff --git a/include/SPELL_IPC/SPELLipcInput.H b/include/SPELL_IPC/SPELLipcInput.H index 56b2619..e513036 100644 --- a/include/SPELL_IPC/SPELLipcInput.H +++ b/include/SPELL_IPC/SPELLipcInput.H @@ -5,7 +5,7 @@ // DESCRIPTION: Data reader // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -42,6 +42,7 @@ // FORWARD REFERENCES ////////////////////////////////////////////////////// class SPELLipcChannel; +class SPELLipcInterface; // TYPES /////////////////////////////////////////////////////////////////// // DEFINES ///////////////////////////////////////////////////////////////// @@ -96,6 +97,11 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// bool isConnected(); + void setHandleEOC(bool eocValue) + { + m_requestedEOC = eocValue; + } + // DATA MEMBERS ////////////////////////////////////////////////////////// protected: //----------------------------------------------------------------- diff --git a/include/SPELL_IPC/SPELLipcInterface.H b/include/SPELL_IPC/SPELLipcInterface.H index e62a32e..ba67190 100644 --- a/include/SPELL_IPC/SPELLipcInterface.H +++ b/include/SPELL_IPC/SPELLipcInterface.H @@ -5,7 +5,7 @@ // DESCRIPTION: Common IPC interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -175,6 +175,12 @@ public: //-------------------------------------------------------------------- * \param msg IN: response to be processed. **//////////////////////////////////////////////////////////////////// virtual void incomingResponse( const SPELLipcMessage& msg ) = 0; + + virtual SPELLipcMessage getPingMessage() + { + static SPELLipcMessage empty = SPELLipcMessage(); + return empty; + }; }; /*@}*/ diff --git a/include/SPELL_IPC/SPELLipcInterfaceListener.H b/include/SPELL_IPC/SPELLipcInterfaceListener.H index 100926b..01e6838 100644 --- a/include/SPELL_IPC/SPELLipcInterfaceListener.H +++ b/include/SPELL_IPC/SPELLipcInterfaceListener.H @@ -5,7 +5,7 @@ // DESCRIPTION: Interface IPC message listener // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -89,6 +89,12 @@ public: /** Peer has closed the connection (end of conversation) **//////////////////////////////////////////////////////////////////// virtual void processConnectionClosed( int clientKey ) = 0; + + virtual SPELLipcMessage getPingMessage() + { + static SPELLipcMessage empty = SPELLipcMessage(); + return empty; + }; }; /*@}*/ diff --git a/include/SPELL_IPC/SPELLipcMessage.H b/include/SPELL_IPC/SPELLipcMessage.H index b93ae94..c882f51 100644 --- a/include/SPELL_IPC/SPELLipcMessage.H +++ b/include/SPELL_IPC/SPELLipcMessage.H @@ -5,7 +5,7 @@ // DESCRIPTION: Definition of IPC message // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -239,6 +239,12 @@ public: //-------------------------------------------------------------------- return m_type; } + ////////////////////////////////////////////////////////////////////// + /**Cleans up this message and frees as much meory as possible. + * + **//////////////////////////////////////////////////////////////////// + void clear(); + ////////////////////////////////////////////////////////////////////// /** Set the value of a message field. * diff --git a/include/SPELL_IPC/SPELLipcMessageMailbox.H b/include/SPELL_IPC/SPELLipcMessageMailbox.H index 989acdb..b8b365d 100644 --- a/include/SPELL_IPC/SPELLipcMessageMailbox.H +++ b/include/SPELL_IPC/SPELLipcMessageMailbox.H @@ -5,7 +5,7 @@ // DESCRIPTION: Mailbox for incoming messages // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -166,11 +166,6 @@ private: //------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// SPELLipcMessageQueue* getQueue( std::string id ); - ////////////////////////////////////////////////////////////////////// - /** Cancell all requests waiting - **//////////////////////////////////////////////////////////////////// - void cancelAll(); - // DATA MEMBERS ////////////////////////////////////////////////////////// /** Holds the map of message queues */ SPELLipcMessageQueueMap m_queueMap; diff --git a/include/SPELL_IPC/SPELLipcOutput.H b/include/SPELL_IPC/SPELLipcOutput.H index 7d8d037..5ede685 100644 --- a/include/SPELL_IPC/SPELLipcOutput.H +++ b/include/SPELL_IPC/SPELLipcOutput.H @@ -5,7 +5,7 @@ // DESCRIPTION: Data writer // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_IPC/SPELLipcServerInterface.H b/include/SPELL_IPC/SPELLipcServerInterface.H index 261b597..8b693dc 100644 --- a/include/SPELL_IPC/SPELLipcServerInterface.H +++ b/include/SPELL_IPC/SPELLipcServerInterface.H @@ -5,7 +5,7 @@ // DESCRIPTION: Interface for servers // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -216,7 +216,7 @@ protected: //----------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// /** Obtain the channel for a peer **//////////////////////////////////////////////////////////////////// - SPELLipcChannel& getChannel( int peerKey ); + SPELLipcChannel** getChannel( int peerKey ); // DATA MEMBERS ////////////////////////////////////////////////////////// @@ -251,6 +251,7 @@ private: //------------------------------------------------------------------- * \param key IN: peer key. **//////////////////////////////////////////////////////////////////// void removeClient( int key ); + void removeClientInternal( int key ); ////////////////////////////////////////////////////////////////////// /** Remove all client of the list of connected clients and disconnect @@ -325,6 +326,9 @@ private: //------------------------------------------------------------------- std::string m_ifcName; /** Holds the client keys used */ std::vector m_usedClientKeys; + + std::vector m_clientKeysToRemove; + /** Holds the server key */ int m_serverKey; /** Holds the server port */ @@ -333,6 +337,7 @@ private: //------------------------------------------------------------------- SPELLsocket* m_serverSocket; /** Synchronization mutex for operations */ SPELLmutex m_clientLock; + SPELLmutex m_clientCleanupLock; /** True if the interface is connected */ bool m_connected; /** Associated IPC listener */ diff --git a/include/SPELL_IPC/SPELLipcServerInterfaceSingle.H b/include/SPELL_IPC/SPELLipcServerInterfaceSingle.H index c6c019e..3346ea7 100644 --- a/include/SPELL_IPC/SPELLipcServerInterfaceSingle.H +++ b/include/SPELL_IPC/SPELLipcServerInterfaceSingle.H @@ -5,7 +5,7 @@ // DESCRIPTION: Interface for single-client servers // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -187,6 +187,7 @@ private: //------------------------------------------------------------------- /** Remove the client **//////////////////////////////////////////////////////////////////// void removeClient(); + void removeClientInternal(); ////////////////////////////////////////////////////////////////////// /** \see SPELLipcInterface. @@ -272,7 +273,8 @@ private: //------------------------------------------------------------------- /** Synchronization mutex for operations */ SPELLmutex m_clientLock; /** True if the interface is connected */ - bool m_connected; + bool m_connected; + bool m_removeClient; /** Associated IPC listener */ SPELLipcInterfaceListener* m_listener; /** Holds the set of incoming request processors to be cleaned up */ @@ -289,6 +291,8 @@ private: //------------------------------------------------------------------- SPELLevent m_clientConnectionEvent; /** Blocks processing of incoming requests */ SPELLmutex m_incomingLock; + /** Only allow one thread to cleanup the channel */ + SPELLmutex m_cleanupLock; /** IPC channel */ SPELLipcChannel* m_channel; /** Timeout for request retries */ diff --git a/include/SPELL_IPC/SPELLipcTrash.H b/include/SPELL_IPC/SPELLipcTrash.H index 5ff4201..4b103cc 100644 --- a/include/SPELL_IPC/SPELLipcTrash.H +++ b/include/SPELL_IPC/SPELLipcTrash.H @@ -5,7 +5,7 @@ // DESCRIPTION: Cleaner for obsolete requests // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -111,8 +111,6 @@ public: //-------------------------------------------------------------------- // DATA MEMBERS ////////////////////////////////////////////////////////// -protected: //----------------------------------------------------------------- - // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// // TYPES ///////////////////////////////////////////////////////////////// diff --git a/include/SPELL_IPC/SPELLipc_Context.H b/include/SPELL_IPC/SPELLipc_Context.H index cfe316e..57fe5dc 100644 --- a/include/SPELL_IPC/SPELLipc_Context.H +++ b/include/SPELL_IPC/SPELLipc_Context.H @@ -5,7 +5,7 @@ // DESCRIPTION: Inter process communication, data definitions for context process // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -100,8 +100,11 @@ namespace MessageField static const std::string FIELD_PROMPT_DELAY("PromptWarningDelay"); static const std::string FIELD_BY_STEP("ByStep"); static const std::string FIELD_FORCE_TC_CONFIRM("ForceTcConfirm"); + static const std::string FIELD_FORCE_PROMPT_CONFIRM("ForcePromptConfirm"); static const std::string FIELD_SAVE_STATE_MODE("SaveStateMode"); static const std::string FIELD_WATCH_VARIABLES("WatchVariables"); + static const std::string FIELD_RESOURCES_DISPLAY("ResourcesDisplay"); + static const std::string FIELD_LOCAL_RESOURCE_SUPPORTED("LocalResourcesSupported"); static const std::string FIELD_MAX_VERBOSITY("MaxVerbosity"); static const std::string FIELD_BROWSABLE_LIB("BrowsableLib"); @@ -178,13 +181,18 @@ namespace MessageValue namespace ContextMessages { /** Request list of available executors (running procedures) */ - static const std::string REQ_EXEC_LIST("REQ_EXEC_LIST"); + static const std::string REQ_EXEC_LIST("REQ_EXEC_LIST"); + static const std::string REQ_SERVICE_LIST("REQ_SERVICE_LIST"); + /** Response to REQ_EXEC_LIST */ static const std::string RSP_EXEC_LIST("RSP_EXEC_LIST"); + static const std::string RSP_SERVICE_LIST("RSP_SERVICE_LIST"); /** Request executor (procedure) information */ - static const std::string REQ_EXEC_INFO("REQ_EXEC_INFO"); - /** Response to REQ_EXEC_INFO */ + static const std::string REQ_EXEC_INFO("REQ_EXEC_INFO"); + /** Request service information */ + static const std::string REQ_SERVICE_INFO("REQ_SERVICE_INFO"); + /** Response to REQ_EXEC_INFO */ static const std::string RSP_EXEC_INFO("RSP_EXEC_INFO"); /** Request opening a new executor (procedure) diff --git a/include/SPELL_IPC/SPELLipc_Executor.H b/include/SPELL_IPC/SPELLipc_Executor.H index 582611b..0537f10 100644 --- a/include/SPELL_IPC/SPELLipc_Executor.H +++ b/include/SPELL_IPC/SPELLipc_Executor.H @@ -5,7 +5,7 @@ // DESCRIPTION: Inter process communication, data definitions for executor process // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -80,6 +80,9 @@ namespace MessageId /** Message for enabling or disabling variable analysis */ static const std::string MSG_ID_WVARIABLES_ENABLE("MSG_WVARIABLES_ENABLE"); static const std::string MSG_ID_WVARIABLES_DISABLE("MSG_WVARIABLES_DISABLE"); + /** Message for enabling or disabling resource analysis */ + static const std::string MSG_ID_DRESOURCES_ENABLE("MSG_DRESOURCES_ENABLE"); + static const std::string MSG_ID_DRESOURCES_DISABLE("MSG_DRESOURCES_DISABLE"); }; /** Defines message fields */ @@ -201,6 +204,31 @@ namespace MessageField /** Variable analysis enabled */ static const std::string FIELD_WVARIABLES_ENABLED("WVarEnabled"); + //################################################################################ + //# DISPLAY OF RESOURCES + //################################################################################ + + /** Resource names */ + static const std::string FIELD_RESOURCE_NAME("ResourceName"); + /** Resource global values */ + static const std::string FIELD_RESOURCE_GLOBAL_VALUE("ResourceGlobalValue"); + /** Resource local values */ + static const std::string FIELD_RESOURCE_LOCAL_VALUE("ResourceLocalValue"); + /** Resource types */ + static const std::string FIELD_RESOURCE_TYPE("ResourceType"); + /** Resource value range */ + static const std::string FIELD_RESOURCE_VALUE_RANGE("ResourceValueRange"); + /** Resource gcs value range */ + static const std::string FIELD_RESOURCE_GCS_VALUE_RANGE("ResourceGCSValueRange"); + /** Resource GCS names */ + static const std::string FIELD_RESOURCE_GCS_NAME("ResourceGCSName"); + /** Resource deleted flags */ + static const std::string FIELD_RESOURCE_DELETE("ResourceDelete"); + /** Resource added flags */ + static const std::string FIELD_RESOURCE_ADDED("ResourceAdded"); + /** Resource analysis enabled */ + static const std::string FIELD_DRESOURCES_ENABLED("DResourcesEnabled"); + //################################################################################ //# DICTIONARY EDITING //################################################################################ @@ -399,6 +427,23 @@ namespace ExecutorMessages /** Response */ static const std::string RSP_WVARIABLES_ENABLED("RSP_WVARIABLES_ENABLED"); + //################################################################################ + //# DISPLAY OF RESOURCES + //################################################################################ + + /** Request for retrieving resource names */ + static const std::string REQ_GET_RESOURCES("REQ_GET_RESOURCES"); + /** Response */ + static const std::string RSP_GET_RESOURCES("RSP_GET_RESOURCES"); + /** Request for changing resources */ + static const std::string REQ_CHANGE_RESOURCE("REQ_CHANGE_RESOURCE"); + /** Response */ + static const std::string RSP_CHANGE_RESOURCE("RSP_CHANGE_RESOURCE"); + /** Request to check if resource analysis is enabled */ + static const std::string REQ_DRESOURCES_ENABLED("REQ_DRESOURCES_ENABLED"); + /** Response */ + static const std::string RSP_DRESOURCES_ENABLED("RSP_DRESOURCES_ENABLED"); + //################################################################################ //# DICTIONARY EDITING //################################################################################ @@ -423,6 +468,9 @@ namespace ExecutorMessages /** Oneway message for variable scope change notifications */ static const std::string MSG_SCOPE_CHANGE("MSG_SCOPE_CHANGE"); + /** Oneway message for resource change notifications */ + static const std::string MSG_RESOURCE_CHANGE("MSG_RESOURCE_CHANGE"); + //################################################################################ //# REQUESTS TO CONTEXT //################################################################################ diff --git a/include/SPELL_IPC/SPELLipc_Listener.H b/include/SPELL_IPC/SPELLipc_Listener.H index 5ef1469..8c2a68c 100644 --- a/include/SPELL_IPC/SPELLipc_Listener.H +++ b/include/SPELL_IPC/SPELLipc_Listener.H @@ -5,7 +5,7 @@ // DESCRIPTION: Inter process communication, data definitions for listener process // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_IPC/SPELLsocket.H b/include/SPELL_IPC/SPELLsocket.H index 0df5e6c..485e2b1 100644 --- a/include/SPELL_IPC/SPELLsocket.H +++ b/include/SPELL_IPC/SPELLsocket.H @@ -5,7 +5,7 @@ // DESCRIPTION: Socket wrapper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -60,7 +60,7 @@ public: //-------------------------------------------------------------------- * * \param fd IN: socket file descriptor. *///////////////////////////////////////////////////////////////////// - SPELLsocket( int fd ); + SPELLsocket(int fd, std::string user, std::vector groups); /*//////////////////////////////////////////////////////////////////// * Destructor @@ -116,6 +116,11 @@ public: //-------------------------------------------------------------------- *///////////////////////////////////////////////////////////////////// bool waitData( int timeout ); + + std::string getUser() { + return user; + }; + /*//////////////////////////////////////////////////////////////////// * Shutdown the socket input. *///////////////////////////////////////////////////////////////////// @@ -183,6 +188,9 @@ private: //------------------------------------------------------------------- int m_socketFd; /** Socket connected flag */ bool m_connected; + + std::string user; + std::vector groups; }; /*@}*/ diff --git a/include/SPELL_IPC/SPELLtimeoutValues.H b/include/SPELL_IPC/SPELLtimeoutValues.H index 7157cd1..848b6f3 100644 --- a/include/SPELL_IPC/SPELLtimeoutValues.H +++ b/include/SPELL_IPC/SPELLtimeoutValues.H @@ -5,7 +5,7 @@ // DESCRIPTION: Inter process communication, timeout values // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_LST/SPELLlistener.H b/include/SPELL_LST/SPELLlistener.H index 1b9dc46..068d769 100644 --- a/include/SPELL_LST/SPELLlistener.H +++ b/include/SPELL_LST/SPELLlistener.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL listener library header file // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_LST/SPELLlistenerComm.H b/include/SPELL_LST/SPELLlistenerComm.H index 78ce8b8..a5507a9 100644 --- a/include/SPELL_LST/SPELLlistenerComm.H +++ b/include/SPELL_LST/SPELLlistenerComm.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL listener library header file // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_LST/SPELLlistenerContext.H b/include/SPELL_LST/SPELLlistenerContext.H index 3c0a5b6..836593e 100644 --- a/include/SPELL_LST/SPELLlistenerContext.H +++ b/include/SPELL_LST/SPELLlistenerContext.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL listener library header file // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -97,10 +97,10 @@ public: void notifyClients( const SPELLipcMessage& msg ); // SPELLprocessListener methods - void processStarted( const std::string& identifier ); - void processFinished( const std::string& identifier, const int& retValue ); - void processKilled( const std::string& identifier ); - void processFailed( const std::string& identifier ); + void processStarted( const std::string identifier ); + void processFinished( const std::string identifier, const int& retValue ); + void processKilled( const std::string identifier ); + void processFailed( const std::string identifier ); bool respawnContext(const std::string& ctxName); // Internals diff --git a/include/SPELL_LST/SPELLlistenerGui.H b/include/SPELL_LST/SPELLlistenerGui.H index 4848d39..ed5a28d 100644 --- a/include/SPELL_LST/SPELLlistenerGui.H +++ b/include/SPELL_LST/SPELLlistenerGui.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL listener library header file // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_PRC/SPELLprocess.H b/include/SPELL_PRC/SPELLprocess.H index 37d8315..08501b1 100644 --- a/include/SPELL_PRC/SPELLprocess.H +++ b/include/SPELL_PRC/SPELLprocess.H @@ -5,7 +5,7 @@ // DESCRIPTION: Process model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_PRC/SPELLprocessInfo.H b/include/SPELL_PRC/SPELLprocessInfo.H index 3a9ee2f..5344f2f 100644 --- a/include/SPELL_PRC/SPELLprocessInfo.H +++ b/include/SPELL_PRC/SPELLprocessInfo.H @@ -5,7 +5,7 @@ // DESCRIPTION: Process information // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_PRC/SPELLprocessManager.H b/include/SPELL_PRC/SPELLprocessManager.H index 4efd787..1c8b05d 100644 --- a/include/SPELL_PRC/SPELLprocessManager.H +++ b/include/SPELL_PRC/SPELLprocessManager.H @@ -5,7 +5,7 @@ // DESCRIPTION: Process manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -77,7 +77,7 @@ public://-------------------------------------------------------------------- * * \param identifier IN: unique identifier of the process. **//////////////////////////////////////////////////////////////////// - virtual void processStarted( const std::string& identifier ) = 0; + virtual void processStarted( const std::string identifier ) = 0; ////////////////////////////////////////////////////////////////////// /** Notify the given process has finished. @@ -85,21 +85,21 @@ public://-------------------------------------------------------------------- * \param identifier IN: unique identifier of the process. * \param retValue IN: process exit code. **//////////////////////////////////////////////////////////////////// - virtual void processFinished( const std::string& identifier, const int& retValue ) = 0; + virtual void processFinished( std::string identifier, const int& retValue ) = 0; ////////////////////////////////////////////////////////////////////// /** Notify the given process has been killed. * * \param identifier IN: unique identifier of the process. **//////////////////////////////////////////////////////////////////// - virtual void processKilled( const std::string& identifier ) = 0; + virtual void processKilled( std::string identifier ) = 0; ////////////////////////////////////////////////////////////////////// /** Notify the given process has failed to start. * * \param identifier IN: unique identifier of the process. **//////////////////////////////////////////////////////////////////// - virtual void processFailed( const std::string& identifier ) = 0; + virtual void processFailed( std::string identifier ) = 0; }; ////////////////////////////////////////////////////////////////////////////// @@ -168,6 +168,8 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void killProcess( const std::string& identifier ); + bool checkProcessExist( const std::string& identifier ); + ////////////////////////////////////////////////////////////////////// /** Wait the given process to finish. * @@ -241,7 +243,7 @@ protected: //----------------------------------------------------------------- * * \param identifier IN: process unique identifier. **//////////////////////////////////////////////////////////////////// - void fireProcessStarted( const std::string& identifier ); + void fireProcessStarted( const std::string identifier ); ////////////////////////////////////////////////////////////////////// /** Notify listeners that a given process has finished. @@ -249,21 +251,21 @@ protected: //----------------------------------------------------------------- * \param identifier IN: process unique identifier. * \param retValue IN: process exit code. **//////////////////////////////////////////////////////////////////// - void fireProcessFinished( const std::string& identifier, int retValue ); + void fireProcessFinished( std::string identifier, int retValue ); ////////////////////////////////////////////////////////////////////// /** Notify listeners that a given process has been killed. * * \param identifier IN: process unique identifier. **//////////////////////////////////////////////////////////////////// - void fireProcessKilled( const std::string& identifier ); + void fireProcessKilled( std::string identifier ); ////////////////////////////////////////////////////////////////////// /** Notify listeners that a given process has failed to start. * * \param identifier IN: process unique identifier. **//////////////////////////////////////////////////////////////////// - void fireProcessFailed( const std::string& identifier ); + void fireProcessFailed( std::string identifier ); // DATA MEMBERS ////////////////////////////////////////////////////////// diff --git a/include/SPELL_PRC/SPELLprocessStatus.H b/include/SPELL_PRC/SPELLprocessStatus.H index 8b61681..16923fd 100644 --- a/include/SPELL_PRC/SPELLprocessStatus.H +++ b/include/SPELL_PRC/SPELLprocessStatus.H @@ -5,7 +5,7 @@ // DESCRIPTION: Process status codes // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_PRD/SPELLlibrary.H b/include/SPELL_PRD/SPELLlibrary.H index 0fe2a2f..ecbd6f4 100644 --- a/include/SPELL_PRD/SPELLlibrary.H +++ b/include/SPELL_PRD/SPELLlibrary.H @@ -5,7 +5,7 @@ // DESCRIPTION: Library model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -120,7 +120,7 @@ protected: //----------------------------------------------------------------- * * \param path IN: the path to the procedure file. **//////////////////////////////////////////////////////////////////// - void parseFile( const std::string& path ); + void parseFile( const std::string& path ) {}; // DATA MEMBERS ////////////////////////////////////////////////////////// diff --git a/include/SPELL_PRD/SPELLprocedure.H b/include/SPELL_PRD/SPELLprocedure.H index 3e78a9d..809dbd5 100644 --- a/include/SPELL_PRD/SPELLprocedure.H +++ b/include/SPELL_PRD/SPELLprocedure.H @@ -5,7 +5,7 @@ // DESCRIPTION: Procedure model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -106,15 +106,6 @@ public: //-------------------------------------------------------------------- return m_name; }; - ////////////////////////////////////////////////////////////////////// - /** Obtain the procedure file MD5 checksum. - * - * \returns The checksum. - **//////////////////////////////////////////////////////////////////// - const std::string getMD5() const { - return m_md5; - }; - ////////////////////////////////////////////////////////////////////// /** Obtain the procedure file name and path. * @@ -210,11 +201,6 @@ protected: //----------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// const bool isPropertyContinued( const std::string& line ); - ////////////////////////////////////////////////////////////////////// - /** Calculate de MD5 checksum of the procedure file. - **//////////////////////////////////////////////////////////////////// - std::string obtainChecksum( const std::string& filename ); - // DATA MEMBERS ////////////////////////////////////////////////////////// private: //------------------------------------------------------------------- @@ -229,8 +215,6 @@ private: //------------------------------------------------------------------- std::string m_procId; /** Procedure name */ std::string m_name; - /** MD5 checksum */ - std::string m_md5; /** Procedure file */ std::string m_file; /** Procedure source code */ diff --git a/include/SPELL_PRD/SPELLprocedureManager.H b/include/SPELL_PRD/SPELLprocedureManager.H index b66c66b..e9f431d 100644 --- a/include/SPELL_PRD/SPELLprocedureManager.H +++ b/include/SPELL_PRD/SPELLprocedureManager.H @@ -5,7 +5,7 @@ // DESCRIPTION: Procedure manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -30,6 +30,7 @@ // FILES TO INCLUDE //////////////////////////////////////////////////////// // System includes --------------------------------------------------------- // Local includes ---------------------------------------------------------- +#include "SPELL_PRD/SPELLpyService.H" #include "SPELL_PRD/SPELLprocedure.H" #include "SPELL_PRD/SPELLlibrary.H" // Project includes -------------------------------------------------------- @@ -38,11 +39,9 @@ /** \addtogroup SPELL_PRD */ /*@{*/ - // FORWARD REFERENCES ////////////////////////////////////////////////////// // TYPES /////////////////////////////////////////////////////////////////// // DEFINES ///////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// /** ** \brief Procedure manager. @@ -54,175 +53,208 @@ ** Used by the executor when loading subprocedures, and to check if a ** given file is on the procedure path. ** -**//////////////////////////////////////////////////////////////////////////// + **//////////////////////////////////////////////////////////////////////////// + +const std::string noInstanceId( const std::string& procId ); + + class SPELLprocedureManager { -public: //-------------------------------------------------------------------- +public: + //-------------------------------------------------------------------- // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// // TYPES ///////////////////////////////////////////////////////////////// - /** Shorcut for procedure lists */ - typedef std::list ProcList; + /** Shorcut for procedure lists */ + typedef std::list ProcList; // LIFECYCLE ///////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - /** Destructor - **//////////////////////////////////////////////////////////////////// - ~SPELLprocedureManager(); + ////////////////////////////////////////////////////////////////////// + /** Destructor + **//////////////////////////////////////////////////////////////////// + ~SPELLprocedureManager(); // STATIC //////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - /** Obtain the singleton instance. - * - * \return The singleton instance - **//////////////////////////////////////////////////////////////////// - static SPELLprocedureManager& instance(); + ////////////////////////////////////////////////////////////////////// + /** Obtain the singleton instance. + * + * \return The singleton instance + **//////////////////////////////////////////////////////////////////// + static SPELLprocedureManager& instance(); // METHODS /////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - /** Setup the procedure manager. - * - * \param ctxName IN: current context name. - **//////////////////////////////////////////////////////////////////// - void setup( const std::string& ctxName ); - - ////////////////////////////////////////////////////////////////////// - /** Obtain the configured library path. - * - * \returns The library path. - **//////////////////////////////////////////////////////////////////// - const std::string getLibPath() const; - - ////////////////////////////////////////////////////////////////////// - /** Obtain the configured procedure path. - * - * \returns The library path. - **//////////////////////////////////////////////////////////////////// - const std::string getProcPath() const; - - ////////////////////////////////////////////////////////////////////// - /** Obtain the filename corresponding to the given procedure. - * - * \param procId IN: the procedure identifier. - * - * \returns The file name. - **//////////////////////////////////////////////////////////////////// - const std::string getProcFile( const std::string& procId ); - - ////////////////////////////////////////////////////////////////////// - /** Obtain the name corresponding to the given procedure. - * - * \param procId IN: the procedure identifier. - * - * \returns The procedure name. - **//////////////////////////////////////////////////////////////////// - const std::string getProcName( const std::string& procId ); - - ////////////////////////////////////////////////////////////////////// - /** Obtain the identifier corresponding to the given procedure file. - * - * \param filename IN: the procedure file. - * - * \returns The identifier. - **//////////////////////////////////////////////////////////////////// - const std::string getProcId( const std::string& filename ); - - ////////////////////////////////////////////////////////////////////// - /** Get the list of available procedures. - * - * \returns The list of procedure identifiers. - **//////////////////////////////////////////////////////////////////// - const ProcList getProcList(); - - ////////////////////////////////////////////////////////////////////// - /** Obtain the source code corresponding to the given procedure. - * - * \param procId IN: the procedure identifier. - * - * \returns The source code. - **//////////////////////////////////////////////////////////////////// - SPELLprocedureSourceCode getSourceCode( const std::string& procId ); - - ////////////////////////////////////////////////////////////////////// - /** Obtain the list of procedure properties - **//////////////////////////////////////////////////////////////////// - SPELLprocedure::PropertyKeys getPropertyKeys( const std::string& procId ); - - ////////////////////////////////////////////////////////////////////// - /** Obtain the value of a procedure property - **//////////////////////////////////////////////////////////////////// - const std::string getProperty( const std::string& procId, const std::string& key ); - - ////////////////////////////////////////////////////////////////////// - /** Refresh and reload the list of available procedures. - **//////////////////////////////////////////////////////////////////// - void refresh(); - - ////////////////////////////////////////////////////////////////////// - /** Get a procedure model - **//////////////////////////////////////////////////////////////////// - SPELLprocedure& getProcedure( const std::string& procId ); + ////////////////////////////////////////////////////////////////////// + /** Setup the procedure manager. + * + * \param ctxName IN: current context name. + **//////////////////////////////////////////////////////////////////// + void setup(const std::string& ctxName); + + ////////////////////////////////////////////////////////////////////// + /** Obtain the configured library path. + * + * \returns The library path. + **//////////////////////////////////////////////////////////////////// + const std::string getLibPath() const; + + ////////////////////////////////////////////////////////////////////// + /** Obtain the configured procedure path. + * + * \returns The library path. + **//////////////////////////////////////////////////////////////////// + const std::string getProcPath() const; + + ////////////////////////////////////////////////////////////////////// + /** Obtain the filename corresponding to the given procedure. + * + * \param procId IN: the procedure identifier. + * + * \returns The file name. + **//////////////////////////////////////////////////////////////////// + const std::string getProcFile(const std::string& procId); + + ////////////////////////////////////////////////////////////////////// + /** Obtain the name corresponding to the given procedure. + * + * \param procId IN: the procedure identifier. + * + * \returns The procedure name. + **//////////////////////////////////////////////////////////////////// + const std::string getProcName(const std::string& procId); + + ////////////////////////////////////////////////////////////////////// + /** Obtain the identifier corresponding to the given procedure file. + * + * \param filename IN: the procedure file. + * + * \returns The identifier. + **//////////////////////////////////////////////////////////////////// + const std::string getProcId(const std::string& filename); + + ////////////////////////////////////////////////////////////////////// + /** Get the list of available procedures. + * + * \returns The list of procedure identifiers. + **//////////////////////////////////////////////////////////////////// + const ProcList getProcList(); + ////////////////////////////////////////////////////////////////////// + /** Get the list of available services. + * + * \returns The list of service identifiers. + **//////////////////////////////////////////////////////////////////// + const ProcList getServiceList(); + + ////////////////////////////////////////////////////////////////////// + /** Obtain the source code corresponding to the given procedure. + * + * \param procId IN: the procedure identifier. + * + * \returns The source code. + **//////////////////////////////////////////////////////////////////// + SPELLprocedureSourceCode getSourceCode(const std::string& procId); + + ////////////////////////////////////////////////////////////////////// + /** Obtain the list of procedure properties + **//////////////////////////////////////////////////////////////////// + SPELLprocedure::PropertyKeys getPropertyKeys(const std::string& procId); + + ////////////////////////////////////////////////////////////////////// + /** Obtain the value of a procedure property + **//////////////////////////////////////////////////////////////////// + const std::string getProperty(const std::string& procId, const std::string& key); + + ////////////////////////////////////////////////////////////////////// + /** Refresh and reload the list of available procedures. + **//////////////////////////////////////////////////////////////////// + void refresh(); + + ////////////////////////////////////////////////////////////////////// + /** Get a procedure model + **//////////////////////////////////////////////////////////////////// + SPELLprocedure& getProcedure(const std::string& procId); + + ////////////////////////////////////////////////////////////////////// + /** Get a service model + **//////////////////////////////////////////////////////////////////// + SPELLpyService& getService(const std::string& serviceId); + + ////////////////////////////////////////////////////////////////////// + /** Callback for registering a SPELL Service + **//////////////////////////////////////////////////////////////////// + void registerServiceHandler(PyObject* serviceImpl); // DATA MEMBERS ////////////////////////////////////////////////////////// -protected: //----------------------------------------------------------------- +protected: + //----------------------------------------------------------------- // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// // TYPES ///////////////////////////////////////////////////////////////// - /** Shortcut for procedure id-name map */ - typedef std::map ProcMap; - /** Shortcut for procedure id-model map */ - typedef std::map ProcModels; - /** Shortcut for library id-model map */ - typedef std::map LibModels; + /** Shortcut for procedure id-name map */ + typedef std::map ProcMap; + /** Shortcut for procedure id-model map */ + typedef std::map ProcModels; + typedef std::map ServiceModelMap; + /** Shortcut for library id-model map */ + typedef std::map LibModels; // LIFECYCLE ///////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - /** Constructor. - **//////////////////////////////////////////////////////////////////// - SPELLprocedureManager(); + ////////////////////////////////////////////////////////////////////// + /** Constructor. + **//////////////////////////////////////////////////////////////////// + SPELLprocedureManager(); // METHODS /////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - /** Resolve procedure paths - **//////////////////////////////////////////////////////////////////// - void resolvePaths(); - - ////////////////////////////////////////////////////////////////////// - /** Find all procedures in the given search path. Include only those - * procedures whose associated spacecraft matches the given one. - * - * \param basePath IN: search path - * \param sc IN: spacecraft id. - **//////////////////////////////////////////////////////////////////// - void findProcedures( const std::string& basePath, const std::string& sc ); - - ////////////////////////////////////////////////////////////////////// - /** Find all libraries available in UserLib location path. - * - * \param basePath IN: the path of UserLib location. - **//////////////////////////////////////////////////////////////////// - void findLibraries( const std::string& basePath ); - - ////////////////////////////////////////////////////////////////////// - /** Remove the instance number from the given procedure identifier. - * - * \param procId IN: the identifier to process. - * - * \returns The procedure identifier without instance information. - **//////////////////////////////////////////////////////////////////// - const std::string noInstanceId( const std::string& procId ); + ////////////////////////////////////////////////////////////////////// + /** Resolve procedure paths + **//////////////////////////////////////////////////////////////////// + void resolvePaths(); + + ////////////////////////////////////////////////////////////////////// + /** Find all procedures in the given search path. Include only those + * procedures whose associated spacecraft matches the given one. + * + * \param basePath IN: search path + * \param sc IN: spacecraft id. + **//////////////////////////////////////////////////////////////////// + void findProcedures(const std::string& basePath, const std::string& sc); + + ////////////////////////////////////////////////////////////////////// + /** Find all Spell Services in the given search path. Include only those + * procedures whose associated spacecraft matches the given one. + * + * \param basePath IN: search path + * \param sc IN: spacecraft id. + **//////////////////////////////////////////////////////////////////// + void findServices(const std::string& basePath, const std::string& sc); + + ////////////////////////////////////////////////////////////////////// + /** Find all libraries available in UserLib location path. + * + * \param basePath IN: the path of UserLib location. + **//////////////////////////////////////////////////////////////////// + void findLibraries(const std::string& basePath); + + ////////////////////////////////////////////////////////////////////// + /** Remove the instance number from the given procedure identifier. + * + * \param procId IN: the identifier to process. + * + * \returns The procedure identifier without instance information. + **//////////////////////////////////////////////////////////////////// + //const std::string noInstanceId(const std::string& procId); // DATA MEMBERS ////////////////////////////////////////////////////////// -private: //------------------------------------------------------------------- +private: + //------------------------------------------------------------------- // EXCEPTIONS //////////////////////////////////////////////////////////// // ENUMS ///////////////////////////////////////////////////////////////// @@ -230,26 +262,30 @@ private: //------------------------------------------------------------------- // LIFECYCLE ///////////////////////////////////////////////////////////// // METHODS /////////////////////////////////////////////////////////////// // DATA MEMBERS /////////////////////////////////////////////////////////// - /** The current context name */ - std::string m_ctxName; - /** The configured procedure search path */ - std::string m_procPath; - /** The configured library path */ - std::string m_libPath; - /** Map of identifiers to names */ - ProcMap m_idToName; - /** Map of names to identifiers */ - ProcMap m_nameToId; - /** Map of filenames to identifiers */ - ProcMap m_filenameToId; - /** Map of identifiers to filenames */ - ProcMap m_idToFilename; - /** Map of identifiers and procedure models */ - ProcModels m_procModels; - /** Map of identifiers and library models */ - LibModels m_libModels; - /** Synchronization lock */ - SPELLmutex m_lock; + /** The current context name */ + std::string m_ctxName; + /** The configured procedure search path */ + std::string m_procPath; + /** The configured library path */ + std::string m_libPath; + /** The configured service path */ + std::string m_servicePath; + /** Map of identifiers to names */ + ProcMap m_idToName; + /** Map of names to identifiers */ + ProcMap m_nameToId; + /** Map of filenames to identifiers */ + ProcMap m_filenameToId; + /** Map of identifiers to filenames */ + ProcMap m_idToFilename; + /** Map of identifiers and procedure models */ + ProcModels m_procModels; + /** Map of identifiers and Spell service models */ + ServiceModelMap m_serviceModels; + /** Map of identifiers and library models */ + LibModels m_libModels; + /** Synchronization lock */ + SPELLmutex m_lock; }; /*@}*/ diff --git a/include/SPELL_PRD/SPELLprocedureSourceCode.H b/include/SPELL_PRD/SPELLprocedureSourceCode.H index 8375c09..0d5a250 100644 --- a/include/SPELL_PRD/SPELLprocedureSourceCode.H +++ b/include/SPELL_PRD/SPELLprocedureSourceCode.H @@ -5,7 +5,7 @@ // DESCRIPTION: Procedure source code model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -64,7 +64,6 @@ public: //-------------------------------------------------------------------- SPELLprocedureSourceCode( const std::string filename ) { m_filename = filename; - m_source = ""; m_sourceLines.clear(); } @@ -80,23 +79,12 @@ public: //-------------------------------------------------------------------- return m_filename; } ; - ////////////////////////////////////////////////////////////////////// - /** Obtain the procedure source code. - * - * \returns The procedure source code. - **//////////////////////////////////////////////////////////////////// - const std::string getSourceCode() const { - return m_source; - }; - ////////////////////////////////////////////////////////////////////// /** Obtain the procedure source code lines. * * \returns The procedure source code lines. **//////////////////////////////////////////////////////////////////// - const std::vector getSourceCodeLines() const { - return m_sourceLines; - }; + const std::vector getSourceCodeLines(); // DATA MEMBERS ////////////////////////////////////////////////////////// @@ -119,7 +107,6 @@ protected: //----------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void addSourceCodeLine( const std::string& sourceLine ) { - m_source += sourceLine + "\n"; m_sourceLines.push_back(sourceLine); }; @@ -128,7 +115,6 @@ protected: //----------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void clear() { - m_source = ""; m_sourceLines.clear(); }; @@ -142,8 +128,6 @@ private: //------------------------------------------------------------------- // DATA MEMBERS ////////////////////////////////////////////////////////// /** Procedure file name */ std::string m_filename; - /** Procedure source code */ - std::string m_source; /** Procedure source code splitted in lines */ std::vector m_sourceLines; }; diff --git a/include/SPELL_PRD/SPELLpyService.H b/include/SPELL_PRD/SPELLpyService.H new file mode 100644 index 0000000..9e2da78 --- /dev/null +++ b/include/SPELL_PRD/SPELLpyService.H @@ -0,0 +1,160 @@ +// ################################################################################ +// FILE : SPELLservice.H +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Service model +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_PY_SERVICE_H__ +#define __SPELL_PY_SERVICE_H__ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" +#include "SPELL_PRD/SPELLprocedureSourceCode.H" +// Local includes ---------------------------------------------------------- + +// Project includes -------------------------------------------------------- + +/** \defgroup SPELL_PRD Service management (SPELL_PRD) + * + * This module provides mechanisms for reading procedure files and libraries, + * getting their source code and properties, etc. + * + * */ +/*@{*/ + +// FORWARD REFERENCES ////////////////////////////////////////////////////// +// TYPES /////////////////////////////////////////////////////////////////// +// DEFINES ///////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +/** + ** \brief Model of a spell service. + ** + ** \par Description and usage: + ** + ** Used by the procedure manager to keep track of all available + ** services and their related information. + ** + ** The SPELLprocedureManager creates one model per service found in + ** the service search path. + ** + **//////////////////////////////////////////////////////////////////////////// +class SPELLpyService +{ +public: + //-------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + + // LIFECYCLE ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + /** Constructor + * + * \param procPath IN: procedure path + * \param file IN: file name. + **//////////////////////////////////////////////////////////////////// + SPELLpyService(PyObject* serviceImpl); + + ////////////////////////////////////////////////////////////////////// + /** Destructor + **//////////////////////////////////////////////////////////////////// + ~SPELLpyService(); + + // STATIC //////////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + std::string getName() const + { + return m_name; + } + + std::string getBasePath() const + { + return m_basePath; + } + std::string getMainServiceFile() const + { + return m_mainServiceFile; + } + + void setBasePath(std::string basePath) + { + m_basePath = basePath; + } + + bool useCommandOverride() const; + + std::string getCommandOverride(int startTimeout, int loginTimeout, std::string config, std::string contextName, int ipcPort, std::string instanceId, + std::string warmstartFile) const; + + void startWatchDog(void (*callback)(std::string&)); + + void start(); + + PyObject* getStartFunction() const; + // DATA MEMBERS ////////////////////////////////////////////////////////// + + PyObject* getService() const{ + Py_INCREF(m_service); + return m_service; + } + + ////////////////////////////////////////////////////////////////////// + /** Obtain the procedure source code. + * + * \returns The procedure source code. + **//////////////////////////////////////////////////////////////////// + SPELLprocedureSourceCode getSourceCode() const { + return m_source; + }; +protected: + //----------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + + // DATA MEMBERS ////////////////////////////////////////////////////////// + +private: + //------------------------------------------------------------------- + + // EXCEPTIONS //////////////////////////////////////////////////////////// + // ENUMS ///////////////////////////////////////////////////////////////// + // TYPES ///////////////////////////////////////////////////////////////// + // LIFECYCLE ///////////////////////////////////////////////////////////// + // METHODS /////////////////////////////////////////////////////////////// + // DATA MEMBERS ////////////////////////////////////////////////////////// + PyObject* m_service; + SPELLprocedureSourceCode m_source; + std::string m_name; + std::string m_basePath; + std::string m_mainServiceFile; +}; + +/*@}*/ +#endif diff --git a/include/SPELL_PRD/SPELLservicePython.H b/include/SPELL_PRD/SPELLservicePython.H new file mode 100644 index 0000000..f3379e7 --- /dev/null +++ b/include/SPELL_PRD/SPELLservicePython.H @@ -0,0 +1,59 @@ +// ################################################################################ +// FILE : SPELLSpellService.H +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the SpellService mechanism +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_SpellPyService_H__ +#define __SPELL_SpellPyService_H__ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +// Local includes ---------------------------------------------------------- +// Project includes -------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" + +/** \addtogroup SPELL_CTX */ +/*@{*/ + + +// FORWARD REFERENCES ////////////////////////////////////////////////////// +// TYPES /////////////////////////////////////////////////////////////////// + +/** Python binding for the SpellService object */ +typedef struct PySpellServiceObject_ +{ + PyObject_HEAD; +} +PySpellServiceObject; + + +/** Install the SpellService binding on the Python layer */ +void SpellService_Install(); + +// DEFINES ///////////////////////////////////////////////////////////////// + + + +/*@}*/ +#endif diff --git a/include/SPELL_PRD/SPELLserviceWatchdogPython.H b/include/SPELL_PRD/SPELLserviceWatchdogPython.H new file mode 100644 index 0000000..0bcecfb --- /dev/null +++ b/include/SPELL_PRD/SPELLserviceWatchdogPython.H @@ -0,0 +1,57 @@ +// ################################################################################ +// FILE : SPELLSpellService.H +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the SpellService mechanism +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +#ifndef __SPELL_SpellPyServiceWatchdog_H__ +#define __SPELL_SpellPyServiceWatchdog_H__ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +// Local includes ---------------------------------------------------------- +// Project includes -------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" + +/** \addtogroup SPELL_CTX */ +/*@{*/ + + +// FORWARD REFERENCES ////////////////////////////////////////////////////// +// TYPES /////////////////////////////////////////////////////////////////// + +/** Python binding for the SpellService object */ +typedef struct PySpellServiceWatchdogObject_ +{ + PyObject_HEAD; + PyObject *callback; +} +PySpellServiceWatchdogObject; + + +// DEFINES ///////////////////////////////////////////////////////////////// +PyObject* SpellServiceWatchdog_Create(void (*callback)(std::string&)); + + +/*@}*/ +#endif diff --git a/include/SPELL_SDB/SPELLdatabase.H b/include/SPELL_SDB/SPELLdatabase.H index d142567..8ccfd60 100644 --- a/include/SPELL_SDB/SPELLdatabase.H +++ b/include/SPELL_SDB/SPELLdatabase.H @@ -5,7 +5,7 @@ // DESCRIPTION: Base class of SPELL databases // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SDB/SPELLdatabaseFactory.H b/include/SPELL_SDB/SPELLdatabaseFactory.H index cf0109e..08aa558 100644 --- a/include/SPELL_SDB/SPELLdatabaseFactory.H +++ b/include/SPELL_SDB/SPELLdatabaseFactory.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL database factory // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SDB/SPELLdatabaseFile.H b/include/SPELL_SDB/SPELLdatabaseFile.H index 77e0dfd..8ab6e82 100644 --- a/include/SPELL_SDB/SPELLdatabaseFile.H +++ b/include/SPELL_SDB/SPELLdatabaseFile.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL database based on local files // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SDB/SPELLdatabaseFileSPB.H b/include/SPELL_SDB/SPELLdatabaseFileSPB.H index 94147e8..4b2e6b3 100644 --- a/include/SPELL_SDB/SPELLdatabaseFileSPB.H +++ b/include/SPELL_SDB/SPELLdatabaseFileSPB.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL database based on SPB local files // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SDB/SPELLpyDatabaseObject.H b/include/SPELL_SDB/SPELLpyDatabaseObject.H index 03daf22..f3f2765 100644 --- a/include/SPELL_SDB/SPELLpyDatabaseObject.H +++ b/include/SPELL_SDB/SPELLpyDatabaseObject.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL database Python extension // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -218,8 +218,7 @@ PyObject* SPELLpyDatabase_IterLen( PyDatabaseIteratorObject* iterator ); #define DATABASE_DEFINITION(__type__,__name__,__doc__) \ static PyTypeObject __type__ = \ { \ - PyObject_HEAD_INIT(NULL) /* basic object head */ \ - 0, /* var objects */ \ + PyVarObject_HEAD_INIT(NULL,0) /* basic object head */ \ __name__, /* type name */ \ sizeof(PyDatabaseObject), /* type size */ \ 0, /* item size */ \ @@ -278,7 +277,7 @@ PyObject* SPELLpyDatabase_IterLen( PyDatabaseIteratorObject* iterator ); err += std::string(__type__.tp_name); \ PyErr_SetString( PyExc_RuntimeError, err.c_str()); \ std::cerr << "ERROR: " << err << std::endl; \ - return; \ + return MOD_ERROR_VAL; \ } /** Convenience macro to load a new type into the given module */ diff --git a/include/SPELL_SYN/SPELLcondition.H b/include/SPELL_SYN/SPELLcondition.H index d743eaa..6f3b592 100644 --- a/include/SPELL_SYN/SPELLcondition.H +++ b/include/SPELL_SYN/SPELLcondition.H @@ -5,7 +5,7 @@ // DESCRIPTION: Condition mechanism wrapper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLconditionFactory.H b/include/SPELL_SYN/SPELLconditionFactory.H index 126e797..424fd6a 100644 --- a/include/SPELL_SYN/SPELLconditionFactory.H +++ b/include/SPELL_SYN/SPELLconditionFactory.H @@ -5,7 +5,7 @@ // DESCRIPTION: Factory of conditions // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLconditionIF.H b/include/SPELL_SYN/SPELLconditionIF.H index 9ed1ba5..9152569 100644 --- a/include/SPELL_SYN/SPELLconditionIF.H +++ b/include/SPELL_SYN/SPELLconditionIF.H @@ -5,7 +5,7 @@ // DESCRIPTION: Condition interface definition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLconditionPOSIX.H b/include/SPELL_SYN/SPELLconditionPOSIX.H index 0a58d31..963bb44 100644 --- a/include/SPELL_SYN/SPELLconditionPOSIX.H +++ b/include/SPELL_SYN/SPELLconditionPOSIX.H @@ -5,7 +5,7 @@ // DESCRIPTION: POSIX implementation of condition mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLevent.H b/include/SPELL_SYN/SPELLevent.H index cae3c52..bba34a5 100644 --- a/include/SPELL_SYN/SPELLevent.H +++ b/include/SPELL_SYN/SPELLevent.H @@ -5,7 +5,7 @@ // DESCRIPTION: Event mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLmonitor.H b/include/SPELL_SYN/SPELLmonitor.H index 428e9eb..6aacfec 100644 --- a/include/SPELL_SYN/SPELLmonitor.H +++ b/include/SPELL_SYN/SPELLmonitor.H @@ -5,7 +5,7 @@ // DESCRIPTION: Monitor mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLmutex.H b/include/SPELL_SYN/SPELLmutex.H index 50ef616..23ce473 100644 --- a/include/SPELL_SYN/SPELLmutex.H +++ b/include/SPELL_SYN/SPELLmutex.H @@ -5,7 +5,7 @@ // DESCRIPTION: Mutex mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLmutexFactory.H b/include/SPELL_SYN/SPELLmutexFactory.H index 136a6aa..762a0c7 100644 --- a/include/SPELL_SYN/SPELLmutexFactory.H +++ b/include/SPELL_SYN/SPELLmutexFactory.H @@ -5,7 +5,7 @@ // DESCRIPTION: Factory for mutexes // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLmutexIF.H b/include/SPELL_SYN/SPELLmutexIF.H index 88d5122..0a4014a 100644 --- a/include/SPELL_SYN/SPELLmutexIF.H +++ b/include/SPELL_SYN/SPELLmutexIF.H @@ -5,7 +5,7 @@ // DESCRIPTION: Mutex interface definition // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLmutexPOSIX.H b/include/SPELL_SYN/SPELLmutexPOSIX.H index 1661028..7690dcc 100644 --- a/include/SPELL_SYN/SPELLmutexPOSIX.H +++ b/include/SPELL_SYN/SPELLmutexPOSIX.H @@ -5,7 +5,7 @@ // DESCRIPTION: POSIX implementation for mutex // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLqueue.H b/include/SPELL_SYN/SPELLqueue.H index f7facce..6cf7485 100644 --- a/include/SPELL_SYN/SPELLqueue.H +++ b/include/SPELL_SYN/SPELLqueue.H @@ -5,7 +5,7 @@ // DESCRIPTION: Queue mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLsyncError.H b/include/SPELL_SYN/SPELLsyncError.H index cc9bbdc..f9cb76b 100644 --- a/include/SPELL_SYN/SPELLsyncError.H +++ b/include/SPELL_SYN/SPELLsyncError.H @@ -5,7 +5,7 @@ // DESCRIPTION: Synchronization error // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLthread.H b/include/SPELL_SYN/SPELLthread.H index d6dd68e..63aa5d3 100644 --- a/include/SPELL_SYN/SPELLthread.H +++ b/include/SPELL_SYN/SPELLthread.H @@ -5,7 +5,7 @@ // DESCRIPTION: Thread mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLthreadPool.H b/include/SPELL_SYN/SPELLthreadPool.H index 933f377..bb21ddc 100644 --- a/include/SPELL_SYN/SPELLthreadPool.H +++ b/include/SPELL_SYN/SPELLthreadPool.H @@ -5,7 +5,7 @@ // DESCRIPTION: Thread pool mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLthreadWork.H b/include/SPELL_SYN/SPELLthreadWork.H index f50e641..1d57c2b 100644 --- a/include/SPELL_SYN/SPELLthreadWork.H +++ b/include/SPELL_SYN/SPELLthreadWork.H @@ -5,7 +5,7 @@ // DESCRIPTION: Thread worker for thread pools // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLthreadWorker.H b/include/SPELL_SYN/SPELLthreadWorker.H index af6c14c..d60e2c5 100644 --- a/include/SPELL_SYN/SPELLthreadWorker.H +++ b/include/SPELL_SYN/SPELLthreadWorker.H @@ -5,7 +5,7 @@ // DESCRIPTION: Thread worker for thread pools // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_SYN/SPELLtimer.H b/include/SPELL_SYN/SPELLtimer.H index e7c0e05..975b7ac 100644 --- a/include/SPELL_SYN/SPELLtimer.H +++ b/include/SPELL_SYN/SPELLtimer.H @@ -5,7 +5,7 @@ // DESCRIPTION: Timer mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_UTIL/SPELLbase.H b/include/SPELL_UTIL/SPELLbase.H index 8e8a32a..3b2c062 100644 --- a/include/SPELL_UTIL/SPELLbase.H +++ b/include/SPELL_UTIL/SPELLbase.H @@ -5,7 +5,7 @@ // DESCRIPTION: Base includes for SPELL framework // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -58,6 +58,7 @@ #include #include #include +#include #include "log4cplus/appender.h" #include "log4cplus/fileappender.h" #include "log4cplus/layout.h" @@ -89,5 +90,50 @@ // DEFINES ///////////////////////////////////////////////////////////////// #define BYTE unsigned char +//Python 3 Compatibility +#if PY_MAJOR_VERSION >= 3 +#define PyString_AsString PyUnicode_AsUTF8 +#define PyString_CheckExact PyUnicode_CheckExact +#define PyString_FromString PyUnicode_FromString +#define PyString_Check PyUnicode_Check +#define PyString_Size PyUnicode_GetLength +#define PyString_AsStringAndSize PyBytes_AsStringAndSize +#define CHAR wchar_t +#define PyInt_Check PyLong_Check +#define PyInt_AsLong PyLong_AsLong +#define PyInt_FromSize_t PyLong_FromSize_t +#define PyInt_FromLong PyLong_FromLong +#define PyClass_Check(value) PyObject_IsInstance(value, (PyObject *)&PyType_Type) +#define PyInstance_Check(value) PyObject_IsInstance(value, (PyObject *)&PyBaseObject_Type) +#define PyInt_CheckExact PyLong_CheckExact +#define PyInt_AS_LONG PyLong_AS_LONG + +#define PyFloat_FromString(floatObj,pend) PyFloat_FromString(floatObj) + +#define PyEval_EvalCode(code,globals,locals) PyEval_EvalCode((PyObject*)code,globals,locals) + +#define MOD_ERROR_VAL NULL +#define MOD_SUCCESS_VAL(val) val +#define MOD_NAME(name) #name"_v3" +#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name##_v3(void) +#define MOD_DEF(ob, name, doc, methods) \ + static struct PyModuleDef moduledef = { \ + PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \ + ob = PyModule_Create(&moduledef); \ + if (ob == NULL) \ + return NULL; +#define BUILTINS "builtins" +#else +#define BUILTINS "__builtin__" +#define CHAR char +#define MOD_ERROR_VAL +#define MOD_SUCCESS_VAL(val) +#define MOD_NAME(name) #name"_v2" +#define MOD_INIT(name) PyMODINIT_FUNC init##name##_v2(void) +#define MOD_DEF(ob, name, doc, methods) \ + ob = Py_InitModule3(name, methods, doc); +#define _Py_CODEUNIT unsigned char +#endif + /*@}*/ #endif diff --git a/include/SPELL_UTIL/SPELLcompression.H b/include/SPELL_UTIL/SPELLcompression.H index 17bd5d6..5d03267 100644 --- a/include/SPELL_UTIL/SPELLcompression.H +++ b/include/SPELL_UTIL/SPELLcompression.H @@ -5,7 +5,7 @@ // DESCRIPTION: General utilities // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_UTIL/SPELLerror.H b/include/SPELL_UTIL/SPELLerror.H index e4b9eb9..58e7014 100644 --- a/include/SPELL_UTIL/SPELLerror.H +++ b/include/SPELL_UTIL/SPELLerror.H @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL core exceptions // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/include/SPELL_UTIL/SPELLlog.H b/include/SPELL_UTIL/SPELLlog.H index eb9a582..9a94602 100644 --- a/include/SPELL_UTIL/SPELLlog.H +++ b/include/SPELL_UTIL/SPELLlog.H @@ -5,7 +5,7 @@ // DESCRIPTION: Executor logging mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -30,6 +30,7 @@ // FILES TO INCLUDE //////////////////////////////////////////////////////// // Local includes ---------------------------------------------------------- // Project includes -------------------------------------------------------- +#include "SPELL_UTIL/SPELLutils.H" #include "SPELL_SYN/SPELLmutex.H" // System includes --------------------------------------------------------- @@ -202,19 +203,19 @@ static const std::string LOG_LEVEL_LBL[] = ** \brief Log an information message. ** *//////////////////////////////////////////////////////////////////////////// -#define LOG_INFO(x) log4cplus::Logger::getRoot().log(log4cplus::INFO_LOG_LEVEL, x, __FILE__, __LINE__ ) +#define LOG_INFO(x) log4cplus::Logger::getRoot().log(log4cplus::INFO_LOG_LEVEL, x, __FILE__, __LINE__, NULL ) ////////////////////////////////////////////////////////////////////////////// /** ** \brief Log a warning message. ** *//////////////////////////////////////////////////////////////////////////// -#define LOG_WARN(x) log4cplus::Logger::getRoot().log(log4cplus::WARN_LOG_LEVEL, x, __FILE__, __LINE__ ) +#define LOG_WARN(x) log4cplus::Logger::getRoot().log(log4cplus::WARN_LOG_LEVEL, x, __FILE__, __LINE__, NULL ) ////////////////////////////////////////////////////////////////////////////// /** ** \brief Log an error message. ** *//////////////////////////////////////////////////////////////////////////// -#define LOG_ERROR(x) log4cplus::Logger::getRoot().log(log4cplus::ERROR_LOG_LEVEL, x, __FILE__, __LINE__ ) +#define LOG_ERROR(x) log4cplus::Logger::getRoot().log(log4cplus::ERROR_LOG_LEVEL, x, __FILE__, __LINE__, NULL ) ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -242,8 +243,9 @@ static const std::string LOG_LEVEL_LBL[] = ** the \c WITH_DEBUG macro is defined. ** *//////////////////////////////////////////////////////////////////////////// + #ifdef WITH_DEBUG -#define DEBUG(x) log4cplus::Logger::getRoot().log(log4cplus::DEBUG_LOG_LEVEL, x, __FILE__, __LINE__ ) +#define DEBUG(x) log4cplus::Logger::getRoot().log(log4cplus::DEBUG_LOG_LEVEL, x, __FILE__, __LINE__ ); #else #define DEBUG(x) #endif diff --git a/include/SPELL_UTIL/SPELLpyArgs.H b/include/SPELL_UTIL/SPELLpyArgs.H index e07eb4b..a092f15 100644 --- a/include/SPELL_UTIL/SPELLpyArgs.H +++ b/include/SPELL_UTIL/SPELLpyArgs.H @@ -5,7 +5,7 @@ // DESCRIPTION: Utility for Python arguments processing // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -30,6 +30,7 @@ // FILES TO INCLUDE //////////////////////////////////////////////////////// // Local includes ---------------------------------------------------------- // Project includes -------------------------------------------------------- +#include "SPELL_UTIL/SPELLutils.H" #include "SPELL_UTIL/SPELLtime.H" // System includes --------------------------------------------------------- @@ -234,6 +235,20 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// std::string getModifier_HiYel() const; + ////////////////////////////////////////////////////////////////////// + /** Obtain the value of the Select modifier. + * + * \return The modifier value. + **//////////////////////////////////////////////////////////////////// + std::string getModifier_Select() const; + + ////////////////////////////////////////////////////////////////////// + /** Obtain the value of the Type modifier for Limits. + * + * \return The modifier value. + **//////////////////////////////////////////////////////////////////// + std::string getModifier_LimitType() const; + ////////////////////////////////////////////////////////////////////// /** Obtain the value of the Message modifier. * @@ -288,6 +303,7 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// std::string getModifier_Default() const; + // DATA MEMBERS ////////////////////////////////////////////////////////// protected: //----------------------------------------------------------------- diff --git a/include/SPELL_UTIL/SPELLpythonHelper.H b/include/SPELL_UTIL/SPELLpythonHelper.H index 7bdecca..8c56fba 100644 --- a/include/SPELL_UTIL/SPELLpythonHelper.H +++ b/include/SPELL_UTIL/SPELLpythonHelper.H @@ -5,7 +5,7 @@ // DESCRIPTION: Python utilities and manipulation functions // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -118,6 +118,18 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// void importAllFrom( const std::string& package ); + ////////////////////////////////////////////////////////////////////// + /** Import all items from the given package into the builtins package. + * + * \throws SPELLcoreException if the given module cannot be imported. + * \throws SPELLcoreException if the __main__ module cannot be accessed. + * \throws SPELLcoreException if the __main__ module dictionary cannot be accessed. + * + * \param package IN: the package to import objects from. + **//////////////////////////////////////////////////////////////////// + void updateBuiltinsWith( const std::string& package ); + + ////////////////////////////////////////////////////////////////////// /** Import an user library module * @@ -127,7 +139,7 @@ public: //-------------------------------------------------------------------- * * \param package IN: the package to import objects from. **//////////////////////////////////////////////////////////////////// - void importUserLibraries( const std::string& libraryPath ); + bool importUserLibraries( const std::string& libraryPath, std::string& errors ); ////////////////////////////////////////////////////////////////////// /** Install an object in main dictionary @@ -210,7 +222,9 @@ public: //-------------------------------------------------------------------- **//////////////////////////////////////////////////////////////////// PyFrameObject* createFrame( const std::string& filename, PyCodeObject* code ); - ////////////////////////////////////////////////////////////////////// + PyFrameObject* createFrameFromFunction( const std::string& filename, PyObject* func ); + + ////////////////////////////////////////////////////////////////////// /** Call the given method of the given object, with variable arguments * * \param obj IN: object providing the desired method. diff --git a/include/SPELL_UTIL/SPELLpythonMonitors.H b/include/SPELL_UTIL/SPELLpythonMonitors.H index 5eba813..3d9add8 100644 --- a/include/SPELL_UTIL/SPELLpythonMonitors.H +++ b/include/SPELL_UTIL/SPELLpythonMonitors.H @@ -5,7 +5,7 @@ // DESCRIPTION: Python safe operation monitors // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -59,14 +59,71 @@ class SPELLsafePythonOperations public: SPELLsafePythonOperations( const std::string& where ) { - //std::cerr << "PYTHON OPERATIONS IN " << where << std::endl; + //std::cerr << "PYTHON OPERATIONS TRY-IN " << where << std::endl; m_state = SPELLpythonHelper::instance().acquireGIL(); + //std::cerr << ">>PYTHON OPERATIONS IN " << where << std::endl; m_where = where; }; - ~SPELLsafePythonOperations() + virtual ~SPELLsafePythonOperations() noexcept(false) { + PyObject* err = PyErr_Occurred(); + if (err != NULL) + { + std::cerr << std::endl << "===============================" << std::endl; + //PyErr_Print(); + PyObject* ptype; + PyObject* pvalue; + PyObject* ptraceback; + PyErr_Fetch( &ptype, &pvalue, &ptraceback ); + std::cerr << "TYPE : " << PYREPR(ptype) << std::endl; + std::cerr << "VALUE: " << PYREPR(pvalue) << std::endl; + if (ptraceback) + { + std::cerr << "Traceback: " << std::endl; + PyTracebackObject* traceback = (PyTracebackObject*) ptraceback; + while(traceback != NULL) + { + std::cerr << "at " << PYREPR(traceback->tb_frame->f_code->co_filename) << ":" << traceback->tb_lineno << std::endl; + traceback = traceback->tb_next; + } + } + std::cerr << "===============================" << std::endl << std::endl; + // Parse the exception to give better information about the error on python side + PyObject* spellException = SPELLpythonHelper::instance().getObject("spell.lib.exception", "SpellException"); + std::string excType = PYREPR(ptype); + if (PyObject_IsInstance( pvalue, spellException )) + { + PyObject* msg = PyObject_GetAttrString( pvalue, "message" ); + PyObject* rea = PyObject_GetAttrString( pvalue, "reason" ); + std::string message = ""; + std::string reason = ""; + if (msg != NULL) + { + message = PYSSTR(msg); + } + if (rea != NULL ) + { + reason = PYSSTR(rea); + } + /** \todo decide the fatal flag value */ + std::cerr << "RAISING INTERNAL DRIVER EXCEPTION" << std::endl; + PyErr_Clear(); + THROW_EXCEPTION("Driver error: " + message, reason, SPELL_DRIVER_ERROR ); + } + else if ( PYSTR(pvalue) == "EXECUTION ABORTED" || PYSTR(pvalue) == "EXECUTION TERMINATED" ) + { + // Do not raise exceptions if the detected exception is an aborted or finished internal exception + return; + } + else + { + std::cerr << "RAISING PYTHON ERROR EXCEPTION" << std::endl; + PyErr_Clear(); + THROW_EXCEPTION("Python error", PYSSTR(PyObject_Str(pvalue)), SPELL_ERROR_PYTHON_API ); + } + } SPELLpythonHelper::instance().releaseGIL(m_state); - //std::cerr << "PYTHON OPERATIONS OUT " << m_where << std::endl; + //std::cerr << "<. +# +################################################################################ -if WITH_LIBS SUBDIRS = SPELL_UTIL \ SPELL_SYN \ SPELL_CFG \ @@ -13,22 +31,8 @@ SUBDIRS = SPELL_UTIL \ SPELL_SDB \ SPELL_DTA \ SPELL_EXC \ - SPELL_WS - -if WITH_EXECUTOR -SUBDIRS += SPELL_CIFS -endif - -if WITH_EXECUTOR_CMD -SUBDIRS += SPELL_CIFC -endif - -if WITH_CONTEXT -SUBDIRS += SPELL_CTX -endif - -if WITH_LISTENER -SUBDIRS += SPELL_LST -endif - -endif + SPELL_WS \ + SPELL_CIFS \ + SPELL_CIFC \ + SPELL_CTX \ + SPELL_LST diff --git a/lib/SPELL_CFG/Makefile.am b/lib/SPELL_CFG/Makefile.am index 1b326a2..d8a92f2 100644 --- a/lib/SPELL_CFG/Makefile.am +++ b/lib/SPELL_CFG/Makefile.am @@ -1,37 +1,47 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_CFG.la -libSPELL_CFG_la_LDFLAGS = -version-info 3:0:0 -libSPELL_CFG_la_SOURCES = \ - src/SPELLxmlConfigReaderFactory.C \ - src/SPELLxmlConfigReaderXC.C \ - src/SPELLconfiguration.C \ - src/SPELLcontextConfig.C \ - src/SPELLdriverConfig.C \ - src/SPELLbrowsableLibMode.C - + +lib_LTLIBRARIES = libSPELL_CFG_v2.la libSPELL_CFG_v3.la + +libSPELL_CFG_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_CFG_v2_la_CDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_CFG_v2_la_SOURCES = src/SPELLxmlConfigReaderFactory.C \ + src/SPELLxmlConfigReaderXC.C \ + src/SPELLconfiguration.C \ + src/SPELLcontextConfig.C \ + src/SPELLdriverConfig.C \ + src/SPELLbrowsableLibMode.C + + +libSPELL_CFG_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_CFG_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_CFG_v3_la_SOURCES = src/SPELLxmlConfigReaderFactory.C \ + src/SPELLxmlConfigReaderXC.C \ + src/SPELLconfiguration.C \ + src/SPELLcontextConfig.C \ + src/SPELLdriverConfig.C \ + src/SPELLbrowsableLibMode.C \ No newline at end of file diff --git a/lib/SPELL_CFG/src/SPELLbrowsableLibMode.C b/lib/SPELL_CFG/src/SPELLbrowsableLibMode.C index e819ae1..4d48f74 100644 --- a/lib/SPELL_CFG/src/SPELLbrowsableLibMode.C +++ b/lib/SPELL_CFG/src/SPELLbrowsableLibMode.C @@ -5,7 +5,7 @@ // DESCRIPTION: // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -39,9 +39,6 @@ std::string s_BROWSABLELIB_MODE_STR[] = "Disabled" }; -unsigned int s_NUM_MODES = sizeof(s_BROWSABLELIB_MODE_STR) / sizeof(std::string); - - // Methods @@ -51,6 +48,7 @@ unsigned int s_NUM_MODES = sizeof(s_BROWSABLELIB_MODE_STR) / sizeof(std::string) SPELLbrowsableLibMode stringToBrowsableLibMode( const std::string& mode ) { unsigned int index = 0; + unsigned int s_NUM_MODES = sizeof(s_BROWSABLELIB_MODE_STR) / sizeof(std::string); for( index = 0; index < s_NUM_MODES; index++) { diff --git a/lib/SPELL_CFG/src/SPELLconfiguration.C b/lib/SPELL_CFG/src/SPELLconfiguration.C index 7ba8d4c..50f1fb1 100644 --- a/lib/SPELL_CFG/src/SPELLconfiguration.C +++ b/lib/SPELL_CFG/src/SPELLconfiguration.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the configuration reader // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CFG/src/SPELLcontextConfig.C b/lib/SPELL_CFG/src/SPELLcontextConfig.C index 2553e19..725e9c8 100644 --- a/lib/SPELL_CFG/src/SPELLcontextConfig.C +++ b/lib/SPELL_CFG/src/SPELLcontextConfig.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the context configuration model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -37,6 +37,7 @@ // GLOBALS ///////////////////////////////////////////////////////////////// const std::string SPELLcontextConfig::ExecutorProgram = "ExecutorProgram"; +const std::string SPELLcontextConfig::ServiceProgram = "ServiceProgram"; const std::string SPELLcontextConfig::ExecutorStartTimeout = "ExecutorStartTimeout"; const std::string SPELLcontextConfig::ExecutorLoginTimeout = "ExecutorLoginTimeout"; const std::string SPELLcontextConfig::UseDriverTime = "UseDriverTime"; @@ -57,6 +58,7 @@ SPELLcontextConfig::SPELLcontextConfig( const std::string& contextFile ) m_gcs = "unknown"; m_family = "unknown"; m_procPath = "unknown"; + m_servicePath = "unknown"; m_libPath = "unknown"; m_outputDir = ""; m_inputDir = ""; @@ -178,6 +180,18 @@ void SPELLcontextConfig::loadBasics() m_libPath = ""; } + list = m_reader->findElementsByName( XMLTags::TAG_CTX_SPATH ); + if (list.size()==1) + { + node = *(list.begin()); + m_servicePath = node->getValue(); + dealloc_list(list); + } + else + { + m_servicePath = "Services"; + } + list = m_reader->findElementsByName( XMLTags::TAG_CTX_OPATH ); if (list.size()==1) { diff --git a/lib/SPELL_CFG/src/SPELLdriverConfig.C b/lib/SPELL_CFG/src/SPELLdriverConfig.C index 69668a3..186a661 100644 --- a/lib/SPELL_CFG/src/SPELLdriverConfig.C +++ b/lib/SPELL_CFG/src/SPELLdriverConfig.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the driver configuration model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CFG/src/SPELLexecutorDefaults.C b/lib/SPELL_CFG/src/SPELLexecutorDefaults.C index 56db148..abc9e93 100644 --- a/lib/SPELL_CFG/src/SPELLexecutorDefaults.C +++ b/lib/SPELL_CFG/src/SPELLexecutorDefaults.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the context execution defaults. // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -42,14 +42,17 @@ SPELLexecutorDefaults::SPELLexecutorDefaults( const SPELLexecutorDefaults& from LOG_INFO("[CTX] Copied Executor Defaults for " + m_ctxName); m_execDelay = from.getExecDelay(); - m_promptWarningDelay = from.getpromptWarningDelay(); + m_promptWarningDelay = from.getPromptWarningDelay(); m_runInto = from.isRunInto(); m_byStep = from.isByStep(); m_browsableLib = from.getBrowsableLib(); m_maxVerbosity = from.getMaxVerbosity(); - m_forceTcConfirm = from.getForceTcConfirm(); + m_forceTcConfirm = from.isForceTcConfirm(); + m_forcePromptConfirm = from.isForcePromptConfirm(); m_saveStateMode = from.getSaveStateMode(); m_watchVariables = from.isWatchVariables(); + m_resourcesDisplay = from.isResourcesDisplay(); + m_localResourceSupport = from.isLocalResourcesSupported(); m_ctxName = from.getCtxName(); } //copy constructor diff --git a/lib/SPELL_CFG/src/SPELLxmlConfigReaderFactory.C b/lib/SPELL_CFG/src/SPELLxmlConfigReaderFactory.C index af1c71e..cd6c56c 100644 --- a/lib/SPELL_CFG/src/SPELLxmlConfigReaderFactory.C +++ b/lib/SPELL_CFG/src/SPELLxmlConfigReaderFactory.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the configuration reader factory // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CFG/src/SPELLxmlConfigReaderXC.C b/lib/SPELL_CFG/src/SPELLxmlConfigReaderXC.C index ae370df..7638235 100644 --- a/lib/SPELL_CFG/src/SPELLxmlConfigReaderXC.C +++ b/lib/SPELL_CFG/src/SPELLxmlConfigReaderXC.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the configuration reader with Xerces-C // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CIF/Makefile.am b/lib/SPELL_CIF/Makefile.am index ab595e1..1e1fa1f 100644 --- a/lib/SPELL_CIF/Makefile.am +++ b/lib/SPELL_CIF/Makefile.am @@ -1,35 +1,46 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_CIF.la -libSPELL_CIF_la_LDFLAGS = -version-info 3:0:0 -libSPELL_CIF_la_SOURCES = \ - src/SPELLcif.C \ - src/SPELLcifPython.C \ - src/SPELLcifHelper.C \ - src/SPELLasRun.C \ - src/SPELLnotifications.C + +lib_LTLIBRARIES = libSPELL_CIF_v2.la libSPELL_CIF_v3.la + +libSPELL_CIF_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_CIF_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_CIF_v2_la_SOURCES = src/SPELLcif.C \ + src/SPELLcifPython.C \ + src/SPELLcifHelper.C \ + src/SPELLasRun.C \ + src/SPELLnotifications.C + +libSPELL_CIF_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_CIF_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_CIF_v3_la_SOURCES = src/SPELLcif.C \ + src/SPELLcifPython.C \ + src/SPELLcifHelper.C \ + src/SPELLasRun.C \ + src/SPELLnotifications.C + + \ No newline at end of file diff --git a/lib/SPELL_CIF/src/SPELLasRun.C b/lib/SPELL_CIF/src/SPELLasRun.C index aa739ac..d7e5ba2 100644 --- a/lib/SPELL_CIF/src/SPELLasRun.C +++ b/lib/SPELL_CIF/src/SPELLasRun.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the As-RUN interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CIF/src/SPELLcif.C b/lib/SPELL_CIF/src/SPELLcif.C index 525a289..2468767 100644 --- a/lib/SPELL_CIF/src/SPELLcif.C +++ b/lib/SPELL_CIF/src/SPELLcif.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the CIF // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -56,8 +56,9 @@ SPELLcif::SPELLcif() m_ctxName = ""; m_ctxPort = 0; m_notificationsEnabled = true; - + m_forcePromptConfirm = false; m_finishEvent.clear(); + m_errorState = false; } //============================================================================= @@ -135,6 +136,15 @@ void SPELLcif::setVerbosity( int verbosity ) { m_verbosity = verbosity; } + +//============================================================================= +// METHOD : SPELLcif::setVerbosity +//============================================================================= +void SPELLcif::setForcePromptConfirm( bool force ) +{ + m_forcePromptConfirm = force; +} + //============================================================================= // METHOD : SPELLcif::setVerbosityFilter //============================================================================= @@ -188,6 +198,8 @@ const int SPELLcif::getVerbosityFilter() const //============================================================================= const std::string SPELLcif::getProcId() const { + if (m_procId.find("#") == std::string::npos) + return m_procId + "#0"; return m_procId; } @@ -450,24 +462,53 @@ void SPELLcif::error( const std::string& msg, unsigned int scope ) //============================================================================= // METHOD: SPELLcif::prompt //============================================================================= -std::string SPELLcif::prompt( const SPELLpromptDefinition& def ) +std::string SPELLcif::prompt( const SPELLpromptDefinition& def ,bool doPromptConfirm /* = true*/) { - // Local variables + bool canExit = true; std::string answerToShow= ""; std::string rawAnswer = ""; - - // Debug trace - DEBUG("[CIF] Prompt message"); - - // Write the prompt in the asrun - m_asRun->writePrompt( getStack(), def ); - - //Run Implementation Specifics - specificPrompt( def, rawAnswer, answerToShow ); - - // Write the answer in asrun - m_asRun->writeAnswer( getStack(), rawAnswer, def.scope ); - + // Local variables + do { + // Debug trace + canExit = true; + DEBUG("[CIF] Prompt message"); + + // Write the prompt in the asrun + m_asRun->writePrompt( getStack(), def ); + + //Run Implementation Specifics + specificPrompt( def, rawAnswer, answerToShow ); + + // Write the answer in asrun + if ( (def.typecode & LanguageConstants::PROMPT_PASSWORD)>0) + m_asRun->writeAnswer( getStack(), "***", def.scope ); + else + m_asRun->writeAnswer( getStack(), answerToShow, def.scope ); + + if (m_forcePromptConfirm && doPromptConfirm) + { + DEBUG("[CIF] Prompt Confirm message"); + SPELLpromptDefinition confirmPromptDefiniton; + confirmPromptDefiniton.message = "The answer '" + answerToShow + "' was provided for the previous Prompt.\nIs this value correct?"; + confirmPromptDefiniton.options.push_back("YES"); + confirmPromptDefiniton.options.push_back("NO"); + confirmPromptDefiniton.expected.push_back("YES"); + confirmPromptDefiniton.expected.push_back("NO"); + confirmPromptDefiniton.scope = def.scope; + confirmPromptDefiniton.typecode = 128; + + std::string confirmResult = this->prompt(confirmPromptDefiniton,false); + + if (confirmResult != "YES") + { + canExit = false; + } + else + { + canExit = true; + } + } + } while (!canExit); return answerToShow; } //std::string SPELLcif::prompt( const SPELLpromptDefinition& definition ) @@ -485,6 +526,7 @@ void SPELLcif::canClose() //============================================================================= void SPELLcif::waitClose() { + SPELLsafeThreadOperations ops("waitClose"); m_finishEvent.wait(); } @@ -560,6 +602,23 @@ void SPELLcif::notifyVariableScopeChange( const std::string& scopeName, } +//============================================================================= +// METHOD: SPELLcif::notifyResourceChange() +//============================================================================= +void SPELLcif::notifyResourceChange( const std::vector& changed ) +{ + specificNotifyResourceChange( changed ); +} + +//============================================================================= +// METHOD: SPELLcif::notifyResourceList() +//============================================================================= +void SPELLcif::notifyResourceList( const std::vector& resources ) +{ + specificNotifyResourceList( resources ); +} + + //============================================================================= // METHOD: SPELLcif::openSubprocedure //============================================================================= diff --git a/lib/SPELL_CIF/src/SPELLcifHelper.C b/lib/SPELL_CIF/src/SPELLcifHelper.C index 8437191..923d33b 100644 --- a/lib/SPELL_CIF/src/SPELLcifHelper.C +++ b/lib/SPELL_CIF/src/SPELLcifHelper.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the CIF helper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -360,6 +360,9 @@ std::string SPELLcifHelper::getResult( const std::string& result, const SPELLpro if ((def.options.size()>0)) { int optionIndex = STRI(result); + if (optionIndex < 0 || (unsigned)optionIndex >= def.options.size()){ + return ""; + } // Conversion LIST|ALPHA if ( (def.typecode & LanguageConstants::PROMPT_ALPHA)>0) { @@ -411,6 +414,7 @@ std::string SPELLcifHelper::getResult( const std::string& result, const SPELLpro } break; } + return promptResult; } @@ -477,15 +481,15 @@ std::string SPELLcifHelper::commandLinePrompt( const SPELLpromptDefinition& def, if (def.options.size()>0) { SPELLpromptDefinition::Options::const_iterator eit; - int count = 0; + unsigned int count = 0; for( eit = def.expected.begin(); eit != def.expected.end(); eit++) { if (*eit == answer ) { - if (useRaw) - { - answer = ISTR(count); - } +// if (useRaw) +// { +// answer = ISTR(count); +// } keepTrying = false; break; } @@ -498,7 +502,8 @@ std::string SPELLcifHelper::commandLinePrompt( const SPELLpromptDefinition& def, for( eit = def.expected.begin(); eit != def.expected.end(); eit++) { std::cout << " " << (*eit); - if (countob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ @@ -307,6 +314,33 @@ static PyObject* ClientIF_ResetVerbosity( PyObject* self, PyObject* args ) Py_RETURN_NONE; } +static PyObject* ClientIF_ForcePromptConfirm( PyObject* self, PyObject* args ) +{ + SPELLpyArgs pargs(args); + bool forcePromptConfirm = false; + + if (pargs.size()>0) + { + PyObject* pyForcePrompt = pargs[0]; + if (PyBool_Check(pyForcePrompt)) + { + + forcePromptConfirm = pyForcePrompt == Py_True; + } + else if(pyForcePrompt == Py_None) + { + // Nothing to do + } + else + { + THROW_SYNTAX_EXCEPTION("Syntax error on CIF::forcePromptConfirm()", "Malformed argument: " + PYREPR(args)); + } + } + SPELLexecutor::instance().getCIF().setForcePromptConfirm(forcePromptConfirm); + + Py_RETURN_NONE; +} + //============================================================================ // FUNCTION : ClientIF_Write //============================================================================ @@ -467,6 +501,10 @@ static PyObject* ClientIF_Prompt( PyObject* self, PyObject* args, PyObject* kwds if (argumentsC.hasModifier(LanguageModifiers::Timeout)) { def.timeout = argumentsC.getModifier_Timeout(); + } + else + { + def.timeout = SPELLtime(0, true); } // The prompt scope def.scope = argumentsC.getModifier_Scope(); diff --git a/lib/SPELL_CIF/src/SPELLnotifications.C b/lib/SPELL_CIF/src/SPELLnotifications.C index 927b3cb..afbcb89 100644 --- a/lib/SPELL_CIF/src/SPELLnotifications.C +++ b/lib/SPELL_CIF/src/SPELLnotifications.C @@ -5,7 +5,7 @@ // DESCRIPTION: Notification data class // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CIFC/Makefile.am b/lib/SPELL_CIFC/Makefile.am index 9a5cf32..ae2684e 100644 --- a/lib/SPELL_CIFC/Makefile.am +++ b/lib/SPELL_CIFC/Makefile.am @@ -1,34 +1,42 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_CIFC.la -libSPELL_CIFC_la_LDFLAGS = -version-info 1:0:0 -libSPELL_CIFC_la_SOURCES = \ - src/SPELLautomaticCif.C \ - src/SPELLncursesShell.C \ - src/SPELLstandaloneCif.C - + +lib_LTLIBRARIES = libSPELL_CIFC_v2.la libSPELL_CIFC_v3.la + +libSPELL_CIFC_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_CIFC_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu + +libSPELL_CIFC_v2_la_SOURCES = src/SPELLautomaticCif.C \ + src/SPELLncursesShell.C \ + src/SPELLstandaloneCif.C + + +libSPELL_CIFC_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_CIFC_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu + +libSPELL_CIFC_v3_la_SOURCES = src/SPELLautomaticCif.C \ + src/SPELLncursesShell.C \ + src/SPELLstandaloneCif.C + \ No newline at end of file diff --git a/lib/SPELL_CIFC/src/SPELLautomaticCif.C b/lib/SPELL_CIFC/src/SPELLautomaticCif.C index 632370b..d250ae9 100644 --- a/lib/SPELL_CIFC/src/SPELLautomaticCif.C +++ b/lib/SPELL_CIFC/src/SPELLautomaticCif.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the automatic (non-interactive) CIF // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -96,12 +96,17 @@ void SPELLautomaticCif::specificSetup( const SPELLcifStartupInfo& info ) getExecutorConfig().setPromptWarningDelay( STRI((ctx.getExecutorParameter(ExecutorConstants::PromptDelay))) ); getExecutorConfig().setBrowsableLib( stringToBrowsableLibMode(ctx.getExecutorParameter(ExecutorConstants::BrowsableLib) ) ); getExecutorConfig().setForceTcConfirm( (ctx.getExecutorParameter(ExecutorConstants::ForceTcConfirm) == PythonConstants::True) ); + getExecutorConfig().setForcePromptConfirm( (ctx.getExecutorParameter(ExecutorConstants::ForcePromptConfirm) == PythonConstants::True) ); std::string saveMode = ctx.getExecutorParameter(ExecutorConstants::SaveStateMode); getExecutorConfig().setSaveStateMode( saveMode ); std::string wvMode = ctx.getExecutorParameter(ExecutorConstants::WatchVariables); bool wvEnabled = wvMode == ExecutorConstants::ENABLED; getExecutorConfig().setWatchEnabled( wvEnabled ); + std::string rdMode = ctx.getExecutorParameter(ExecutorConstants::ResourcesDisplay); + bool rdEnabled = rdMode == ExecutorConstants::ENABLED; + getExecutorConfig().setResourcesDisplayEnabled( rdEnabled ); + getExecutorConfig().setLocalResourcesSupported( (ctx.getExecutorParameter(ExecutorConstants::LocalResourcesSupported) == PythonConstants::True) ); } //============================================================================= @@ -322,6 +327,22 @@ void SPELLautomaticCif::specificNotifyVariableScopeChange( const std::string& sc std::cout << "[ NOTIFY VARIABLE SCOPE CHANGE ] " << "Variable Scope Change" << std::endl; } +//============================================================================= +// METHOD: SPELLautomaticCif::specificNotifyResourceChange() +//============================================================================= +void SPELLautomaticCif::specificNotifyResourceChange( const std::vector& changed ) +{ + std::cout << "[ NOTIFY RESOURCE CHANGE ] " << "Resource Change" << std::endl; +} + +//============================================================================= +// METHOD: SPELLautomaticCif::specificNotifyResourceList() +//============================================================================= +void SPELLautomaticCif::specificNotifyResourceList( const std::vector& resources ) +{ + std::cout << "[ NOTIFY RESOURCE LIST ] " << "Resource List" << std::endl; +} + //============================================================================= // METHOD: SPELLautomaticCif::specificNotify //============================================================================= diff --git a/lib/SPELL_CIFC/src/SPELLncursesShell.C b/lib/SPELL_CIFC/src/SPELLncursesShell.C index 18649bb..a34ea90 100644 --- a/lib/SPELL_CIFC/src/SPELLncursesShell.C +++ b/lib/SPELL_CIFC/src/SPELLncursesShell.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the NCurses shell for standalone executor // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -47,7 +47,7 @@ #define COLOR_WARNING 3 #define COLOR_OK 4 -char *choices[] = { +static const std::string choices[] = { "RUN", "PAUSE", "SKIP", @@ -60,7 +60,7 @@ char *choices[] = { "RELOAD" }; -char *descriptions[] = { +static const std::string descriptions[] = { "Run the procedure", "Pause the execution", "Skip current line", @@ -333,7 +333,7 @@ void SPELLncursesShell::setupMenu() m_menuItems = (ITEM **)calloc(n_choices, sizeof(ITEM *)); for(i = 0; i < n_choices; ++i) { - m_menuItems[i] = new_item(choices[i], descriptions[i]); + m_menuItems[i] = new_item(choices[i].c_str(), descriptions[i].c_str()); } // Crate menu diff --git a/lib/SPELL_CIFC/src/SPELLstandaloneCif.C b/lib/SPELL_CIFC/src/SPELLstandaloneCif.C index b122fb2..1eef08c 100644 --- a/lib/SPELL_CIFC/src/SPELLstandaloneCif.C +++ b/lib/SPELL_CIFC/src/SPELLstandaloneCif.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the CIF for standalone executor // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CIFS/Makefile.am b/lib/SPELL_CIFS/Makefile.am index 18834d7..12a323d 100644 --- a/lib/SPELL_CIFS/Makefile.am +++ b/lib/SPELL_CIFS/Makefile.am @@ -1,36 +1,47 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_CIFS.la -libSPELL_CIFS_la_LDFLAGS = -version-info 2:1:0 -libSPELL_CIFS_la_SOURCES = \ - src/SPELLrequestProcessor.C \ - src/SPELLdisplayBuffer.C \ - src/SPELLvariableBuffer.C \ - src/SPELLcifPromptHelper.C \ - src/SPELLserverCif.C - + +lib_LTLIBRARIES = libSPELL_CIFS_v2.la libSPELL_CIFS_v3.la + +libSPELL_CIFS_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_CIFS_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_CIFS_v2_la_SOURCES = src/SPELLrequestProcessor.C \ + src/SPELLdisplayBuffer.C \ + src/SPELLvariableBuffer.C \ + src/SPELLresourceBuffer.C \ + src/SPELLcifPromptHelper.C \ + src/SPELLserverCif.C + +libSPELL_CIFS_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_CIFS_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_CIFS_v3_la_SOURCES = src/SPELLrequestProcessor.C \ + src/SPELLdisplayBuffer.C \ + src/SPELLvariableBuffer.C \ + src/SPELLresourceBuffer.C \ + src/SPELLcifPromptHelper.C \ + src/SPELLserverCif.C + \ No newline at end of file diff --git a/lib/SPELL_CIFS/src/SPELLcifPromptHelper.C b/lib/SPELL_CIFS/src/SPELLcifPromptHelper.C index 3ecf0e2..0561ffe 100644 --- a/lib/SPELL_CIFS/src/SPELLcifPromptHelper.C +++ b/lib/SPELL_CIFS/src/SPELLcifPromptHelper.C @@ -5,7 +5,7 @@ // DESCRIPTION: Helper for prompt processing // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -38,7 +38,7 @@ std::string SPELLcifPromptHelper::completeOptions( const SPELLpromptDefinition& { std::string msgToShow = origMsgToShow; - msgToShow += "\nAvailable options:\n"; + msgToShow += "Available options:\n"; int keyCount = 0; std::string optionStr = ""; diff --git a/lib/SPELL_CIFS/src/SPELLdisplayBuffer.C b/lib/SPELL_CIFS/src/SPELLdisplayBuffer.C index 5a4a46c..aa97e9f 100644 --- a/lib/SPELL_CIFS/src/SPELLdisplayBuffer.C +++ b/lib/SPELL_CIFS/src/SPELLdisplayBuffer.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the display messages buffer // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CIFS/src/SPELLrequestProcessor.C b/lib/SPELL_CIFS/src/SPELLrequestProcessor.C index d51c8c7..31644ce 100644 --- a/lib/SPELL_CIFS/src/SPELLrequestProcessor.C +++ b/lib/SPELL_CIFS/src/SPELLrequestProcessor.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the message request processor // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -160,12 +160,14 @@ void SPELLrequestProcessor::processGetConfig( const SPELLipcMessage& msg, SPELLi std::string byStep = config.isByStep() ? True : False; std::string browsableLibStr = config.getBrowsableLibStr(); std::string forceTcConfirm = config.isForceTcConfirm() ? True : False; + std::string forcePromptConfirm = config.isForcePromptConfirm() ? True : False; response.set(ExecutorConstants::ExecDelay, execDelay); response.set(ExecutorConstants::PromptDelay, promptDelay); response.set(ExecutorConstants::ByStep, byStep); response.set(ExecutorConstants::BrowsableLib, browsableLibStr ); response.set(ExecutorConstants::ForceTcConfirm, forceTcConfirm); + response.set(ExecutorConstants::ForcePromptConfirm, forcePromptConfirm); LOG_INFO("Current executor configuration:"); LOG_INFO(" run into : " + (config.isRunInto() ? True : False) ); @@ -174,6 +176,7 @@ void SPELLrequestProcessor::processGetConfig( const SPELLipcMessage& msg, SPELLi LOG_INFO(" by step : " + byStep); LOG_INFO(" browsable lib : " + browsableLibStr ); LOG_INFO(" force confirm : " + forceTcConfirm); + LOG_INFO(" force prompt confirm : " + forcePromptConfirm); DEBUG("[CIF] Request to get executor config done"); } @@ -237,6 +240,7 @@ void SPELLrequestProcessor::processSetConfig( const SPELLipcMessage& msg, SPELLi std::string byStep = msg.get(ExecutorConstants::ByStep); std::string browsableLibStr = msg.get(ExecutorConstants::BrowsableLib); std::string forceTcConfirm = msg.get(ExecutorConstants::ForceTcConfirm); + std::string forcePromptConfirm = msg.get(ExecutorConstants::ForcePromptConfirm); LOG_INFO("New executor configuration ----------------------------------"); @@ -246,6 +250,7 @@ void SPELLrequestProcessor::processSetConfig( const SPELLipcMessage& msg, SPELLi LOG_INFO(" By step : " + byStep); LOG_INFO(" Br. lib : " + browsableLibStr); LOG_INFO(" TC confirm: " + forceTcConfirm); + LOG_INFO("Prompt confirm: " + forcePromptConfirm); LOG_INFO("-------------------------------------------------------------"); SPELLexecutor::instance().setRunInto( (runInto == True) ); @@ -254,6 +259,7 @@ void SPELLrequestProcessor::processSetConfig( const SPELLipcMessage& msg, SPELLi SPELLexecutor::instance().setByStep( (byStep == True) ); SPELLexecutor::instance().setBrowsableLibStr( browsableLibStr ); SPELLexecutor::instance().setForceTcConfirm( forceTcConfirm == True ); + SPELLexecutor::instance().setForcePromptConfirm( forcePromptConfirm == True ); DEBUG("[CIF] Request to change executor config done"); } @@ -280,7 +286,6 @@ void SPELLrequestProcessor::processSetBreakpoint( const SPELLipcMessage& msg, SP //============================================================================= void SPELLrequestProcessor::processClearBreakpoints( const SPELLipcMessage& msg, SPELLipcMessage& response ) { - SPELLmonitor mon(m_requestLock); DEBUG("[CIF] Request to clear breakpoints for the given code"); // Update the response message response.setId(ExecutorMessages::RSP_CLEAR_BREAKPOINT); @@ -293,7 +298,6 @@ void SPELLrequestProcessor::processClearBreakpoints( const SPELLipcMessage& msg, //============================================================================= void SPELLrequestProcessor::processCheckVariablesEnabled( const SPELLipcMessage& msg, SPELLipcMessage& response ) { - SPELLmonitor mon(m_requestLock); // Update the response message response.setId(ExecutorMessages::RSP_WVARIABLES_ENABLED); bool enabled = SPELLexecutor::instance().getVariableManager().isEnabled(); @@ -449,6 +453,82 @@ void SPELLrequestProcessor::processChangeVariable( const SPELLipcMessage& msg, S SPELLexecutor::instance().getVariableManager().changeVariable( info ); } +//============================================================================= +// METHOD: SPELLrequestProcessor::processCheckResourcesEnabled +//============================================================================= +void SPELLrequestProcessor::processCheckResourcesEnabled( const SPELLipcMessage& msg, SPELLipcMessage& response ) +{ + // Update the response message + response.setId(ExecutorMessages::RSP_DRESOURCES_ENABLED); + bool enabled = SPELLexecutor::instance().getResourceManager().isEnabled(); + bool localSupport = SPELLexecutor::instance().getConfiguration().isLocalResourcesSupported(); + response.set( MessageField::FIELD_DRESOURCES_ENABLED, enabled ? "True" : "False"); + response.set( MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED, localSupport ? "True" : "False"); +} + +//============================================================================= +// METHOD: SPELLrequestProcessor::processGetResources +//============================================================================= +void SPELLrequestProcessor::processGetResources( const SPELLipcMessage& msg, SPELLipcMessage& response ) +{ + SPELLmonitor mon(m_requestLock); + // Update the response message + response.setId(ExecutorMessages::RSP_GET_RESOURCES); + + if (!SPELLexecutor::instance().getResourceManager().isStatusValid()) + { + LOG_WARN("Resource manager is not in valid status"); + response.setType(MSG_TYPE_ERROR); + response.set( MessageField::FIELD_ERROR, "Cannot retrieve resources"); + response.set( MessageField::FIELD_REASON, "Resource analysis cannot be done in the current status"); + response.set( MessageField::FIELD_FATAL, PythonConstants::False ); + return; + } + + if (!SPELLexecutor::instance().getResourceManager().isEnabled()) + { + LOG_WARN("Resource manager is disabled, but received getResources request"); + return; + } + + SPELLexecutor::instance().getResourceManager().getResources(); +} + +//============================================================================= +// METHOD: SPELLrequestProcessor::processChangeResource +//============================================================================= +void SPELLrequestProcessor::processChangeResource( const SPELLipcMessage& msg, SPELLipcMessage& response ) +{ + SPELLmonitor mon(m_requestLock); + // Update the response message + response.setId(ExecutorMessages::RSP_CHANGE_RESOURCE); + + if (!SPELLexecutor::instance().getResourceManager().isStatusValid()) + { + LOG_WARN("Resource manager is not in valid status"); + response.setType(MSG_TYPE_ERROR); + response.set( MessageField::FIELD_ERROR, "Cannot change resources"); + response.set( MessageField::FIELD_REASON, "Resource analysis cannot be done in the current status"); + response.set( MessageField::FIELD_FATAL, PythonConstants::False ); + return; + } + + if (!SPELLexecutor::instance().getResourceManager().isEnabled()) + { + LOG_WARN("Resource manager is disabled, but received change resource request"); + return; + } + + std::string name = msg.get( MessageField::FIELD_RESOURCE_NAME ); + std::string globalValueExpression = msg.get( MessageField::FIELD_RESOURCE_GLOBAL_VALUE ); + std::string localValueExpression = msg.get( MessageField::FIELD_RESOURCE_LOCAL_VALUE ); + + // Type and registration flag are not important here + SPELLresourceInfo info(name,"",globalValueExpression,localValueExpression, std::vector >(), ""); + + SPELLexecutor::instance().getResourceManager().changeResource( info ); +} + //============================================================================= // METHOD: SPELLrequestProcessor::processGetDictionary //============================================================================= diff --git a/lib/SPELL_CIFS/src/SPELLresourceBuffer.C b/lib/SPELL_CIFS/src/SPELLresourceBuffer.C new file mode 100644 index 0000000..0e5f95a --- /dev/null +++ b/lib/SPELL_CIFS/src/SPELLresourceBuffer.C @@ -0,0 +1,197 @@ +// ################################################################################ +// FILE : SPELLresourceBuffer.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the RDOTCO messages buffer +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// Local includes ---------------------------------------------------------- +#include "SPELL_CIFS/SPELLresourceBuffer.H" +#include "SPELL_CIFS/SPELLserverCif.H" +// Project includes -------------------------------------------------------- +#include "SPELL_IPC/SPELLipc.H" +#include "SPELL_SYN/SPELLmonitor.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_WRP/SPELLconstants.H" +// System includes --------------------------------------------------------- + + +#define FLUSH_PERIOD_USEC 250000 //half a sec + +//============================================================================= +// CONSTRUCTOR: SPELLresourceBuffer::SPELLresourceBuffer +//============================================================================= +SPELLresourceBuffer::SPELLresourceBuffer( const std::string& procId, SPELLserverCif& cif ) +: SPELLthread("display-buffer"), + m_cif(cif), + m_resourceMessage( ExecutorMessages::MSG_RESOURCE_CHANGE ) +{ + DEBUG("[CIF] Created display buffer"); + m_working = true; + m_resourceMessage.setType(MSG_TYPE_ONEWAY); + m_resourceMessage.set( MessageField::FIELD_PROC_ID, procId ); + m_total = 0; + m_bufferHasListResources = false; +} + +//============================================================================= +// DESTRUCTOR: SPELLresourceBuffer::~SPELLresourceBuffer +//============================================================================= +SPELLresourceBuffer::~SPELLresourceBuffer() +{ + DEBUG("[CIF] Destroyed RDOTCO buffer"); +} + +//============================================================================= +// METHOD: SPELLresourceBuffer::run() +//============================================================================= +void SPELLresourceBuffer::run() +{ + while(m_working) + { + usleep(FLUSH_PERIOD_USEC); + { + SPELLmonitor m(m_lock); + if (hasDataToSend()) + { + flush(); + } + } + } +} + +//============================================================================= +// METHOD: SPELLresourceBuffer::run() +//============================================================================= +void SPELLresourceBuffer::stop() +{ + m_working = false; +} + +//============================================================================= +// METHOD: SPELLresourceBuffer::resourceChange() +//============================================================================= +void SPELLresourceBuffer::resourceChange( const std::vector& changed ) +{ + SPELLmonitor m(m_lock); + std::vector::const_iterator it; + std::map::iterator mit; + + for( it = changed.begin(); it != changed.end(); it++) + { + // If the resource was added and not yet notified, just not process + // this notification and leave the add operation but with the new value. + std::string name = (*it).resourceName; + m_resources[ name ] = (*it); + } + m_total++; +} + +//============================================================================= +// METHOD: SPELLresourceBuffer::resourceList() +//============================================================================= +void SPELLresourceBuffer::resourceList( const std::vector& resources ) +{ + resourceChange(resources); + m_bufferHasListResources = true; +} + +//============================================================================= +// METHOD: SPELLresourceBuffer::flush() +//============================================================================= +void SPELLresourceBuffer::flush() +{ + SPELLmonitor m(m_lock); + + std::string names = ""; + std::string types = ""; + std::string globalValues = ""; + std::string localValues = ""; + std::string valueRange = ""; + std::string gcsValueRange = ""; + std::string gcsNames = ""; + + std::map::const_iterator it; + for(it = m_resources.begin(); it != m_resources.end(); it++) + { + if (names != "") + { + names += VARIABLE_SEPARATOR; + types += VARIABLE_SEPARATOR; + globalValues += VARIABLE_SEPARATOR; + localValues += VARIABLE_SEPARATOR; + gcsNames += VARIABLE_SEPARATOR; + if (m_bufferHasListResources) + { + valueRange += VARIABLE_SEPARATOR; + gcsValueRange += VARIABLE_SEPARATOR; + } + } + names += it->second.resourceName; + types += it->second.resourceType; + globalValues += it->second.resourceGlobalValue; + localValues += it->second.resourceLocalValue; + gcsNames += it->second.resourceGCSName; + if (m_bufferHasListResources) + { + for (unsigned int vri = 0; vri < it->second.resourceValueRange.size(); vri++) + { + if (vri > 0) + { + valueRange += VARIABLE_PROPERTY_SEPARATOR; + gcsValueRange += VARIABLE_PROPERTY_SEPARATOR; + } + valueRange += it->second.resourceValueRange[vri].first; + gcsValueRange += it->second.resourceValueRange[vri].second; + } + } + } + + m_resources.clear(); + + m_resourceMessage.set(MessageField::FIELD_RESOURCE_NAME, names); + m_resourceMessage.set(MessageField::FIELD_RESOURCE_TYPE, types); + m_resourceMessage.set(MessageField::FIELD_RESOURCE_GLOBAL_VALUE, globalValues); + m_resourceMessage.set(MessageField::FIELD_RESOURCE_LOCAL_VALUE, localValues); + // An empty string is passed in case of resource change (no need to resend the ranges) + m_resourceMessage.set(MessageField::FIELD_RESOURCE_VALUE_RANGE, valueRange); + m_resourceMessage.set(MessageField::FIELD_RESOURCE_GCS_VALUE_RANGE, gcsValueRange); + m_resourceMessage.set(MessageField::FIELD_RESOURCE_GCS_NAME, gcsNames); + +#ifdef WITH_DEBUG + std::cerr << "SEND RDOTCO (" << m_total << ")" << std::endl; +#endif + + m_cif.sendGUIMessage(m_resourceMessage); + m_total = 0; + m_bufferHasListResources = false; +} + +//============================================================================= +// METHOD: SPELLresourceBuffer::hasDataToSend() +//============================================================================= +bool SPELLresourceBuffer::hasDataToSend() +{ + SPELLmonitor m(m_lock); + return (m_resources.size()>0); +} diff --git a/lib/SPELL_CIFS/src/SPELLserverCif.C b/lib/SPELL_CIFS/src/SPELLserverCif.C index 85a133d..0be5af8 100644 --- a/lib/SPELL_CIFS/src/SPELLserverCif.C +++ b/lib/SPELL_CIFS/src/SPELLserverCif.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the CIF for server environment // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -51,7 +51,7 @@ // DEFINES ///////////////////////////////////////////////////////////////// -#define ACKNOWLEDGE_TIMEOUT_SEC 30 +#define ACKNOWLEDGE_TIMEOUT_MSEC 30000 // GLOBALS ///////////////////////////////////////////////////////////////// SPELLserverCif* s_handle = NULL; @@ -72,11 +72,18 @@ SPELLserverCif::SPELLserverCif() m_ifc = NULL; m_buffer = NULL; m_wovBuffer = NULL; + m_rdotcoBuffer = NULL; m_ready = false; - + m_timeoutOpenProcMsec = 0; + m_ipcTimeoutGuiRequestMsec = 0; + m_ipcTimeoutCtxRequestMsec = 0; + m_ipcInterruptionNotified = false; m_errorState = false; m_sequence = 0; m_sequenceStack = 0; + m_numNotAcknowledged = 0; + m_timeoutExecLoginMsec = 0; + m_timeoutAcknowledgeSec = 0; getExecutorConfig().setVisible(true); getExecutorConfig().setAutomatic(false); @@ -101,12 +108,6 @@ SPELLserverCif::SPELLserverCif() m_closing = false; m_lastStack = ""; - - m_ipcTimeoutGuiRequestMsec = SPELLconfiguration::instance().commonOrDefault( "GuiRequestTimeout", IPC_GUIREQUEST_DEFAULT_TIMEOUT_MSEC ); - m_ipcTimeoutCtxRequestMsec = SPELLconfiguration::instance().commonOrDefault( "CtxRequestTimeout", IPC_CTXREQUEST_DEFAULT_TIMEOUT_MSEC ); - m_timeoutOpenProcMsec = SPELLconfiguration::instance().commonOrDefault( "OpenProcTimeout", IPC_OPENPROC_DEFAULT_TIMEOUT_MSEC ); - m_timeoutExecLoginMsec = SPELLconfiguration::instance().commonOrDefault( "ExecutorLoginTimeout", IPC_EXLOGIN_DEFAULT_TIMEOUT_MSEC ); - m_timeoutAcknowledgeSec = SPELLconfiguration::instance().commonOrDefault( "AcknowledgeTimeout", ACKNOWLEDGE_TIMEOUT_SEC ); } //============================================================================= @@ -129,6 +130,11 @@ SPELLserverCif::~SPELLserverCif() delete m_wovBuffer; m_wovBuffer = NULL; } + if (m_rdotcoBuffer != NULL) + { + delete m_rdotcoBuffer; + m_rdotcoBuffer = NULL; + } } //============================================================================= @@ -136,6 +142,18 @@ SPELLserverCif::~SPELLserverCif() //============================================================================= void SPELLserverCif::specificSetup( const SPELLcifStartupInfo& info ) { + m_ipcTimeoutGuiRequestMsec = SPELLconfiguration::instance().commonOrDefault( "GuiRequestTimeout", IPC_GUIREQUEST_DEFAULT_TIMEOUT_MSEC ); + m_ipcTimeoutCtxRequestMsec = SPELLconfiguration::instance().commonOrDefault( "CtxRequestTimeout", IPC_CTXREQUEST_DEFAULT_TIMEOUT_MSEC ); + m_timeoutOpenProcMsec = SPELLconfiguration::instance().commonOrDefault( "OpenProcTimeout", IPC_OPENPROC_DEFAULT_TIMEOUT_MSEC ); + m_timeoutExecLoginMsec = SPELLconfiguration::instance().commonOrDefault( "ExecutorLoginTimeout", IPC_EXLOGIN_DEFAULT_TIMEOUT_MSEC ); + m_timeoutAcknowledgeSec = SPELLconfiguration::instance().commonOrDefault( "AcknowledgeTimeout", ACKNOWLEDGE_TIMEOUT_MSEC ) / 1000; + + LOG_INFO("GUI request timeout: " + ISTR(m_ipcTimeoutGuiRequestMsec) + " ms"); + LOG_INFO("CTX request timeout: " + ISTR(m_ipcTimeoutCtxRequestMsec) + " ms"); + LOG_INFO(" OPEN timeout: " + ISTR(m_timeoutOpenProcMsec) + " ms"); + LOG_INFO(" LOGIN timeout: " + ISTR(m_timeoutExecLoginMsec) + " ms"); + LOG_INFO(" ACK timeout: " + ISTR(m_timeoutAcknowledgeSec) + " sec"); + //Initialize Executor Config parameters getExecutorConfig().setVisible(true); getExecutorConfig().setAutomatic(false); @@ -157,6 +175,9 @@ void SPELLserverCif::specificSetup( const SPELLcifStartupInfo& info ) m_wovBuffer = new SPELLvariableBuffer( getProcId(), *this ); m_wovBuffer->start(); + m_rdotcoBuffer = new SPELLresourceBuffer( getProcId(), *this ); + m_rdotcoBuffer->start(); + // Initialize message sequencer m_sequence = 0; m_sequenceStack = 0; @@ -188,8 +209,10 @@ void SPELLserverCif::specificCleanup( bool force ) cancelPrompt(); m_buffer->stop(); m_wovBuffer->stop(); + m_rdotcoBuffer->stop(); m_buffer->join(); m_wovBuffer->join(); + m_rdotcoBuffer->join(); DEBUG("[CIF] Disconnecting server CIF"); if (!force) { @@ -246,14 +269,12 @@ SPELLipcMessage SPELLserverCif::login() loginmsg.set( MessageField::FIELD_CSP, getProcId()); // status loaded is not correct if the procedure did not compile, but the error will be - // notified afterwards anyhow. - loginmsg.set( MessageField::FIELD_EXEC_STATUS, SPELLexecutorUtils::statusToString(STATUS_LOADED)); + // notified afterwards anyhow.c loginmsg.set( MessageField::FIELD_ASRUN_NAME, getAsRunName() ); loginmsg.set( MessageField::FIELD_LOG_NAME, SPELLlog::instance().getLogFile() ); LOG_INFO("Login information:"); LOG_INFO("Proc : " + getProcId() ); - LOG_INFO("Status: LOADED"); LOG_INFO("AsRun : " + getAsRunName() ); LOG_INFO("Log : " + SPELLlog::instance().getLogFile() ); @@ -376,7 +397,10 @@ void SPELLserverCif::processLogin( const SPELLipcMessage& loginResp ) { getExecutorConfig().setForceTcConfirm( loginResp.get(MessageField::FIELD_FORCE_TC_CONFIRM) == ExecutorConstants::TRUE_VALUE ); } - + if (loginResp.hasField(MessageField::FIELD_FORCE_PROMPT_CONFIRM)) + { + getExecutorConfig().setForcePromptConfirm( loginResp.get(MessageField::FIELD_FORCE_PROMPT_CONFIRM) == ExecutorConstants::TRUE_VALUE ); + } if (loginResp.hasField(MessageField::FIELD_SAVE_STATE_MODE)) { getExecutorConfig().setSaveStateMode( loginResp.get(MessageField::FIELD_SAVE_STATE_MODE) ); @@ -387,6 +411,16 @@ void SPELLserverCif::processLogin( const SPELLipcMessage& loginResp ) getExecutorConfig().setWatchEnabled( loginResp.get(MessageField::FIELD_WATCH_VARIABLES) == ExecutorConstants::TRUE_VALUE ); } + if (loginResp.hasField(MessageField::FIELD_RESOURCES_DISPLAY)) + { + getExecutorConfig().setResourcesDisplayEnabled( loginResp.get(MessageField::FIELD_RESOURCES_DISPLAY) == ExecutorConstants::TRUE_VALUE ); + } + + if (loginResp.hasField(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED)) + { + getExecutorConfig().setLocalResourcesSupported( loginResp.get(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED) == ExecutorConstants::TRUE_VALUE ); + } + if (loginResp.hasField(MessageField::FIELD_MAX_VERBOSITY)) { getExecutorConfig().setMaxVerbosity( STRI(loginResp.get(MessageField::FIELD_MAX_VERBOSITY)) ); @@ -412,8 +446,11 @@ void SPELLserverCif::processLogin( const SPELLipcMessage& loginResp ) LOG_INFO("Prompt Delay : " + ISTR(getExecutorConfig().getPromptWarningDelay())); LOG_INFO("By Step : " + BSTR(getExecutorConfig().isByStep())); LOG_INFO("Force Tc Conf : " + BSTR(getExecutorConfig().isForceTcConfirm())); + LOG_INFO("Force Prompt Conf : " + BSTR(getExecutorConfig().isForcePromptConfirm())); LOG_INFO("Save State Mod: " + getExecutorConfig().getSaveStateMode()); LOG_INFO("WatchVariables: " + BSTR(getExecutorConfig().isWatchEnabled())); + LOG_INFO("ResourcesDisplay: " + BSTR(getExecutorConfig().isResourcesDisplayEnabled())); + LOG_INFO("Local Resource supported: " + BSTR(getExecutorConfig().isLocalResourcesSupported())); LOG_INFO("Max Verbosity : " + ISTR(getExecutorConfig().getMaxVerbosity())); } @@ -479,6 +516,8 @@ void SPELLserverCif::sendGUIMessage( const SPELLipcMessage& msg ) LOG_ERROR("Unable to communicate with Context: " + std::string(ex.what())); SPELLexecutor::instance().pause(); } + } else { + usleep(500000); } } @@ -576,35 +615,30 @@ void SPELLserverCif::prepareMessage( SPELLipcMessage& msg, const std::string da void SPELLserverCif::specificNotifyLine() { // Local variables - std::string stage = ""; - + SPELLsafeThreadOperations ops("Notify"); + std::string stage = ""; + SPELLipcMessage msg = m_lnMessage; // prepares the message to be sent to GUI - prepareMessage( m_lnMessage, MessageValue::DATA_TYPE_LINE, MSG_TYPE_NOTIFY_ASYNC); + prepareMessage( msg, MessageValue::DATA_TYPE_LINE, MSG_TYPE_NOTIFY_ASYNC); // Update message with stage info stage = getStage(); - - if (stage.find(":") != std::string::npos) + size_t delim = stage.find(":"); + if (delim != std::string::npos) { - std::vector stage_title = SPELLutils::tokenize(stage,":"); - if (stage_title.size()==2) - { - m_lnMessage.set(MessageField::FIELD_STAGE_ID,stage_title[0]); - m_lnMessage.set(MessageField::FIELD_STAGE_TL,stage_title[1]); - } + msg.set(MessageField::FIELD_STAGE_ID,stage.substr(0, delim)); + if (delim + 1 < stage.length()) + msg.set(MessageField::FIELD_STAGE_TL,stage.substr(delim + 1)); else - { - m_lnMessage.set(MessageField::FIELD_STAGE_ID,"(none)"); - m_lnMessage.set(MessageField::FIELD_STAGE_TL,"(none)"); - } + msg.set(MessageField::FIELD_STAGE_TL,"(none)"); } else { - m_lnMessage.set(MessageField::FIELD_STAGE_ID,stage); - m_lnMessage.set(MessageField::FIELD_STAGE_TL,stage); + msg.set(MessageField::FIELD_STAGE_ID,stage); + msg.set(MessageField::FIELD_STAGE_TL,stage); } - sendGUIMessage(m_lnMessage); + sendGUIMessage(msg); } //SPELLserverCif::specificNotifyLine() @@ -615,10 +649,16 @@ void SPELLserverCif::specificNotifyLine() void SPELLserverCif::specificNotifyCall() { // prepares the message to be sent to GUI - prepareMessage( m_lnMessage, MessageValue::DATA_TYPE_CALL, MSG_TYPE_NOTIFY); + SPELLsafeThreadOperations ops("NotifyCall"); + SPELLipcMessage msg = m_lnMessage; + prepareMessage( msg, MessageValue::DATA_TYPE_CALL, MSG_TYPE_NOTIFY); + + do + { + sendGUIMessage(msg); + } + while (!waitAcknowledge(msg)); - sendGUIMessage(m_lnMessage); - waitAcknowledge(m_lnMessage); } //void SPELLserverCif::specificNotifyCall() @@ -627,11 +667,15 @@ void SPELLserverCif::specificNotifyCall() //============================================================================= void SPELLserverCif::specificNotifyReturn() { - // prepares the message to be sent to GUI - prepareMessage( m_lnMessage, MessageValue::DATA_TYPE_RETURN, MSG_TYPE_NOTIFY); + // prepares the message to be sent to GUI + SPELLsafeThreadOperations ops("NotifyReturn"); + SPELLipcMessage msg = m_lnMessage; + prepareMessage(msg, MessageValue::DATA_TYPE_RETURN, MSG_TYPE_NOTIFY); - sendGUIMessage(m_lnMessage); - waitAcknowledge(m_lnMessage); + do + { + sendGUIMessage(msg); + } while (!waitAcknowledge(msg)); } //============================================================================= @@ -640,24 +684,28 @@ void SPELLserverCif::specificNotifyReturn() void SPELLserverCif::specificNotifyStatus( const SPELLstatusInfo& st ) { // Prepare message - m_stMessage.set(MessageField::FIELD_EXEC_STATUS, SPELLexecutorUtils::statusToString(st.status)); - completeMessage( m_stMessage ); + SPELLsafeThreadOperations ops("NotifyStatus"); + SPELLipcMessage msg = m_stMessage; + msg.set(MessageField::FIELD_EXEC_STATUS, SPELLexecutorUtils::statusToString(st.status)); + completeMessage( msg ); // Set message Condition information if (st.condition.size()>0) { - m_stMessage.set( MessageField::FIELD_CONDITION, st.condition ); + msg.set( MessageField::FIELD_CONDITION, st.condition ); } // Set message Action information if (st.actionLabel != "") { - m_stMessage.set( MessageField::FIELD_ACTION_LABEL, st.actionLabel ); - m_stMessage.set( MessageField::FIELD_ACTION_ENABLED, st.actionEnabled ? MessageValue::DATA_TRUE : MessageValue::DATA_FALSE ); + msg.set( MessageField::FIELD_ACTION_LABEL, st.actionLabel ); + msg.set( MessageField::FIELD_ACTION_ENABLED, st.actionEnabled ? MessageValue::DATA_TRUE : MessageValue::DATA_FALSE ); } - sendGUIMessage(m_stMessage); - waitAcknowledge(m_stMessage); + do{ + sendGUIMessage(msg); + } while(!waitAcknowledge(msg)); + } //============================================================================= @@ -665,6 +713,7 @@ void SPELLserverCif::specificNotifyStatus( const SPELLstatusInfo& st ) //============================================================================= void SPELLserverCif::specificNotifyUserActionSet( const std::string& label, const unsigned int severity ) { + SPELLsafeThreadOperations ops("NotifyActionSet"); SPELLipcMessage actionMessage(MessageId::MSG_ID_SET_UACTION); actionMessage.setType(MSG_TYPE_ONEWAY); actionMessage.set( MessageField::FIELD_PROC_ID, getProcId() ); @@ -692,6 +741,7 @@ void SPELLserverCif::specificNotifyUserActionSet( const std::string& label, cons //============================================================================= void SPELLserverCif::specificNotifyUserActionUnset() { + SPELLsafeThreadOperations ops("NotifyActionUnset"); SPELLipcMessage actionMessage(MessageId::MSG_ID_DISMISS_UACTION); actionMessage.setType(MSG_TYPE_ONEWAY); actionMessage.set( MessageField::FIELD_PROC_ID, getProcId() ); @@ -703,6 +753,7 @@ void SPELLserverCif::specificNotifyUserActionUnset() //============================================================================= void SPELLserverCif::specificNotifyUserActionEnable( bool enable ) { + SPELLsafeThreadOperations ops("Notify"); if (enable) { SPELLipcMessage actionMessage(MessageId::MSG_ID_ENABLE_UACTION); @@ -725,7 +776,9 @@ void SPELLserverCif::specificNotifyUserActionEnable( bool enable ) void SPELLserverCif::specificNotify( ItemNotification notification ) { //Prepare message - completeMessage( m_ntMessage ); + SPELLsafeThreadOperations ops("Notify"); + SPELLipcMessage msg = m_ntMessage; + completeMessage( msg ); //DEBUG("[CIF] Processing status"); @@ -733,27 +786,30 @@ void SPELLserverCif::specificNotify( ItemNotification notification ) std::stringstream buffer; buffer << notification.getSuccessfulCount(); - m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_TYPE, NOTIF_TYPE_STR[notification.type]); - m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_NAME, notification.name); - m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_VALUE, notification.value); - m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_STATUS, notification.status); - m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_REASON, notification.getTokenizedComment()); - m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_TIME, notification.getTokenizedTime()); - m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_SCOUNT, buffer.str()); + msg.set(MessageField::FIELD_NOTIF_ITEM_TYPE, NOTIF_TYPE_STR[notification.type]); + msg.set(MessageField::FIELD_NOTIF_ITEM_NAME, notification.name); + msg.set(MessageField::FIELD_NOTIF_ITEM_VALUE, notification.value); + msg.set(MessageField::FIELD_NOTIF_ITEM_STATUS, notification.status); + msg.set(MessageField::FIELD_NOTIF_ITEM_REASON, notification.getTokenizedComment()); + msg.set(MessageField::FIELD_NOTIF_ITEM_TIME, notification.getTokenizedTime()); + msg.set(MessageField::FIELD_NOTIF_ITEM_SCOUNT, buffer.str()); //DEBUG("[CIF] Message prepared, sending"); - sendGUIMessage(m_ntMessage); - waitAcknowledge(m_ntMessage); + do + { + sendGUIMessage(msg); + } while(!waitAcknowledge(msg)); + //DEBUG("[CIF] Notification sent"); } //============================================================================= // METHOD: SPELLserverCif::waitAcknowledge() //============================================================================= -void SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg ) +bool SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg ) { - if (m_ready && !m_ipcInterruptionNotified) + if (m_ready) { bool found = false; std::string seq = msg.get(MessageField::FIELD_MSG_SEQUENCE); @@ -766,11 +822,12 @@ void SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg ) SPELLmonitor m(m_ackLock); it = std::find(m_ackSequences.begin(), m_ackSequences.end(), seq); - found = it != m_ackSequences.end(); if (found) { m_ackSequences.erase(it); + + return true; } else { @@ -782,41 +839,16 @@ void SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg ) LOG_WARN("Acknowledge not received!"); LOG_WARN(msg.dataStr()); LOG_WARN("#########################"); - m_numNotAcknowledged++; - - if (m_numNotAcknowledged==5) - { - m_numNotAcknowledged = 0; - if (!m_ipcInterruptionNotified) - { - m_ipcInterruptionNotified = true; - SPELLexecutorStatus st = SPELLexecutor::instance().getStatus(); - if ( st == STATUS_RUNNING ) - { - ExecutorCommand cmd; - cmd.id = CMD_PAUSE; - warning("Communication with controlling GUI interrupted. Procedure paused for safety.", LanguageConstants::SCOPE_SYS); - warning("You may try to resume execution.", LanguageConstants::SCOPE_SYS); - SPELLexecutor::instance().command(cmd,false); - } - else if ( st == STATUS_WAITING ) - { - ExecutorCommand cmd; - cmd.id = CMD_INTERRUPT; - warning("Communication with controlling GUI interrupted. Procedure interruptedfor safety.", LanguageConstants::SCOPE_SYS); - warning("You may try to resume execution.", LanguageConstants::SCOPE_SYS); - SPELLexecutor::instance().command(cmd,false); - } - } - } - return; + + return false; } } } - if (!m_ready) return; + if (!m_ready) return false; usleep(52000); } } + return false; } //============================================================================= @@ -825,7 +857,7 @@ void SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg ) void SPELLserverCif::specificNotifyError( const std::string& error, const std::string& reason, bool fatal ) { //LOG_ERROR("[CIF] Error notification: " + error + " (" + reason + ")"); - + SPELLsafeThreadOperations ops("Notify"); // prepare error message SPELLipcMessage errorMsg( MessageId::MSG_ID_ERROR); errorMsg.setType(MSG_TYPE_ERROR); @@ -852,71 +884,77 @@ void SPELLserverCif::specificNotifyError( const std::string& error, const std::s //============================================================================= // METHOD: SPELLserverCif::specificWrite //============================================================================= -void SPELLserverCif::specificWrite( const std::string& msg, unsigned int scope ) +void SPELLserverCif::specificWrite( const std::string& msgText, unsigned int scope ) { if (isManual()) { - completeMessage( m_wrMessage ); + SPELLsafeThreadOperations ops("Notify"); + SPELLipcMessage msg = m_wrMessage; + completeMessage( msg ); std::string timeStr = SPELLutils::timestampUsec(); - m_wrMessage.set(MessageField::FIELD_TEXT,msg); - m_wrMessage.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_INFO); - m_wrMessage.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY); - m_wrMessage.set(MessageField::FIELD_TIME, timeStr); - m_wrMessage.set(MessageField::FIELD_SCOPE, ISTR(scope)); - sendGUIMessage(m_wrMessage); + msg.set(MessageField::FIELD_TEXT,msgText); + msg.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_INFO); + msg.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY); + msg.set(MessageField::FIELD_TIME, timeStr); + msg.set(MessageField::FIELD_SCOPE, ISTR(scope)); + sendGUIMessage(msg); } else { - m_buffer->write( msg, scope ); + m_buffer->write( msgText, scope ); } } //============================================================================= // METHOD: SPELLserverCif::specificWarning //============================================================================= -void SPELLserverCif::specificWarning( const std::string& msg, unsigned int scope ) +void SPELLserverCif::specificWarning( const std::string& msgText, unsigned int scope ) { // We shall not bufferize in manual mode if (isManual()) { - completeMessage( m_wrMessage ); + SPELLsafeThreadOperations ops("Notify"); + SPELLipcMessage msg = m_wrMessage; + completeMessage( msg ); std::string timeStr = SPELLutils::timestampUsec(); - m_wrMessage.set(MessageField::FIELD_TEXT,msg); - m_wrMessage.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_WARN); - m_wrMessage.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY); - m_wrMessage.set(MessageField::FIELD_TIME, timeStr); - m_wrMessage.set(MessageField::FIELD_SCOPE, ISTR(scope)); - sendGUIMessage(m_wrMessage); + msg.set(MessageField::FIELD_TEXT,msgText); + msg.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_WARN); + msg.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY); + msg.set(MessageField::FIELD_TIME, timeStr); + msg.set(MessageField::FIELD_SCOPE, ISTR(scope)); + sendGUIMessage(msg); } else { - m_buffer->warning( msg, scope ); + m_buffer->warning( msgText, scope ); } } //============================================================================= // METHOD: SPELLserverCif::specificError -//============================================================================= -void SPELLserverCif::specificError( const std::string& msg, unsigned int scope ) +//==============================b=============================================== +void SPELLserverCif::specificError( const std::string& msgText, unsigned int scope ) { // We shall not bufferize in manual mode if (isManual()) { - completeMessage( m_wrMessage ); + SPELLsafeThreadOperations ops("Notify"); + SPELLipcMessage msg = m_wrMessage; + completeMessage( msg ); std::string timeStr = SPELLutils::timestampUsec(); - m_wrMessage.set(MessageField::FIELD_TEXT,msg); - m_wrMessage.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_ERROR); - m_wrMessage.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY); - m_wrMessage.set(MessageField::FIELD_TIME, timeStr); - m_wrMessage.set(MessageField::FIELD_SCOPE, ISTR(scope)); - sendGUIMessage(m_wrMessage); + msg.set(MessageField::FIELD_TEXT,msgText); + msg.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_ERROR); + msg.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY); + msg.set(MessageField::FIELD_TIME, timeStr); + msg.set(MessageField::FIELD_SCOPE, ISTR(scope)); + sendGUIMessage(msg); } else { - m_buffer->error( msg, scope ); + m_buffer->error( msgText, scope ); } } //void SPELLserverCif::specificError( const std::string& msg, unsigned int scope ) @@ -928,6 +966,7 @@ void SPELLserverCif::specificNotifyVariableChange( const std::vector& changed, const std::vector& deleted ) { + SPELLsafeThreadOperations ops("Notify"); m_wovBuffer->variableChange(added,changed,deleted); } @@ -938,7 +977,8 @@ void SPELLserverCif::specificNotifyVariableScopeChange( const std::string& scope const std::vector& globals, const std::vector& locals ) { - SPELLipcMessage notifyMsg(ExecutorMessages::MSG_SCOPE_CHANGE); + SPELLsafeThreadOperations ops("Notify"); + SPELLipcMessage notifyMsg(ExecutorMessages::MSG_SCOPE_CHANGE); notifyMsg.setType(MSG_TYPE_ONEWAY); std::string names = ""; @@ -989,11 +1029,34 @@ void SPELLserverCif::specificNotifyVariableScopeChange( const std::string& scope sendGUIMessage(notifyMsg); } +//============================================================================= +// METHOD: SPELLserverCif::specificNotifyResourceChange() +//============================================================================= +void SPELLserverCif::specificNotifyResourceChange( const std::vector& changed ) +{ + SPELLsafeThreadOperations ops("Notify"); + m_rdotcoBuffer->resourceChange(changed); +} + +//============================================================================= +// METHOD: SPELLserverCif::specificNotifyResourceList() +//============================================================================= +void SPELLserverCif::specificNotifyResourceList( const std::vector& resources ) +{ + SPELLsafeThreadOperations ops("Notify"); + m_rdotcoBuffer->resourceList(resources); +} + //============================================================================= // METHOD: SPELLserverCif::specificPrompt //============================================================================= void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::string& rawAnswer, std::string& answerToShow ) { + PyThreadState* m_state; + m_state = SPELLpythonHelper::instance().beginSafeAllowThreads(); + SPELLmonitor m(m_promptLock); + SPELLpythonHelper::instance().endSafeAllowThreads( m_state ); + m_promptDef = def; std::string timeStr = SPELLutils::timestampUsec(); @@ -1013,7 +1076,7 @@ void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::stri DEBUG("[CIF] Prompt typecode " + ISTR(def.typecode)); // the prompt display - std::string msgToShow = def.message; + std::string msgToShow = ""; if ( def.options.size() == 0 ) { @@ -1030,7 +1093,9 @@ void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::stri DEBUG("[CIF] Expected string: " + m_promptMessage.get(MessageField::FIELD_EXPECTED)); // Send the display message via the buffer to ensure synchronization - m_buffer->prompt(msgToShow, LanguageConstants::SCOPE_PROMPT); + m_asRun->writeInfo( getStack(), msgToShow, LanguageConstants::SCOPE_PROMPT ); + + m_buffer->prompt(def.message + "\n" + msgToShow, LanguageConstants::SCOPE_PROMPT); // Ensure buffer is flushed m_buffer->flush(); @@ -1097,11 +1162,14 @@ void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::stri // \todo When there is no controlling client we should keep the child procedure in prompt waiting state // Send the display message via the buffer to ensure synchronization - m_buffer->write("Answer: '" + toShow + "'", LanguageConstants::SCOPE_PROMPT); - m_buffer->flush(); + if ( (def.typecode & LanguageConstants::PROMPT_PASSWORD)>0) + m_buffer->write("Answer: '***'", LanguageConstants::SCOPE_PROMPT); + else + m_buffer->write("Answer: '" + toShow + "'", LanguageConstants::SCOPE_PROMPT); + m_buffer->flush(); - rawAnswer = toProcess; - answerToShow = toShow; + rawAnswer = toProcess; + answerToShow = toShow; } //============================================================================= @@ -1109,6 +1177,7 @@ void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::stri //============================================================================= std::string SPELLserverCif::specificOpenSubprocedure( const std::string& procId, int callingLine, const std::string& args, bool automatic, bool blocking, bool visible ) { + SPELLsafeThreadOperations ops("Notify"); std::string openModeStr = "{"; DEBUG("[CIF] Open subprocedure options: " + BSTR(automatic) + "," + BSTR(blocking) + "," + BSTR(visible)); openModeStr += (automatic ? (LanguageModifiers::Automatic + ":" + PythonConstants::True) : (LanguageModifiers::Automatic + ":" + PythonConstants::False)) + ","; @@ -1185,6 +1254,7 @@ std::string SPELLserverCif::specificOpenSubprocedure( const std::string& procId, //============================================================================= void SPELLserverCif::specificCloseSubprocedure( const std::string& procId ) { + SPELLsafeThreadOperations ops("Notify"); SPELLipcMessage closeMsg(ContextMessages::REQ_CLOSE_EXEC); closeMsg.setType(MSG_TYPE_REQUEST); closeMsg.set(MessageField::FIELD_SPROC_ID, procId); @@ -1197,6 +1267,7 @@ void SPELLserverCif::specificCloseSubprocedure( const std::string& procId ) //============================================================================= void SPELLserverCif::specificKillSubprocedure( const std::string& procId ) { + SPELLsafeThreadOperations ops("Notify"); SPELLipcMessage killMsg(ContextMessages::REQ_KILL_EXEC); killMsg.setType(MSG_TYPE_REQUEST); killMsg.set(MessageField::FIELD_SPROC_ID, procId); @@ -1265,6 +1336,7 @@ void SPELLserverCif::processMessage( const SPELLipcMessage& msg ) if (msgId == MessageId::MSG_ID_ADD_CLIENT) { LOG_INFO("Add controlling client"); + SPELLexecutor::instance().refreshStatus(); if (msg.hasField(MessageField::FIELD_GUI_CONTROL)) { getExecutorConfig().setHeadless( false ); @@ -1275,6 +1347,16 @@ void SPELLserverCif::processMessage( const SPELLipcMessage& msg ) else if (msgId == MessageId::MSG_ID_REMOVE_CLIENT) { LOG_WARN("Controlling client removed"); + + // In case of a (Warning) text to submit to GCS send it + if (msg.hasField(MessageField::FIELD_TEXT) && + msg.hasField(MessageField::FIELD_GUI_CONTROL) && + msg.get(MessageField::FIELD_GUI_CONTROL) == getExecutorConfig().getControlClient()) { + LOG_WARN("[CIF] " + msg.get(MessageField::FIELD_TEXT)); + SPELLexecutor::instance().getScheduler().raiseWarningEventToGCS(msg.get(MessageField::FIELD_TEXT)); + } + + SPELLexecutor::instance().refreshStatus(); switch(SPELLexecutor::instance().getStatus()) { case STATUS_FINISHED: @@ -1315,6 +1397,14 @@ void SPELLserverCif::processMessage( const SPELLipcMessage& msg ) { SPELLexecutor::instance().getVariableManager().setEnabled(false); } + else if (msgId == MessageId::MSG_ID_DRESOURCES_ENABLE) + { + SPELLexecutor::instance().getResourceManager().setEnabled(true); + } + else if (msgId == MessageId::MSG_ID_DRESOURCES_DISABLE) + { + SPELLexecutor::instance().getResourceManager().setEnabled(false); + } else { processMessageCommand(msg); @@ -1446,6 +1536,18 @@ SPELLipcMessage SPELLserverCif::processRequest( const SPELLipcMessage& msg ) { m_processor.processCheckVariablesEnabled(msg, response); } + else if (requestId == ExecutorMessages::REQ_GET_RESOURCES) + { + m_processor.processGetResources(msg, response); + } + else if (requestId == ExecutorMessages::REQ_CHANGE_RESOURCE) + { + m_processor.processChangeResource(msg, response); + } + else if (requestId == ExecutorMessages::REQ_DRESOURCES_ENABLED) + { + m_processor.processCheckResourcesEnabled(msg, response); + } else if (requestId == ExecutorMessages::REQ_GET_DICTIONARY) { m_processor.processGetDictionary(msg, response); @@ -1468,6 +1570,20 @@ void SPELLserverCif::processConnectionError( int clientKey, std::string error, s { if (!isClosing()) { + // send an alert to the GCS if context disconnect in transitionning states + switch(SPELLexecutor::instance().getStatus()) + { + case STATUS_FINISHED: + case STATUS_PAUSED: + case STATUS_ABORTED: + case STATUS_ERROR: + case STATUS_PROMPT: + case STATUS_INTERRUPTED: + break; + default: + SPELLexecutor::instance().getScheduler().raiseWarningEventToGCS("Procedure lost SPELL Context, check and resume: "+ getProcId()); + } + m_ready = false; LOG_ERROR("IPC error: " + error + ": " + reason); SPELLexecutor::instance().pause(); @@ -1578,7 +1694,7 @@ void SPELLserverCif::waitPromptAnswer() // Finish the prompt state SPELLexecutor::instance().getScheduler().finishPrompt(); - + //SPELLexecutor::instance().getScheduler().wait(); m_promptMessage = VOID_MESSAGE; } @@ -1800,4 +1916,42 @@ void SPELLserverCif::removeSharedDataScopes() { THROW_EXCEPTION(response.get(MessageField::FIELD_ERROR),response.get(MessageField::FIELD_REASON), SPELL_ERROR_ENVIRONMENT); } + +} +SPELLipcMessage SPELLserverCif::getPingMessage() +{ + if (SPELLexecutor::instance().hasController()) { + SPELLcontrollerIF& controller = + SPELLexecutor::instance().getController(); + + SPELLstatusInfo st(controller.getStatus()); + st.condition = controller.getCondition(); + st.actionLabel = SPELLexecutor::instance().getUserAction().getLabel(); + st.actionEnabled = + SPELLexecutor::instance().getUserAction().isEnabled(); + + m_stMessage.set(MessageField::FIELD_EXEC_STATUS, + SPELLexecutorUtils::statusToString(st.status)); + completeMessage(m_stMessage); + + // Set message Condition information + if (st.condition.size() > 0) { + m_stMessage.set(MessageField::FIELD_CONDITION, st.condition); + } + + // Set message Action information + if (st.actionLabel != "") { + m_stMessage.set(MessageField::FIELD_ACTION_LABEL, st.actionLabel); + m_stMessage.set(MessageField::FIELD_ACTION_ENABLED, + st.actionEnabled ? + MessageValue::DATA_TRUE : MessageValue::DATA_FALSE); + } + + return m_stMessage; + } + else + { + return SPELLipcMessage(); + } + } diff --git a/lib/SPELL_CIFS/src/SPELLvariableBuffer.C b/lib/SPELL_CIFS/src/SPELLvariableBuffer.C index a0ff793..2517521 100644 --- a/lib/SPELL_CIFS/src/SPELLvariableBuffer.C +++ b/lib/SPELL_CIFS/src/SPELLvariableBuffer.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the WOV messages buffer // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CTX/Makefile.am b/lib/SPELL_CTX/Makefile.am index 9272c3c..8bb4801 100644 --- a/lib/SPELL_CTX/Makefile.am +++ b/lib/SPELL_CTX/Makefile.am @@ -1,51 +1,72 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -#libSPELL_EXC_la_CPPFLAGS = ${AM_CPPFLAGS} -DWITH_DEBUG - -lib_LTLIBRARIES= libSPELL_CTX.la -libSPELL_CTX_la_LDFLAGS = -version-info 3:0:0 -libSPELL_CTX_la_SOURCES = \ - src/SPELLclient.C \ - src/SPELLclientInterestList.C \ - src/SPELLclientIPC.C \ - src/SPELLclientManager.C \ - src/SPELLclientNotifier.C \ - src/SPELLcontext.C \ - src/SPELLdataHelper.C \ - src/SPELLexecutor.C \ - src/SPELLexecutorIPC.C \ - src/SPELLexecutorOperation.C \ - src/SPELLexecutorManager.C \ - src/SPELLexecutorModel.C \ - src/SPELLlistenerIPC.C \ - src/SPELLpersistencyTable.C \ - src/SPELLsharedData.C \ - src/SPELLdataTable.C - - \ No newline at end of file +lib_LTLIBRARIES = libSPELL_CTX_v2.la libSPELL_CTX_v3.la + +libSPELL_CTX_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_CTX_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_CTX_v2_la_SOURCES = src/SPELLclient.C \ + src/SPELLclientInterestList.C \ + src/SPELLclientIPC.C \ + src/SPELLclientManager.C \ + src/SPELLclientNotifier.C \ + src/SPELLcontext.C \ + src/SPELLdataHelper.C \ + src/SPELLexecutor.C \ + src/SPELLexecutorIPC.C \ + src/SPELLexecutorOperation.C \ + src/SPELLexecutorManager.C \ + src/SPELLexecutorModel.C \ + src/SPELLservice.C \ + src/SPELLserviceManager.C \ + src/SPELLlistenerIPC.C \ + src/SPELLpersistencyTable.C \ + src/SPELLsharedData.C \ + src/SPELLdataTable.C + + +libSPELL_CTX_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_CTX_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_CTX_v3_la_SOURCES = src/SPELLclient.C \ + src/SPELLclientInterestList.C \ + src/SPELLclientIPC.C \ + src/SPELLclientManager.C \ + src/SPELLclientNotifier.C \ + src/SPELLcontext.C \ + src/SPELLdataHelper.C \ + src/SPELLexecutor.C \ + src/SPELLexecutorIPC.C \ + src/SPELLexecutorOperation.C \ + src/SPELLexecutorManager.C \ + src/SPELLexecutorModel.C \ + src/SPELLservice.C \ + src/SPELLserviceManager.C \ + src/SPELLlistenerIPC.C \ + src/SPELLpersistencyTable.C \ + src/SPELLsharedData.C \ + src/SPELLdataTable.C + \ No newline at end of file diff --git a/lib/SPELL_CTX/src/SPELLclient.C b/lib/SPELL_CTX/src/SPELLclient.C index e77382b..5b24327 100644 --- a/lib/SPELL_CTX/src/SPELLclient.C +++ b/lib/SPELL_CTX/src/SPELLclient.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the client // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -179,6 +179,10 @@ SPELLipcMessage SPELLclient::processRequestFromClient( const SPELLipcMessage& ms { resp = SPELLcontext::instance().getExecutorList( msg ); } + else if (msg.getId() == ContextMessages::REQ_SERVICE_LIST) + { + resp = SPELLcontext::instance().getServiceList( msg ); + } else if (msg.getId() == ContextMessages::REQ_PROC_PROP) { resp = SPELLcontext::instance().getProcedureProperties( msg ); @@ -191,6 +195,10 @@ SPELLipcMessage SPELLclient::processRequestFromClient( const SPELLipcMessage& ms { resp = SPELLcontext::instance().getExecutorInfo( msg ); } + else if (msg.getId() == ContextMessages::REQ_SERVICE_INFO) + { + resp = SPELLcontext::instance().getServiceInfo( msg ); + } else if (msg.getId() == ContextMessages::REQ_CLIENT_INFO) { resp = SPELLcontext::instance().getClientInfo( msg ); diff --git a/lib/SPELL_CTX/src/SPELLclientIPC.C b/lib/SPELL_CTX/src/SPELLclientIPC.C index 4095686..56ba56f 100644 --- a/lib/SPELL_CTX/src/SPELLclientIPC.C +++ b/lib/SPELL_CTX/src/SPELLclientIPC.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the client IPC interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -47,8 +47,11 @@ //============================================================================= SPELLclientIPC::SPELLclientIPC() : SPELLipcInterfaceListener(), +#ifdef WITH_KUBERNETES + m_ipc("CTX-TO-GUI", 888, 19888) +#else m_ipc("CTX-TO-GUI", 888, 0) - +#endif { SPELLclientManager::instance().setIPC(this); } @@ -133,6 +136,7 @@ void SPELLclientIPC::unregisterInterest( int clientKey, SPELLclientListener* lis //============================================================================= void SPELLclientIPC::processMessage( const SPELLipcMessage& msg ) { + LOG_INFO("[CLTRCV] Received message from client " + ISTR(msg.getKey()) + ": " + msg.getId() + " for ("+msg.get("User")+")"); // Get the peer key int clientKey = msg.getKey(); @@ -148,8 +152,9 @@ void SPELLclientIPC::processMessage( const SPELLipcMessage& msg ) //============================================================================= SPELLipcMessage SPELLclientIPC::processRequest( const SPELLipcMessage& msg ) { + if (msg.getId() != ContextMessages::REQ_CURRENT_TIME) + LOG_INFO("[CLTRCV] Received request from client " + ISTR(msg.getKey()) + ": " + msg.getId() + " for ("+msg.get("User")+")"); int clientKey = msg.getKey(); - DEBUG("[CLTRCV] Received request from client: " + msg.getId()); SPELLipcMessage resp = VOID_MESSAGE; SPELLclientInterestList* list = getClientInterestList(clientKey); // If the message is a login message, redirect it to the client manager @@ -193,7 +198,12 @@ SPELLipcMessage SPELLclientIPC::processRequest( const SPELLipcMessage& msg ) } else { - LOG_ERROR("No listeners for client " + ISTR(clientKey) + " to distribute request: " + msg.getId()); + if (msg.getId() == ContextMessages::REQ_CURRENT_TIME) { + resp = SPELLcontext::instance().getCurrentTime(msg); + return resp; + } else { + LOG_ERROR("No listeners for client " + ISTR(clientKey) + " to distribute request: " + msg.getId()); + } } return resp; } diff --git a/lib/SPELL_CTX/src/SPELLclientInterestList.C b/lib/SPELL_CTX/src/SPELLclientInterestList.C index 0d8ba7f..df78699 100644 --- a/lib/SPELL_CTX/src/SPELLclientInterestList.C +++ b/lib/SPELL_CTX/src/SPELLclientInterestList.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the client interest list // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CTX/src/SPELLclientManager.C b/lib/SPELL_CTX/src/SPELLclientManager.C index f5fd20c..48ca00d 100644 --- a/lib/SPELL_CTX/src/SPELLclientManager.C +++ b/lib/SPELL_CTX/src/SPELLclientManager.C @@ -5,7 +5,7 @@ // DESCRIPTION: Client manager implementation // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -29,12 +29,15 @@ #include "SPELL_CTX/SPELLclientManager.H" #include "SPELL_CTX/SPELLclient.H" #include "SPELL_CTX/SPELLdataHelper.H" +#include "SPELL_CTX/SPELLexecutorManager.H" // Project includes -------------------------------------------------------- #include "SPELL_SYN/SPELLmonitor.H" #include "SPELL_UTIL/SPELLlog.H" #include "SPELL_UTIL/SPELLutils.H" #include "SPELL_IPC/SPELLipc_Context.H" #include "SPELL_IPC/SPELLipc_Executor.H" +#include "SPELL_UTIL/SPELLerror.H" +#include "SPELL_PRD/SPELLprocedureManager.H" // System includes --------------------------------------------------------- @@ -46,7 +49,7 @@ SPELLclientManager* SPELLclientManager::s_instance = NULL; //============================================================================= SPELLclientManager::SPELLclientManager() { - + m_ipc = NULL; } //============================================================================= @@ -98,7 +101,7 @@ void SPELLclientManager::clientLogin( int clientKey, const std::string& host ) SPELLclient* client = new SPELLclient( clientKey, host, *m_ipc ); m_clientMap.insert( std::make_pair( clientKey, client )); - DEBUG("[CMGR] Client logged in: " + ISTR(clientKey)); + LOG_INFO("[CMGR] Client logged in: " + ISTR(clientKey) + " running on " + host); notifyClientOperation( clientKey, host, CLIENT_OP_LOGIN ); } @@ -118,6 +121,29 @@ void SPELLclientManager::clientLogout( int clientKey ) if (it != m_clientMap.end()) { SPELLclient* client = it->second; + + SPELLclient::ProcedureList procs = client->getProcedures(); + SPELLclient::ProcedureList::iterator pit; + for ( pit = procs.begin(); pit != procs.end(); pit++ ) + { + try + { + SPELLexecutor* exec = SPELLexecutorManager::instance().getExecutor( pit->first ); + if (pit->second == CLIENT_MODE_CONTROL ) + { + SPELLclientManager::instance().removeExecutorController(client, exec, true, true); + LOG_WARN("Client " + ISTR(clientKey) + " stop controlling executor " + exec->getModel().getInstanceId()); + } + else + { + SPELLclientManager::instance().stopMonitorExecutor(client, exec); + LOG_INFO("Client " + ISTR(clientKey) + " stop monitoring executor " + exec->getModel().getInstanceId()); + } + } + catch(SPELLcoreException& ex){}; + } + DEBUG("Client " + ISTR(clientKey) + " logged out, stopping procedures done"); + std::string host = client->getClientHost(); LOG_INFO("Client logged out: " + ISTR(clientKey) + ":" + host); delete client; @@ -141,6 +167,27 @@ void SPELLclientManager::clientLost( int clientKey ) if (it != m_clientMap.end()) { SPELLclient* client = it->second; + SPELLclient::ProcedureList procs = client->getProcedures(); + SPELLclient::ProcedureList::iterator pit; + for ( pit = procs.begin(); pit != procs.end(); pit++ ) + { + try + { + SPELLexecutor* exec = SPELLexecutorManager::instance().getExecutor( pit->first ); + if (pit->second == CLIENT_MODE_CONTROL ) + { + SPELLclientManager::instance().removeExecutorController(client, exec, true, true); + LOG_WARN("Client lost:" + ISTR(clientKey) + " stop controlling executor " + exec->getModel().getInstanceId()); + } + else + { + SPELLclientManager::instance().stopMonitorExecutor(client, exec); + LOG_INFO("Client lost:" + ISTR(clientKey) + " stop monitoring executor " + exec->getModel().getInstanceId()); + } + } + catch(SPELLcoreException& ex){}; + } + std::string host = client->getClientHost(); LOG_WARN("Client lost: " + ISTR(clientKey) + ":" + host); delete client; @@ -244,6 +291,8 @@ void SPELLclientManager::stopMonitorExecutor( SPELLclient* client, SPELLexecutor } } + + //============================================================================= // METHOD: SPELLclientManager:: //============================================================================= @@ -262,6 +311,11 @@ std::list SPELLclientManager::getMonitoringClients( const std::stri monitoring.push_back(id); } } + if (monitoring.empty() && procId.find("#") != std::string::npos) + { + std::string newId = noInstanceId(procId); + return getMonitoringClients(newId); + } return monitoring; } @@ -282,6 +336,11 @@ std::list SPELLclientManager::getMonitoringClientsKeys( const std::string& keys.push_back(notifier->getClientKey()); } } + if (keys.empty() && procId.find("#") != std::string::npos) + { + std::string newId = noInstanceId(procId); + return getMonitoringClientsKeys(newId); + } return keys; } @@ -316,9 +375,9 @@ void SPELLclientManager::notifyClientOperation( int clientKey, notification.set( MessageField::FIELD_GUI_KEY, ISTR(clientKey)); notification.set( MessageField::FIELD_CLOP, SPELLdataHelper::clientOperationToString(operation) ); notification.set( MessageField::FIELD_HOST, host ); - ClientMap::const_iterator it; - for( it = m_clientMap.begin(); it != m_clientMap.end(); it++ ) + ClientMap clientMap = m_clientMap; + for( it = clientMap.begin(); it != clientMap.end(); it++ ) { SPELLclient* client = it->second; if (client->getClientKey() == clientKey) continue; @@ -336,7 +395,8 @@ void SPELLclientManager::notifyClients( const SPELLipcMessage& msg ) SPELLmonitor m(m_clientLock); DEBUG("Notify clients IN"); ClientMap::const_iterator it; - for( it = m_clientMap.begin(); it != m_clientMap.end(); it++ ) + ClientMap clientMap = m_clientMap; + for( it = clientMap.begin(); it != clientMap.end(); it++ ) { SPELLclient* client = it->second; DEBUG(" - client " + ISTR(it->first)); @@ -355,7 +415,8 @@ void SPELLclientManager::notifyMonitoringClients( const SPELLipcMessage& msg ) DEBUG("Notify monitoring clients IN"); ClientMap::const_iterator it; int controllingKey = msg.getKey(); - for( it = m_clientMap.begin(); it != m_clientMap.end(); it++ ) + ClientMap clientMap = m_clientMap; + for( it = clientMap.begin(); it != clientMap.end(); it++ ) { SPELLclient* client = it->second; if (it->first == controllingKey) continue; diff --git a/lib/SPELL_CTX/src/SPELLclientNotifier.C b/lib/SPELL_CTX/src/SPELLclientNotifier.C index e783c75..af069c0 100644 --- a/lib/SPELL_CTX/src/SPELLclientNotifier.C +++ b/lib/SPELL_CTX/src/SPELLclientNotifier.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the client notifier // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CTX/src/SPELLcontext.C b/lib/SPELL_CTX/src/SPELLcontext.C index 4383e40..966945c 100644 --- a/lib/SPELL_CTX/src/SPELLcontext.C +++ b/lib/SPELL_CTX/src/SPELLcontext.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the context main class // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -26,11 +26,12 @@ // FILES TO INCLUDE //////////////////////////////////////////////////////// // Local includes ---------------------------------------------------------- +#include "SPELL_PRD/SPELLservicePython.H" #include "SPELL_CTX/SPELLcontext.H" #include "SPELL_CTX/SPELLclientManager.H" #include "SPELL_CTX/SPELLexecutorManager.H" +#include "SPELL_CTX/SPELLserviceManager.H" #include "SPELL_CTX/SPELLdataHelper.H" -// Project includes -------------------------------------------------------- #include "SPELL_SYN/SPELLmonitor.H" #include "SPELL_WRP/SPELLconstants.H" #include "SPELL_WRP/SPELLdriverManager.H" @@ -46,9 +47,9 @@ #include "SPELL_IPC/SPELLipc_Context.H" #include "SPELL_IPC/SPELLipc_Listener.H" #include "SPELL_SDB/SPELLdatabaseFactory.H" +#include "SPELL_WRP/SPELLdatabaseManager.H" // System includes --------------------------------------------------------- - // DEFINES ///////////////////////////////////////////////////////////////// #define NAME std::string("[CTX] ") @@ -56,7 +57,26 @@ SPELLcontext* SPELLcontext::s_instance = NULL; const std::string USE_DRIVER_TIME = "UseDriverTime"; - +extern "C" { + void checkService(std::string& serviceId) { + SPELLsafeThreadOperations ops("checkService"); + SPELLserviceManager::ServiceList runningServices = SPELLserviceManager::instance().getServiceList(); + for(SPELLserviceManager::ServiceList::iterator it = runningServices.begin();it != runningServices.end();++it) + { + //LOG_INFO("Service " + (*it) + " found!"); + if (*it == serviceId) + { + SPELLservice* service = SPELLserviceManager::instance().getService(serviceId); + if (service && service->isActive()) + { + return; + } + } + } + + SPELLcontext::instance().openService(serviceId); + } +} //============================================================================= // CONSTRUCTOR: SPELLcontext::SPELLcontext() //============================================================================= @@ -100,6 +120,7 @@ void SPELLcontext::start( const SPELLcontextConfiguration& config ) // Setup the configuration SPELLconfiguration::instance().loadConfig(m_config.configFile); + // Configure the time format if defined in configuration std::string format = SPELLconfiguration::instance().getCommonParameter("TdsTimeFormat"); if (format.length()!=0) @@ -126,8 +147,11 @@ void SPELLcontext::start( const SPELLcontextConfiguration& config ) m_executorDefaults.setPromptWarningDelay( STRI(srvConfig.getExecutorParameter(ExecutorConstants::PromptDelay)) ); m_executorDefaults.setByStep( srvConfig.getExecutorParameter(ExecutorConstants::ByStep) == ExecutorConstants::TRUE_VALUE ); m_executorDefaults.setForceTcConfirm( srvConfig.getExecutorParameter(ExecutorConstants::ForceTcConfirm) == ExecutorConstants::TRUE_VALUE ); + m_executorDefaults.setForcePromptConfirm( srvConfig.getExecutorParameter(ExecutorConstants::ForcePromptConfirm) == ExecutorConstants::TRUE_VALUE ); m_executorDefaults.setSaveStateMode( srvConfig.getExecutorParameter(ExecutorConstants::SaveStateMode) ); m_executorDefaults.setWatchVariables( srvConfig.getExecutorParameter(ExecutorConstants::WatchVariables) == ExecutorConstants::ENABLED ); + m_executorDefaults.setResourcesDisplay( srvConfig.getExecutorParameter(ExecutorConstants::ResourcesDisplay) == ExecutorConstants::ENABLED ); + m_executorDefaults.setLocalResourcesSupported( srvConfig.getExecutorParameter(ExecutorConstants::LocalResourcesSupported) == ExecutorConstants::TRUE_VALUE ); m_executorDefaults.setMaxVerbosity( STRI(srvConfig.getExecutorParameter(ExecutorConstants::MaxVerbosity)) ); m_executorDefaults.setBrowsableLibStr( srvConfig.getExecutorParameter(ExecutorConstants::BrowsableLib) ); @@ -141,11 +165,17 @@ void SPELLcontext::start( const SPELLcontextConfiguration& config ) if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ByStep) != "" ) m_executorDefaults.setByStep( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ByStep) == ExecutorConstants::TRUE_VALUE ); if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForceTcConfirm) != "" ) - m_executorDefaults.setForceTcConfirm( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForceTcConfirm) == ExecutorConstants::TRUE_VALUE ); + m_executorDefaults.setForceTcConfirm( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForceTcConfirm) == ExecutorConstants::TRUE_VALUE ); + if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForcePromptConfirm) != "" ) + m_executorDefaults.setForcePromptConfirm( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForcePromptConfirm) == ExecutorConstants::TRUE_VALUE ); if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::SaveStateMode) != "" ) m_executorDefaults.setSaveStateMode( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::SaveStateMode) ); if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::SaveStateMode) != "" ) m_executorDefaults.setWatchVariables( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::WatchVariables) == ExecutorConstants::ENABLED ); + if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ResourcesDisplay) != "" ) + m_executorDefaults.setResourcesDisplay( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ResourcesDisplay) == ExecutorConstants::ENABLED ); + if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::LocalResourcesSupported) != "" ) + m_executorDefaults.setLocalResourcesSupported( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::LocalResourcesSupported) == ExecutorConstants::TRUE_VALUE ); if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::MaxVerbosity) != "" ) m_executorDefaults.setMaxVerbosity( STRI(srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::MaxVerbosity)) ); if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::BrowsableLib) != "" ) @@ -160,30 +190,52 @@ void SPELLcontext::start( const SPELLcontextConfiguration& config ) // Initialize Python support (some client requests require Python API) SPELLpythonHelper::instance().initialize(); + SPELLsafePythonOperations ops("Context Init"); + SpellService_Install(); + + SPELLconfiguration::instance().loadPythonConfig(m_config.configFile); + if (SPELLconfiguration::instance().getContextParameter(USE_DRIVER_TIME) == "true") + { + // Setup the TIME driver for getCurrentTime (need to load Python config first) + SPELLdriverManager::instance().setup(getContextName(), "TIME"); + } + else + { + SPELLdriverManager::instance().setup(getContextName(), "CONFIG"); + } + + SPELLpythonHelper::instance().loadFramework(); + SPELLdatabaseManager::instance().loadBuiltinDatabases(); // Setup the procedure manager SPELLprocedureManager::instance().setup( getContextName() ); - // Setup the executor manager. This may take time to come back, if - // there are executors to reconnect to. The listener login message will be sent after this stage. - SPELLexecutorManager::instance().setup( getContextName() ); - - if (SPELLconfiguration::instance().getContextParameter(USE_DRIVER_TIME) == "true") - { - // Setup the TIME driver for getCurrentTime (need to load Python config first) - SPELLconfiguration::instance().loadPythonConfig(m_config.configFile); - SPELLdriverManager::instance().setup(getContextName(), "TIME"); - } // Setup the IPC interfaces to clients and listener. The listener one logs in. m_clientIPC.setup(); - m_listenerIPC.setup(); + m_listenerIPC.setup(); + + // Setup the executor manager. This may take time to come back, if + // there are executors to reconnect to. The listener login message will be sent after this stage. + SPELLexecutorManager::instance().setup(getContextName()); + SPELLserviceManager::instance().setup(getContextName()); - LOG_INFO("Context " + getContextName() + " ready" ); + LOG_INFO("Context " + getContextName() + " ready" ); // SPELLpythonHelper::initialize has acquired the GIL. Release it so // that operations in other threads (messages) can use it too. - PyEval_ReleaseLock(); + + + std::list serviceList = SPELLprocedureManager::instance().getServiceList(); + std::list::iterator it = serviceList.begin(); + for (; it != serviceList.end(); ++it) + { + LOG_INFO("Starting Service " + (*it) + "." ); + //openService(*it); + SPELLpyService& exec = SPELLprocedureManager::instance().getService(*it); + exec.startWatchDog(&checkService); + } + } //============================================================================= @@ -291,8 +343,9 @@ SPELLipcMessage SPELLcontext::openExecutor( const SPELLipcMessage& msg, SPELLcli std::string theOriginId = "GUI"; if (msg.hasField( MessageField::FIELD_ORIGIN_ID )) { - theOriginId = msg.get( MessageField::FIELD_ORIGIN_ID ); + theOriginId = msg.get( MessageField::FIELD_ORIGIN_ID ) ; } + theOriginId = theOriginId + " ("+msg.get("User")+")"; SPELLexecutorStartupParams config(theInstanceId, SPELLutils::fileTimestamp() ); @@ -322,6 +375,18 @@ SPELLipcMessage SPELLcontext::openExecutor( const SPELLipcMessage& msg, SPELLcli try { + SPELLprocedureManager::ProcList services = SPELLprocedureManager::instance().getServiceList(); + SPELLprocedureManager::ProcList::const_iterator it = services.begin(); + for (;it != services.end();++it) + { + if (config.getProcId() == *it) + { + resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_OPEN_EXEC, msg ); + resp.set( MessageField::FIELD_ERROR, "Cannot open selected service"); + resp.set( MessageField::FIELD_REASON, "The select entry is a service and can't be started manually." ); + return resp; + } + } SPELLexecutorManager::instance().startExecutor( config, controllingClient ); resp = SPELLipcHelper::createResponse( ContextMessages::RSP_OPEN_EXEC, msg ); @@ -367,6 +432,86 @@ SPELLipcMessage SPELLcontext::openExecutor( const SPELLipcMessage& msg, SPELLcli return resp; } +bool SPELLcontext::openService( const std::string serviceName ) +{ + LOG_INFO( "Requested opening new service" ); + + // Get the information about procedure instance identifiers. Note that if the procedure + // has been started by another one, there will be a parent instance identifier in the request message. + // + // - The identifier of the child (subprocedure) will be in SPROC_ID in this case, + // - The identifier of the parent will be in the PROC_ID. + std::string theInstanceId = ""; + std::string theParentInstanceId = ""; + // Note that the group id matches the instance id for standalone procedures, but it is + // the id of the original main procedure for all the children down a dependency tree. + std::string theGroupId = serviceName; + + // The following condition is for the case when we have a subprocedure being started. + int callingLine = 0; + theInstanceId = serviceName; + + // Origin ID is just informative for SPELL and it is optional + std::string theOriginId = "SERVICE"; + + SPELLserviceStartupParams config(theInstanceId, SPELLutils::fileTimestamp() ); + + config.setArguments(""); + config.setCondition(""); + std::string cMode = MessageValue::DATA_GUI_MODE_B; + config.setClientMode(SPELLdataHelper::clientModeFromString(cMode)); + std::string oMode = "1"; + config.setOpenMode(SPELLdataHelper::openModeFromString(oMode)); + config.setParentInstanceId(theParentInstanceId); + config.setParentCallingLine(callingLine); + config.setGroupId( theGroupId ); + config.setOriginId( theOriginId ); + + LOG_INFO(" - Instance Id : " + config.getInstanceId()); + LOG_INFO(" - Client mode : " + cMode); + LOG_INFO(" - Group Id : " + config.getGroupId()); + LOG_INFO(" - Origin Id : " + config.getOriginId()); + LOG_INFO(" - Calling line: " + ISTR(config.getParentCallingLine()) ); + LOG_INFO(" - Time Id : " + config.getTimeId()); + LOG_INFO(" - Proc Id : " + config.getProcId()); + LOG_INFO(" - Instance num: " + ISTR(config.getInstanceNum())); + LOG_INFO(" - Arguments : " + config.getArguments()); + LOG_INFO(" - Condition : " + config.getCondition()); + LOG_INFO(" - Open mode : " + oMode); + LOG_INFO(" - Parent : " + config.getParentInstanceId()); + + try + { + SPELLserviceManager::instance().startService( config ); + + SPELLservice* exec = SPELLserviceManager::instance().getService(config.getInstanceId()); + SPELLexecutorStatus initialStatus = exec->getStatus(); + + config.setClientMode(CLIENT_MODE_BACKGROUND); + + // Notify other clients + SPELLexecutorOperation op; + op.instanceId = config.getInstanceId(); + op.parentId = theParentInstanceId; + op.groupId = config.getGroupId(); + op.originId = config.getOriginId(); + op.clientKey = -1; + op.clientMode = config.getClientMode(); + op.status = initialStatus; + op.condition = config.getCondition(); + op.type = SPELLexecutorOperation::EXEC_OP_OPEN; + notifyExecutorOperation( op ); + + } + catch( SPELLcoreException& err ) + { + err.loggit(); + return false; + } + return true; +} + + //============================================================================= // METHOD: SPELLcontext:: //============================================================================= @@ -643,6 +788,8 @@ SPELLipcMessage SPELLcontext::getProcedureList( const SPELLipcMessage& msg ) SPELLprocedureManager::instance().refresh(); } } + + SPELLprocedureManager::ProcList list = SPELLprocedureManager::instance().getProcList(); std::string listStr = ""; @@ -652,6 +799,15 @@ SPELLipcMessage SPELLcontext::getProcedureList( const SPELLipcMessage& msg ) if (listStr != "") listStr += LIST_SEPARATOR; listStr += *it; } + + list = SPELLprocedureManager::instance().getServiceList(); + + for( it = list.begin(); it != list.end(); it++) + { + if (listStr != "") listStr += LIST_SEPARATOR; + listStr += *it + "|" + *it; + } + resp = SPELLipcHelper::createResponse( ContextMessages::RSP_PROC_LIST, msg ); resp.set( MessageField::FIELD_PROC_LIST, listStr ); return resp; @@ -750,13 +906,18 @@ SPELLipcMessage SPELLcontext::listFiles( const SPELLipcMessage& msg ) if (fileList.size()>0) fileList += LIST_SEPARATOR; fileList += "+" + *it; } + resp = SPELLipcHelper::createResponse( ContextMessages::RSP_LIST_FILES, msg ); + resp.set( MessageField::FIELD_FILE_LIST, fileList ); } else { LOG_ERROR("Path does not exist, cannot list files: '" + dir + "'"); + resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_LIST_FILES, msg ); + resp.set( MessageField::FIELD_FILE_LIST, "" ); + resp.set( MessageField::FIELD_ERROR, "Cannot list files"); + resp.set( MessageField::FIELD_REASON, "Path does not exist: '" + dir + "'"); + resp.set( MessageField::FIELD_FATAL, "false"); } - resp = SPELLipcHelper::createResponse( ContextMessages::RSP_LIST_FILES, msg ); - resp.set( MessageField::FIELD_FILE_LIST, fileList ); return resp; } @@ -860,11 +1021,38 @@ SPELLipcMessage SPELLcontext::getExecutorList( const SPELLipcMessage& msg ) DEBUG(" found " + *it); listStr += *it; } + + SPELLserviceManager::ServiceList serviceList = SPELLserviceManager::instance().getServiceList(); + + SPELLserviceManager::ServiceList::const_iterator sit; + for( sit = serviceList.begin(); sit != serviceList.end(); sit++) + { + if (listStr != "") listStr += LIST_SEPARATOR; + DEBUG(" found " + *sit); + listStr += *sit + "#0"; + } + + resp = SPELLipcHelper::createResponse( ContextMessages::RSP_EXEC_LIST, msg ); resp.set( MessageField::FIELD_EXEC_LIST, listStr ); return resp; } +//============================================================================= +// METHOD: SPELLcontext:: +//============================================================================= +SPELLipcMessage SPELLcontext::getServiceList( const SPELLipcMessage& msg ) +{ + DEBUG( NAME + "Requested list of services"); + SPELLipcMessage resp = VOID_MESSAGE; + SPELLserviceManager::ServiceList list = SPELLserviceManager::instance().getServiceList(); + std::string listStr = ""; + + resp = SPELLipcHelper::createResponse( ContextMessages::RSP_SERVICE_LIST, msg ); + resp.set( MessageField::FIELD_EXEC_LIST, listStr ); + return resp; +} + //============================================================================= // METHOD: SPELLcontext:: //============================================================================= @@ -899,6 +1087,19 @@ SPELLipcMessage SPELLcontext::getExecutorInfo( const SPELLipcMessage& msg ) return resp; } +//============================================================================= +// METHOD: SPELLcontext:: +//============================================================================= +SPELLipcMessage SPELLcontext::getServiceInfo( const SPELLipcMessage& msg ) +{ + std::string instanceId = msg.get( MessageField::FIELD_PROC_ID ); + SPELLipcMessage resp = SPELLipcHelper::createResponse( ContextMessages::RSP_EXEC_INFO, msg); + DEBUG( NAME + "Requested service information: " + instanceId); + SPELLserviceManager::instance().buildServiceInfo( instanceId, resp ); + + return resp; +} + //============================================================================= // METHOD: SPELLcontext::getExecutorDefaults @@ -953,7 +1154,11 @@ SPELLipcMessage SPELLcontext::setExecutorDefaults( const SPELLipcMessage& msg ) LOG_INFO(" - TC confirm : " + msg.get(MessageField::FIELD_FORCE_TC_CONFIRM) ); m_executorDefaults.setForceTcConfirm( msg.get(MessageField::FIELD_FORCE_TC_CONFIRM) == ExecutorConstants::TRUE_VALUE ); } - + if( msg.hasField(MessageField::FIELD_FORCE_PROMPT_CONFIRM) ) + { + LOG_INFO(" - Prompt confirm: " + msg.get(MessageField::FIELD_FORCE_PROMPT_CONFIRM) ); + m_executorDefaults.setForcePromptConfirm( msg.get(MessageField::FIELD_FORCE_PROMPT_CONFIRM) == ExecutorConstants::TRUE_VALUE ); + } if( msg.hasField(MessageField::FIELD_SAVE_STATE_MODE) ) { LOG_INFO(" - Save state : " + msg.get(MessageField::FIELD_SAVE_STATE_MODE) ); @@ -966,6 +1171,18 @@ SPELLipcMessage SPELLcontext::setExecutorDefaults( const SPELLipcMessage& msg ) m_executorDefaults.setWatchVariables( msg.get(MessageField::FIELD_WATCH_VARIABLES) == ExecutorConstants::TRUE_VALUE ); } + if( msg.hasField(MessageField::FIELD_RESOURCES_DISPLAY) ) + { + LOG_INFO(" - Resource disp: " + msg.get(MessageField::FIELD_RESOURCES_DISPLAY) ); + m_executorDefaults.setResourcesDisplay( msg.get(MessageField::FIELD_RESOURCES_DISPLAY) == ExecutorConstants::TRUE_VALUE ); + } + + if( msg.hasField(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED) ) + { + LOG_INFO(" - Local resource support: " + msg.get(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED) ); + m_executorDefaults.setLocalResourcesSupported( msg.get(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED) == ExecutorConstants::TRUE_VALUE ); + } + if( msg.hasField(MessageField::FIELD_MAX_VERBOSITY) ) { LOG_INFO(" - Verbosity : " + msg.get(MessageField::FIELD_MAX_VERBOSITY) ); @@ -993,8 +1210,11 @@ void SPELLcontext::fillExecutorDefaults( SPELLipcMessage& msg ) msg.set( MessageField::FIELD_PROMPT_DELAY, ISTR(m_executorDefaults.getPromptWarningDelay()) ); msg.set( MessageField::FIELD_BY_STEP, (m_executorDefaults.isByStep() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) ); msg.set( MessageField::FIELD_FORCE_TC_CONFIRM, (m_executorDefaults.isForceTcConfirm() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) ); + msg.set( MessageField::FIELD_FORCE_PROMPT_CONFIRM, (m_executorDefaults.isForcePromptConfirm() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) ); msg.set( MessageField::FIELD_SAVE_STATE_MODE, m_executorDefaults.getSaveStateMode() ); msg.set( MessageField::FIELD_WATCH_VARIABLES, (m_executorDefaults.isWatchVariables() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) ); + msg.set( MessageField::FIELD_RESOURCES_DISPLAY, (m_executorDefaults.isResourcesDisplay() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) ); + msg.set( MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED, (m_executorDefaults.isLocalResourcesSupported() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) ); msg.set( MessageField::FIELD_MAX_VERBOSITY, ISTR(m_executorDefaults.getMaxVerbosity()) ); msg.set( MessageField::FIELD_BROWSABLE_LIB, m_executorDefaults.getBrowsableLibStr() ); @@ -1083,11 +1303,58 @@ SPELLipcMessage SPELLcontext::attachExecutor( const SPELLipcMessage& msg, SPELLc } catch( SPELLcoreException& ex ) { - LOG_ERROR("Cannot attach: " + std::string(ex.what()) ); - resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_ATTACH_EXEC, msg ); - resp.set( MessageField::FIELD_ERROR, "Cannot attach to executor"); - resp.set( MessageField::FIELD_REASON, ex.what()); - resp.set( MessageField::FIELD_FATAL, PythonConstants::True ); + + try + { + SPELLservice* exec = SPELLserviceManager::instance().getService(instanceId); + std::string groupId = exec->getModel().getGroupId(); + std::string originId = exec->getModel().getOriginId(); + + if (mode == CLIENT_MODE_CONTROL) + { + LOG_ERROR("Cannot take control of Service! Not supported for service: " + instanceId ); + resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_ATTACH_EXEC, msg ); + resp.set( MessageField::FIELD_ERROR, "Cannot attach to service in controlling mode"); + resp.set( MessageField::FIELD_REASON, "Not supported for service" ); + resp.set( MessageField::FIELD_FATAL, PythonConstants::True ); + } + else + { + // Set the procedure controlling client on the client model + client->addProcedure(instanceId, CLIENT_MODE_MONITOR); + + LOG_INFO("Client " + ISTR(client->getClientKey()) + " monitoring service " + instanceId); + + resp = SPELLipcHelper::createResponse( ContextMessages::RSP_ATTACH_EXEC, msg ); + // Add the executor information + SPELLexecutorManager::instance().buildExecutorInfo( instanceId, resp ); + // Add the GUI list + SPELLclientManager::instance().completeMonitoringInfo( instanceId, resp ); + // Monitor the executor + SPELLclientManager::instance().startMonitorExecutor(client, exec ); + // Notify other clients + SPELLexecutorOperation op; + op.instanceId = instanceId; + op.parentId = exec->getParentInstanceId(); + op.groupId = groupId; + op.originId = originId; + op.clientKey = msg.getKey(); + op.clientMode = CLIENT_MODE_MONITOR; + op.status = exec->getStatus(); + op.type = SPELLexecutorOperation::EXEC_OP_ATTACH; + notifyExecutorOperation( op ); + } + } + catch( SPELLcoreException& ex ) + { + + + LOG_ERROR("Cannot attach: " + std::string(ex.what()) ); + resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_ATTACH_EXEC, msg ); + resp.set( MessageField::FIELD_ERROR, "Cannot attach to executor"); + resp.set( MessageField::FIELD_REASON, ex.what()); + resp.set( MessageField::FIELD_FATAL, PythonConstants::True ); + } } return resp; } @@ -1183,6 +1450,45 @@ void SPELLcontext::executorLost( const std::string& instanceId ) catch(SPELLcoreException& ex){}; } +//============================================================================= +// METHOD: SPELLcontext:: +//============================================================================= +void SPELLcontext::serviceLost( const std::string& instanceId ) +{ + try + { + LOG_ERROR("Service lost: " + instanceId); + SPELLservice* exec = SPELLserviceManager::instance().getService( instanceId ); + std::string groupId = exec->getModel().getGroupId(); + std::string originId = exec->getModel().getOriginId(); + std::string parentId = exec->getModel().getParentInstanceId(); + std::string name = exec->getModel().getProcId(); + LOG_ERROR(" - Group ID : " + groupId); + LOG_ERROR(" - Origin ID: " + originId); + LOG_ERROR(" - Parent ID: " + parentId); + + LOG_ERROR("Notify clients about executor lost"); + + // Notify all GUIs in the system + SPELLexecutorOperation op; + op.instanceId = instanceId; + op.status = STATUS_ERROR; + op.groupId = groupId; + op.originId = originId; + op.parentId = parentId; + op.type = SPELLexecutorOperation::EXEC_OP_CRASH; + notifyExecutorOperation( op ); + + // Mark the model to be removed (cannot delete now, since this operation is + // triggered from the process model itself + SPELLserviceManager::instance().closeService( instanceId ); + +// openService(instanceId); + + } + catch(SPELLcoreException& ex){}; +} + //============================================================================= // METHOD: SPELLcontext:: //============================================================================= @@ -1228,12 +1534,39 @@ SPELLipcMessage SPELLcontext::detachExecutor( const SPELLipcMessage& msg, SPELLc } catch( SPELLcoreException& ex ) { - LOG_ERROR("Cannot detach: " + std::string(ex.what()) ); - resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_DETACH_EXEC, msg ); - resp.set( MessageField::FIELD_ERROR, "Cannot detach from executor"); - resp.set( MessageField::FIELD_REASON, ex.what() ); - resp.set( MessageField::FIELD_FATAL, PythonConstants::True ); - } + try + { + SPELLservice* exec = SPELLserviceManager::instance().getService(instanceId); + std::string groupId = exec->getModel().getGroupId(); + std::string originId = exec->getModel().getOriginId(); + + LOG_INFO("Client " + ISTR(client->getClientKey()) + " detached from service " + instanceId); + + // To notify to other clients + SPELLexecutorOperation op; + op.instanceId = instanceId; + op.clientKey = msg.getKey(); + op.groupId = groupId; + op.originId = originId; + op.status = exec->getStatus(); + op.type = SPELLexecutorOperation::EXEC_OP_DETACH; + + resp = SPELLipcHelper::createResponse(ContextMessages::RSP_DETACH_EXEC, msg); + + SPELLclientManager::instance().stopMonitorExecutor(client, exec); + op.clientMode = CLIENT_MODE_MONITOR; + + + notifyExecutorOperation(op); + } catch (SPELLcoreException& ex) + { + LOG_ERROR("Cannot detach: " + std::string(ex.what())); + resp = SPELLipcHelper::createErrorResponse(ContextMessages::RSP_DETACH_EXEC, msg); + resp.set(MessageField::FIELD_ERROR, "Cannot detach from executor"); + resp.set(MessageField::FIELD_REASON, ex.what()); + resp.set(MessageField::FIELD_FATAL, PythonConstants::True); + } + } return resp; } diff --git a/lib/SPELL_CTX/src/SPELLdataHelper.C b/lib/SPELL_CTX/src/SPELLdataHelper.C index 33b7a5b..706aca8 100644 --- a/lib/SPELL_CTX/src/SPELLdataHelper.C +++ b/lib/SPELL_CTX/src/SPELLdataHelper.C @@ -5,7 +5,7 @@ // DESCRIPTION: Data handling utilities // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CTX/src/SPELLdataTable.C b/lib/SPELL_CTX/src/SPELLdataTable.C index c8d54a0..e09e8b8 100644 --- a/lib/SPELL_CTX/src/SPELLdataTable.C +++ b/lib/SPELL_CTX/src/SPELLdataTable.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the shared data tables // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CTX/src/SPELLexecutor.C b/lib/SPELL_CTX/src/SPELLexecutor.C index b2c7986..7a54a20 100644 --- a/lib/SPELL_CTX/src/SPELLexecutor.C +++ b/lib/SPELL_CTX/src/SPELLexecutor.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -42,53 +42,42 @@ #include "SPELL_UTIL/SPELLtime.H" #include "SPELL_IPC/SPELLipc_Executor.H" #include "SPELL_IPC/SPELLipc_Context.H" +#include "SPELL_PRD/SPELLprocedureManager.H" // System includes --------------------------------------------------------- -class LoginMonitor : public SPELLthread -{ -public: - LoginMonitor( SPELLexecutor& exec ) - : SPELLthread("login-" + exec.getModel().getInstanceId() ), - m_exec( exec ) - {} - void run() - { - SPELLtime checkStart; - for(;;) - { - SPELLtime now; - SPELLtime delta = now - checkStart; - if (delta.getSeconds()>120) - { - SPELLexecutorManager::instance().callback_executorNotReconnected( m_exec.getModel().getInstanceId() ); - return; - } - else - { - if (m_exec.isLoggedIn()) - { - SPELLexecutorManager::instance().callback_executorReconnected( m_exec.getModel().getInstanceId() ); - return; - } - else - { - usleep(30000); - } - } - } - } - -private: - SPELLexecutor& m_exec; -}; // DEFINES ///////////////////////////////////////////////////////////////// #define DEFAULT_START_TIMEOUT 20 #define DEFAULT_LOGIN_TIMEOUT 60 - +void LoginMonitor::run() +{ + SPELLtime checkStart; + for (;;) + { + SPELLtime now; + SPELLtime delta = now - checkStart; + if (delta.getSeconds() > 120) + { + SPELLexecutorManager::instance().callback_executorNotReconnected(m_exec.getModel().getInstanceId()); + return; + } + else + { + if (m_exec.isLoggedIn()) + { + SPELLexecutorManager::instance().callback_executorReconnected(m_exec.getModel().getInstanceId()); + return; + } + else + { + usleep(30000); + } + } + } +} //============================================================================= // CONSTRUCTOR: SPELLexecutor::SPELLexecutor() //============================================================================= @@ -112,6 +101,10 @@ SPELLexecutor::SPELLexecutor( const SPELLexecutorStartupParams& config, SPELLcli m_reconnecting = config.isReconnecting(); m_loggedIn = false; m_loginMonitor = NULL; + m_notAckNotifications = 0; + m_status = STATUS_UNINIT; + m_processStatus = PSTATUS_INITIAL; + } //============================================================================= @@ -150,6 +143,15 @@ void SPELLexecutor::start() THROW_EXCEPTION("Cannot launch executor", "No executor command defined in configuration", SPELL_ERROR_CONFIG); } + std::string pyVersion = SPELLprocedureManager::instance().getProperty(m_model.getProcId(),"PYTHON VERSION"); + if (pyVersion.empty()) + pyVersion = "2"; + LOG_INFO("Requested executor for python version " + pyVersion); + if (pyVersion.find("3") == 0) + { + command += "_v3"; + } + int startTimeout = -1; int loginTimeout = -1; std::string startTimeoutStr = SPELLconfiguration::instance().getContextParameter( SPELLcontextConfig::ExecutorStartTimeout ); @@ -177,7 +179,8 @@ void SPELLexecutor::start() { command += " -r " + m_model.getWsFilename(); } - + if (SPELLprocessManager::instance().checkProcessExist(m_model.getInstanceId() )) + SPELLprocessManager::instance().killProcess( m_model.getInstanceId() ); SPELLprocessManager::instance().clearProcess( m_model.getInstanceId() ); SPELLprocessManager::instance().startProcess( m_model.getInstanceId(), command ); @@ -355,7 +358,12 @@ SPELLipcMessage SPELLexecutor::sendRequestToExecutor( const SPELLipcMessage& msg SPELLipcMessage response = VOID_MESSAGE; if (processOk()) { - response = m_ipc.sendRequest( m_model.getInstanceId(), msg, 5000 ); + int timeout = 3000; + if (msg.getId() == ExecutorMessages::REQ_WVARIABLES_ENABLED) + { + timeout = 500; + } + response = m_ipc.sendRequest( m_model.getInstanceId(), msg, timeout ); } else { @@ -496,7 +504,7 @@ SPELLipcMessage SPELLexecutor::processRequestFromExecutor( SPELLipcMessage msg ) //============================================================================= // METHOD: SPELLexecutor:: //============================================================================= -void SPELLexecutor::processStarted( const std::string& identifier ) +void SPELLexecutor::processStarted( const std::string identifier ) { DEBUG("Callback - Executor process started: " + identifier); m_processStatus = PSTATUS_RUNNING; @@ -506,7 +514,7 @@ void SPELLexecutor::processStarted( const std::string& identifier ) //============================================================================= // METHOD: SPELLexecutor:: //============================================================================= -void SPELLexecutor::processFinished( const std::string& identifier, const int& retValue ) +void SPELLexecutor::processFinished( const std::string identifier, const int& retValue ) { LOG_INFO("Executor process finished: " + identifier); m_processStatus = PSTATUS_FINISHED; @@ -517,7 +525,7 @@ void SPELLexecutor::processFinished( const std::string& identifier, const int& r //============================================================================= // METHOD: SPELLexecutor:: //============================================================================= -void SPELLexecutor::processKilled( const std::string& identifier ) +void SPELLexecutor::processKilled( const std::string identifier ) { LOG_ERROR("Executor process killed: " + identifier); m_model.setStatus(STATUS_ERROR); @@ -547,7 +555,7 @@ void SPELLexecutor::processKilled( const std::string& identifier ) //============================================================================= // METHOD: SPELLexecutor:: //============================================================================= -void SPELLexecutor::processFailed( const std::string& identifier ) +void SPELLexecutor::processFailed( const std::string identifier ) { LOG_ERROR("Executor process failed startup: " + identifier); m_model.setStatus(STATUS_ABORTED); @@ -654,6 +662,11 @@ bool SPELLexecutor::isActive() DEBUG("Executor " + m_model.getInstanceId() + " active: " + SPELLdataHelper::executorStatusToString(getStatus())); return true; } + if (m_reconnecting) + { + DEBUG("Executor " + m_model.getInstanceId() + " is reconnecting: " + SPELLdataHelper::executorStatusToString(getStatus())); + return true; + } return false; } @@ -723,6 +736,9 @@ void SPELLexecutor::removeControllingClient( bool clientLost ) removeClient.set( MessageField::FIELD_PROC_ID, m_model.getInstanceId() ); removeClient.set( MessageField::FIELD_GUI_CONTROL, ISTR(cKey)); removeClient.set( MessageField::FIELD_GUI_CONTROL_HOST, cHost); + if (clientLost) { + removeClient.set( MessageField::FIELD_TEXT, "Procedure GUI disconnected from SPELL Context: " + m_model.getInstanceId()); + } sendMessageToExecutor(removeClient); LOG_INFO("Controlling client removed"); @@ -752,6 +768,8 @@ void SPELLexecutor::forcePause() } else if (getStatus() == STATUS_RUNNING) { + if (m_executorStatusEvent.isClear()) + return; cmd.id = CMD_PAUSE; LOG_WARN("Pausing procedure (force stop)"); command(cmd); @@ -974,12 +992,16 @@ SPELLipcMessage SPELLexecutor::executorLogin( const SPELLipcMessage& msg ) DEBUG("Received executor login: " + m_model.getInstanceId() ); m_loggedIn = true; + m_model.setStatus(STATUS_UNINIT); // Store the information given by the executor + LOG_INFO("Executor login provided: " + m_model.getInstanceId()); m_model.setIpcKey(msg.getKey()); - m_model.setStatus(SPELLdataHelper::stringToExecutorStatus( msg.get( MessageField::FIELD_EXEC_STATUS ))); + LOG_INFO(" IPC key: " + msg.getKey()); m_model.setAsRunFilename( msg.get( MessageField::FIELD_ASRUN_NAME )); + LOG_INFO(" ASRUN : " + msg.get( MessageField::FIELD_ASRUN_NAME )); m_model.setLogFilename( msg.get( MessageField::FIELD_LOG_NAME )); + LOG_INFO(" LOG : " + msg.get( MessageField::FIELD_LOG_NAME )); //TODO //m_model.wsFileName = msg.get( MessageField::FIELD_WS_NAME ); @@ -1110,7 +1132,7 @@ void SPELLexecutor::executorNotification( const SPELLipcMessage& nmsg ) // Force an additional status notification upon line notifications where // the stage title changes - if (getModel().getStageId() != id) + if (getModel().getStageId() != id || getModel().getStageTitle() != tl) { getModel().setStage(id,tl); SPELLexecutorOperation op; diff --git a/lib/SPELL_CTX/src/SPELLexecutorIPC.C b/lib/SPELL_CTX/src/SPELLexecutorIPC.C index 5543ca3..07d289c 100644 --- a/lib/SPELL_CTX/src/SPELLexecutorIPC.C +++ b/lib/SPELL_CTX/src/SPELLexecutorIPC.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor IPC interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -59,10 +59,10 @@ SPELLexecutorIPC::SPELLexecutorIPC( SPELLexecutor& controller, const SPELLexecut //============================================================================= SPELLexecutorIPC::~SPELLexecutorIPC() { - DEBUG("[EXCIPC] Destroying"); + //DEBUG("[EXCIPC] Destroying"); m_ipc.removeListener(); m_ipc.join(); - DEBUG("[EXCIPC] Destroyed"); + //DEBUG("[EXCIPC] Destroyed"); } //============================================================================= @@ -70,7 +70,7 @@ SPELLexecutorIPC::~SPELLexecutorIPC() //============================================================================= void SPELLexecutorIPC::setup() { - DEBUG("[EXCIPC] Setup"); + //DEBUG("[EXCIPC] Setup"); m_ipc.initialize(&*this); m_ipc.connect(); m_ipc.start(); @@ -83,13 +83,13 @@ void SPELLexecutorIPC::setup() void SPELLexecutorIPC::cleanup() { SPELLmonitor m(m_notifyLock); - DEBUG("[EXCIPC] Cleanup"); + //DEBUG("[EXCIPC] Cleanup"); m_connected = false; - DEBUG("[EXCIPC] Close executor connection"); + //DEBUG("[EXCIPC] Close executor connection"); m_ipc.removeListener(); - DEBUG("[EXCIPC] Perform disconnection"); + //DEBUG("[EXCIPC] Perform disconnection"); m_ipc.disconnect(); - DEBUG("[EXCIPC] Close executor connection done"); + //DEBUG("[EXCIPC] Close executor connection done"); } //============================================================================= @@ -138,21 +138,21 @@ SPELLipcMessage SPELLexecutorIPC::sendRequest( const std::string& executorId, co void SPELLexecutorIPC::processMessage( const SPELLipcMessage& msg ) { TICK_IN; - DEBUG("[EXCIPC] Received message from executor: " + msg.dataStr()); + //DEBUG("[EXCIPC] Received message from executor: " + msg.dataStr()); // Certain messages are for monitoring clients only if ((msg.getId() != MessageId::MSG_ID_PROMPT_START)&&(msg.getId() != MessageId::MSG_ID_PROMPT_END)) { - DEBUG("[EXCIPC] Forward message to controller"); + //DEBUG("[EXCIPC] Forward message to controller"); m_controller.processMessageFromExecutor(msg); } if (msg.getId() != ExecutorMessages::MSG_NOTIF_EXEC_CLOSE) { - DEBUG("[EXCIPC] Forward message to monitoring clients"); + //DEBUG("[EXCIPC] Forward message to monitoring clients"); notifyMessage(msg); } - DEBUG("[EXCIPC] Message processed"); + //DEBUG("[EXCIPC] Message processed"); TICK_OUT; } @@ -163,21 +163,21 @@ SPELLipcMessage SPELLexecutorIPC::processRequest( const SPELLipcMessage& msg ) { TICK_IN; - DEBUG("[EXCIPC] Received request from executor: " + msg.dataStr()); + //DEBUG("[EXCIPC] Received request from executor: " + msg.dataStr()); SPELLipcMessage resp = VOID_MESSAGE; - DEBUG("[EXCIPC] Forward request to controller"); + //DEBUG("[EXCIPC] Forward request to controller"); resp = m_controller.processRequestFromExecutor(msg); // Certain requests are to be sent to controlling clients only if ( shouldForwardToMonitoring(msg) ) { - DEBUG("[EXCIPC] Forward to monitoring clients"); + //DEBUG("[EXCIPC] Forward to monitoring clients"); // Notify request notifyRequest(msg); } - DEBUG("[EXCIPC] Request processed"); + //DEBUG("[EXCIPC] Request processed"); TICK_OUT; return resp; } @@ -205,6 +205,10 @@ bool SPELLexecutorIPC::shouldForwardToMonitoring( const SPELLipcMessage& msg ) { return false; } + else if ( requestId == ContextMessages::REQ_SERVICE_INFO ) + { + return false; + } else if ( requestId == ContextMessages::REQ_DEL_SHARED_DATA ) { return false; @@ -257,9 +261,9 @@ void SPELLexecutorIPC::notifyMessage( const SPELLipcMessage& msg ) { if (m_connected) { + SPELLmonitor m(m_notifyLock); for( NotifierMap::iterator it = m_notifiers.begin(); it != m_notifiers.end(); it++) { - SPELLmonitor m(m_notifyLock); if (it->second!=NULL) it->second->processMessageFromExecutor(msg); } } @@ -272,9 +276,9 @@ void SPELLexecutorIPC::notifyRequest( const SPELLipcMessage& msg ) { if (m_connected) { + SPELLmonitor m(m_notifyLock); for( NotifierMap::iterator it = m_notifiers.begin(); it != m_notifiers.end(); it++) { - SPELLmonitor m(m_notifyLock); if (it->second!=NULL) it->second->processRequestFromExecutor(msg); } } @@ -288,7 +292,7 @@ void SPELLexecutorIPC::registerExecutorNotifier( std::string id, SPELLexecutorLi SPELLmonitor m(m_notifyLock); LOG_INFO("[EXCIPC] #### Register notifier listener: " + id); NotifierMap::iterator it = m_notifiers.find(id); - if (it == m_notifiers.end()) + if (it == m_notifiers.end() || it->second != notifier) { m_notifiers[id] = notifier; } @@ -304,6 +308,8 @@ void SPELLexecutorIPC::deregisterExecutorNotifier( std::string id ) NotifierMap::iterator it = m_notifiers.find(id); if (it != m_notifiers.end()) { - m_notifiers.erase(it); + // Don't invalidate iterators by just setting the entry to NULL + //m_notifiers.erase(it); + m_notifiers[id] = NULL; } } diff --git a/lib/SPELL_CTX/src/SPELLexecutorManager.C b/lib/SPELL_CTX/src/SPELLexecutorManager.C index a8a194b..5e10bf3 100644 --- a/lib/SPELL_CTX/src/SPELLexecutorManager.C +++ b/lib/SPELL_CTX/src/SPELLexecutorManager.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -40,6 +40,7 @@ #include "SPELL_IPC/SPELLipc_Context.H" #include "SPELL_IPC/SPELLipc_Executor.H" #include "SPELL_WRP/SPELLconstants.H" +#include "SPELL_CTX/SPELLserviceManager.H" // System includes --------------------------------------------------------- @@ -79,7 +80,7 @@ SPELLexecutorManager& SPELLexecutorManager::instance() void SPELLexecutorManager::setup( const std::string& ctxName ) { m_contextName = ctxName; - m_persisTable = new SPELLpersistencyTable(ctxName); + m_persisTable = new SPELLpersistencyTable(ctxName + "_executors"); if (m_persisTable->load()) { reconnectExecutors(); @@ -199,6 +200,8 @@ void SPELLexecutorManager::callback_executorReconnected( const std::string& inst SPELLexecutor* exec = it->second; addInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() ); addExecutorModel( exec ); + SPELLprocessManager::instance().attachProcess( exec->getModel().getInstanceId(), exec->getModel().getPID() ); + m_pendingLogin.erase(it); SPELLexecutorOperation op; @@ -318,7 +321,13 @@ void SPELLexecutorManager::deleteExecutorFiles( const SPELLexecutorStartupParams //============================================================================= void SPELLexecutorManager::addExecutorModel( SPELLexecutor* exec ) { - m_executors.insert( std::make_pair( exec->getModel().getInstanceId(), exec )); + const std::string id = exec->getModel().getInstanceId(); + if (m_executors.count(id) > 0) + { + delete m_executors[id]; + m_executors.erase(id); + } + m_executors.insert( std::make_pair(id, exec )); DEBUG("[EMGR] Added executor: '" + exec->getModel().getInstanceId() + "'"); m_persisTable->registerExecutor(exec->getModel().getInstanceId(), exec->getModel().getTimeId(), @@ -337,13 +346,17 @@ void SPELLexecutorManager::removeExecutorModel( const std::string& instanceId ) { DEBUG("[EMGR] Removing executor model: '" + instanceId + "'"); m_persisTable->deregisterExecutor(it->second->getModel().getInstanceId()); + m_lock.unlock(); delete it->second; + m_lock.lock(); + m_executors.erase(it); DEBUG("[EMGR] Removed executor: '" + instanceId + "'"); } else { - LOG_ERROR("[EMGR]: No executor to remove: '" + instanceId + "'"); + SPELLserviceManager::instance().removeServiceModel(instanceId); + //LOG_ERROR("[EMGR]: No executor to remove: '" + instanceId + "'"); } } @@ -353,6 +366,15 @@ void SPELLexecutorManager::removeExecutorModel( const std::string& instanceId ) std::string SPELLexecutorManager::getInstanceId( const std::string& procId ) { SPELLmonitor m(m_lock); + + // We never remove instance numbers but we can live with it - memory consumption + // is not big and do not need to be concerned with race conditions between add and get + // due to simultaneous requests from *different* clients (e.g .GUI and Parent Exec). + + // Nevertheless attempt to clean now, protected by the lock, before getting an instance id. + // Just clean if no executors running. + if (m_executors.size()==0) m_instances.clear(); + std::string instanceId = ""; InstanceMap::iterator it = m_instances.find(procId); if ( it == m_instances.end() ) @@ -363,9 +385,10 @@ std::string SPELLexecutorManager::getInstanceId( const std::string& procId ) { int instanceNum = 0; while(hasInstanceNumber(procId, instanceNum)) instanceNum++; + addInstanceNumber(procId, instanceNum); instanceId = procId + "#" + ISTR(instanceNum); } - DEBUG("[EMGR] Found instance id: '" + instanceId + "'"); + LOG_INFO("Assigned instance id: '" + instanceId + "'"); return instanceId; } @@ -401,43 +424,18 @@ bool SPELLexecutorManager::hasInstanceNumber( const std::string& procId, int ins return false; } -//============================================================================= -// METHOD: SPELLexecutorManager::removeInstanceNumber() -//============================================================================= -void SPELLexecutorManager::removeInstanceNumber( const std::string& procId, int instanceNum ) -{ - InstanceMap::iterator it = m_instances.find(procId); - if (it != m_instances.end()) - { - InstanceList::iterator toRemove = it->second.end(); - InstanceList::iterator lit; - for( lit = it->second.begin(); lit != it->second.end(); lit++ ) - { - if (*lit == instanceNum) - { - toRemove = lit; - break; - } - } - if (toRemove != it->second.end()) - { - it->second.erase(toRemove); - } - } -} - //============================================================================= // METHOD: SPELLexecutorManager::closeExecutor() //============================================================================= void SPELLexecutorManager::closeExecutor( const std::string& instanceId ) { SPELLmonitor m(m_lock); + try { // Will raise exception if not found SPELLexecutor* exec = getExecutor(instanceId); exec->close(); - removeInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() ); removeExecutorModel( exec->getModel().getInstanceId() ); LOG_INFO("Executor successfully closed: " + instanceId); } @@ -466,7 +464,6 @@ void SPELLexecutorManager::killExecutor( const std::string& instanceId ) // Will raise exception if not found SPELLexecutor* exec = getExecutor(instanceId); exec->kill(); - removeInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() ); removeExecutorModel( exec->getModel().getInstanceId() ); } catch(SPELLcoreException& ex) @@ -499,7 +496,6 @@ void SPELLexecutorManager::clearModels() try { SPELLexecutor* exec = getExecutor(*it); - removeInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() ); removeExecutorModel( exec->getModel().getInstanceId() ); } catch(SPELLcoreException& ex) @@ -509,6 +505,9 @@ void SPELLexecutorManager::clearModels() } } m_toClear.clear(); + if (m_executors.empty()){ + m_instances.clear(); + } } } @@ -520,6 +519,8 @@ SPELLexecutor* SPELLexecutorManager::getExecutor( const std::string& instanceId //DEBUG("[EMGR] Search for executor: '" + instanceId + "'"); ExecutorMap::iterator it = m_executors.find(instanceId); if (it != m_executors.end()) return it->second; + const std::string id = noInstanceId(instanceId); + return SPELLserviceManager::instance().getService(id); THROW_EXCEPTION("Cannot get executor", "No such id: " + instanceId, SPELL_ERROR_EXECUTION ); return NULL; } @@ -591,10 +592,11 @@ void SPELLexecutorManager::buildExecutorInfo( const std::string& procId, SPELLip { LOG_INFO("Building executor information for " + procId ); - std::string procName = SPELLprocedureManager::instance().getProcName(procId); try { + std::string procName = SPELLprocedureManager::instance().getProcName(procId); + // Will raise exception if not found SPELLexecutor* exec = getExecutor(procId); @@ -675,23 +677,6 @@ void SPELLexecutorManager::buildExecutorInfo( const std::string& procId, SPELLip } catch(SPELLcoreException& ex) { - LOG_ERROR("No executor found to complete information"); - msg.set( MessageField::FIELD_PROC_ID, procId ); - msg.set( MessageField::FIELD_GROUP_ID, procId ); - msg.set( MessageField::FIELD_ORIGIN_ID, "???" ); - msg.set( MessageField::FIELD_PARENT_PROC, " " ); - msg.set( MessageField::FIELD_PARENT_PROC_LINE, " " ); - msg.set( MessageField::FIELD_PROC_NAME, procName ); - msg.set( MessageField::FIELD_ASRUN_NAME, " " ); - msg.set( MessageField::FIELD_EXEC_STATUS, SPELLdataHelper::executorStatusToString(STATUS_UNINIT) ); - msg.set( MessageField::FIELD_CONDITION, " " ); - msg.set( MessageField::FIELD_GUI_LIST, " " ); - msg.set( MessageField::FIELD_GUI_CONTROL, " " ); - msg.set( MessageField::FIELD_GUI_CONTROL_HOST, " " ); - msg.set( MessageField::FIELD_OPEN_MODE, " " ); - msg.set( MessageField::FIELD_STAGE_ID, " " ); - msg.set( MessageField::FIELD_STAGE_TL, " " ); - msg.set( MessageField::FIELD_CSP, " " ); - msg.set( MessageField::FIELD_CODE_NAME, " " ); + SPELLserviceManager::instance().buildServiceInfo( procId, msg ); } } diff --git a/lib/SPELL_CTX/src/SPELLexecutorModel.C b/lib/SPELL_CTX/src/SPELLexecutorModel.C index d0ec261..853a115 100644 --- a/lib/SPELL_CTX/src/SPELLexecutorModel.C +++ b/lib/SPELL_CTX/src/SPELLexecutorModel.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CTX/src/SPELLexecutorOperation.C b/lib/SPELL_CTX/src/SPELLexecutorOperation.C index 8e9698e..9fab2aa 100644 --- a/lib/SPELL_CTX/src/SPELLexecutorOperation.C +++ b/lib/SPELL_CTX/src/SPELLexecutorOperation.C @@ -5,7 +5,7 @@ // DESCRIPTION: Executor operation notifications // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_CTX/src/SPELLlistenerIPC.C b/lib/SPELL_CTX/src/SPELLlistenerIPC.C index 4dbc25b..ffb967c 100644 --- a/lib/SPELL_CTX/src/SPELLlistenerIPC.C +++ b/lib/SPELL_CTX/src/SPELLlistenerIPC.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the listener IPC interface // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -48,6 +48,7 @@ //============================================================================= SPELLlistenerIPC::SPELLlistenerIPC() { + m_ipc = NULL; } //============================================================================= diff --git a/lib/SPELL_CTX/src/SPELLpersistencyTable.C b/lib/SPELL_CTX/src/SPELLpersistencyTable.C index 63abf94..5e9c7fe 100644 --- a/lib/SPELL_CTX/src/SPELLpersistencyTable.C +++ b/lib/SPELL_CTX/src/SPELLpersistencyTable.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor persistency table // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -92,7 +92,7 @@ bool SPELLpersistencyTable::load() pers.timeId = tokens[1]; pers.parentId = parentId; pers.pid = STRI(tokens[4]); - m_data.insert( std::make_pair(tokens[0], pers) ); + m_data[tokens[0]] = pers; } else { @@ -145,7 +145,7 @@ void SPELLpersistencyTable::registerExecutor( const std::string& instanceId, con pers.timeId = timeId; pers.parentId = parentId; pers.pid = pid; - m_data.insert( std::make_pair(instanceId, pers) ); + m_data[instanceId] = pers; dumpToFile(); } } diff --git a/lib/SPELL_CTX/src/SPELLservice.C b/lib/SPELL_CTX/src/SPELLservice.C new file mode 100644 index 0000000..10f0edb --- /dev/null +++ b/lib/SPELL_CTX/src/SPELLservice.C @@ -0,0 +1,207 @@ +// ################################################################################ +// FILE : SPELLexecutor.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the executor manager +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// Local includes ---------------------------------------------------------- +#include "SPELL_CTX/SPELLservice.H" +#include "SPELL_CTX/SPELLserviceManager.H" +#include "SPELL_CTX/SPELLdataHelper.H" +#include "SPELL_CTX/SPELLcontext.H" +#include "SPELL_PRD/SPELLprocedureManager.H" +// Project includes -------------------------------------------------------- +#include "SPELL_WRP/SPELLconstants.H" +#include "SPELL_CFG/SPELLconfiguration.H" +#include "SPELL_SYN/SPELLmonitor.H" +#include "SPELL_SYN/SPELLthread.H" +#include "SPELL_IPC/SPELLipcHelper.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLutils.H" +#include "SPELL_UTIL/SPELLerror.H" +#include "SPELL_UTIL/SPELLtime.H" +#include "SPELL_IPC/SPELLipc_Executor.H" +#include "SPELL_IPC/SPELLipc_Context.H" +// System includes --------------------------------------------------------- + +// DEFINES ///////////////////////////////////////////////////////////////// + +#define DEFAULT_START_TIMEOUT 20 +#define DEFAULT_LOGIN_TIMEOUT 60 + + +//============================================================================= +// CONSTRUCTOR: SPELLservice::SPELLservice() +//============================================================================= +SPELLservice::SPELLservice( const SPELLserviceStartupParams& config ) +: SPELLexecutor(config,NULL) +{ + +} + +//============================================================================= +// DESTRUCTOR: SPELLservice::~SPELLservice() +//============================================================================= +SPELLservice::~SPELLservice() +{ + +} + +//============================================================================= +// METHOD: SPELLservice::start() +//============================================================================= +void SPELLservice::start() +{ + LOG_INFO("Starting service " + m_model.getInstanceId()); + m_ipc.setup(); + m_model.setIpcPort( m_ipc.getPort() ); + m_executorLoggedInEvent.clear(); + + if (!m_reconnecting) + { + m_processStartedEvent.clear(); + std::string command; + SPELLpyService& service = SPELLprocedureManager::instance().getService(m_model.getProcId()); + int startTimeout = -1; + int loginTimeout = -1; + if (service.useCommandOverride()) + { + std::string startTimeoutStr = SPELLconfiguration::instance().getContextParameter(SPELLcontextConfig::ExecutorStartTimeout); + std::string loginTimeoutStr = SPELLconfiguration::instance().getContextParameter(SPELLcontextConfig::ExecutorLoginTimeout); + if (startTimeoutStr != "") + { + startTimeout = STRI(startTimeoutStr); + } + if (loginTimeoutStr != "") + { + loginTimeout = STRI(loginTimeoutStr); + } + if (startTimeout == -1) + startTimeout = DEFAULT_START_TIMEOUT; + if (loginTimeout == -1) + loginTimeout = DEFAULT_LOGIN_TIMEOUT; + + LOG_INFO("Using start timeout: " + ISTR(startTimeout) + " seconds"); + LOG_INFO("Using login timeout: " + ISTR(loginTimeout) + " seconds"); + + std::string config = m_model.getConfigFile(); + std::string contextName = m_model.getContextName(); + int ipcPort = m_ipc.getPort(); + std::string instanceId = m_model.getInstanceId(); + std::string warmstartFile = ""; + if (m_model.getWsFilename() != "") + { + warmstartFile = m_model.getWsFilename(); + } + command = service.getCommandOverride(startTimeout,loginTimeout,config,contextName,ipcPort,instanceId,warmstartFile); + } + else + { + command = SPELLconfiguration::instance().getContextParameter( SPELLcontextConfig::ServiceProgram ); + + if (command == "") + { + THROW_EXCEPTION("Cannot launch service", "No service command defined in configuration", SPELL_ERROR_CONFIG); + } + + + std::string startTimeoutStr = SPELLconfiguration::instance().getContextParameter( SPELLcontextConfig::ExecutorStartTimeout ); + std::string loginTimeoutStr = SPELLconfiguration::instance().getContextParameter( SPELLcontextConfig::ExecutorLoginTimeout ); + if (startTimeoutStr != "") + { + startTimeout = STRI(startTimeoutStr); + } + if (loginTimeoutStr != "") + { + loginTimeout = STRI(loginTimeoutStr); + } + if (startTimeout == -1) startTimeout = DEFAULT_START_TIMEOUT; + if (loginTimeout == -1) loginTimeout = DEFAULT_LOGIN_TIMEOUT; + + LOG_INFO("Using start timeout: " + ISTR(startTimeout) + " seconds"); + LOG_INFO("Using login timeout: " + ISTR(loginTimeout) + " seconds"); + + command += " -c " + m_model.getConfigFile(); + command += " -n " + m_model.getContextName(); + command += " -s " + ISTR(m_ipc.getPort()); + command += " -p " + m_model.getInstanceId(); // Parent id + command += " -w "; + if (m_model.getWsFilename() != "") + { + command += " -r " + m_model.getWsFilename(); + } + } + if (SPELLprocessManager::instance().checkProcessExist(m_model.getInstanceId() )) + SPELLprocessManager::instance().killProcess( m_model.getInstanceId() ); + SPELLprocessManager::instance().clearProcess( m_model.getInstanceId() ); + SPELLprocessManager::instance().startProcess( m_model.getInstanceId(), command ); + + DEBUG("Waiting executor process to begin"); + bool timedOut = m_processStartedEvent.wait( startTimeout * 1000 ); // milliseconds + if (timedOut) + { + THROW_EXCEPTION("Cannot launch executor", "Executor process did not begin in time", SPELL_ERROR_PROCESS); + } + DEBUG("Start event received"); + + m_processStatus = SPELLprocessManager::instance().getProcessStatus( m_model.getInstanceId() ); + if (m_processStatus == PSTATUS_RUNNING) + { + if (!m_loggedIn) + { + DEBUG("Executor process started, waiting for login"); + bool timeout = m_executorLoggedInEvent.wait( loginTimeout * 1000 ); // milliseconds + if (timeout) + { + THROW_EXCEPTION("Cannot launch executor", "Executor did not login in time", SPELL_ERROR_PROCESS); + } + } + DEBUG("Executor process logged in"); + m_model.setPID( SPELLprocessManager::instance().getProcessId( m_model.getInstanceId() )); + LOG_INFO("Executor started: " + m_model.getInstanceId() + " with pid " + ISTR(m_model.getPID())); + } + else if (m_processStatus == PSTATUS_FINISHED ) + { + THROW_EXCEPTION("Cannot launch executor", "Executor process finished too quickly", SPELL_ERROR_PROCESS); + } + else if (m_processStatus == PSTATUS_FAILED ) + { + THROW_EXCEPTION("Cannot launch executor", "Executor process failed to start", SPELL_ERROR_PROCESS); + } + else if (m_processStatus == PSTATUS_KILLED ) + { + THROW_EXCEPTION("Cannot launch executor", "Executor process crashed or was killed", SPELL_ERROR_PROCESS); + } + else + { + THROW_EXCEPTION("Cannot launch executor", "Executor process in unexpected state: " + SPELLprocessUtils::processStatusToString(m_processStatus), SPELL_ERROR_PROCESS); + } + } + else + { + m_loginMonitor = new LoginMonitor(*this); + m_loginMonitor->start(); + } +} + diff --git a/lib/SPELL_CTX/src/SPELLserviceManager.C b/lib/SPELL_CTX/src/SPELLserviceManager.C new file mode 100644 index 0000000..fbee805 --- /dev/null +++ b/lib/SPELL_CTX/src/SPELLserviceManager.C @@ -0,0 +1,676 @@ +// ################################################################################ +// FILE : SPELLserviceManager.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the executor manager +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// Local includes ---------------------------------------------------------- +#include "SPELL_CTX/SPELLserviceManager.H" +#include "SPELL_CTX/SPELLservice.H" +#include "SPELL_CTX/SPELLclientManager.H" +#include "SPELL_CTX/SPELLdataHelper.H" +#include "SPELL_CTX/SPELLcontext.H" +// Project includes -------------------------------------------------------- +#include "SPELL_PRD/SPELLprocedureManager.H" +#include "SPELL_SYN/SPELLmonitor.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLutils.H" +#include "SPELL_UTIL/SPELLerror.H" +#include "SPELL_CFG/SPELLconfiguration.H" +#include "SPELL_IPC/SPELLipc_Context.H" +#include "SPELL_IPC/SPELLipc_Executor.H" +#include "SPELL_WRP/SPELLconstants.H" +// System includes --------------------------------------------------------- + + +// DEFINES ///////////////////////////////////////////////////////////////// +SPELLserviceManager* SPELLserviceManager::s_instance = NULL; + +//============================================================================= +// CONSTRUCTOR: SPELLexecutorManager::SPELLexecutorManager() +//============================================================================= +SPELLserviceManager::SPELLserviceManager() +{ + m_persisTable = NULL; +} + +//============================================================================= +// DESTRUCTOR: SPELLexecutorManager::~SPELLexecutorManager() +//============================================================================= +SPELLserviceManager::~SPELLserviceManager() +{ +} + +//============================================================================= +// STATIC: SPELLexecutorManager::instance() +//============================================================================= +SPELLserviceManager& SPELLserviceManager::instance() +{ + if (s_instance == NULL) + { + s_instance = new SPELLserviceManager(); + } + return *s_instance; +} + +//============================================================================= +// METHOD: SPELLexecutorManager::setup() +//============================================================================= +void SPELLserviceManager::setup( const std::string& ctxName ) +{ + m_contextName = ctxName; + m_persisTable = new SPELLpersistencyTable(ctxName + "_services"); + if (m_persisTable->load()) + { + reconnectServices(); + } +} + +//============================================================================= +// METHOD: SPELLexecutorManager::setup() +//============================================================================= +void SPELLserviceManager::cleanup() +{ + if (m_persisTable) delete m_persisTable; + for( ServiceMap::iterator it = m_pendingLogin.begin(); it != m_pendingLogin.end(); it++ ) + { + delete it->second; + } + m_pendingLogin.clear(); +} + +//============================================================================= +// METHOD: SPELLexecutorManager::startExecutor() +//============================================================================= +void SPELLserviceManager::startService( SPELLserviceStartupParams& config) +{ + DEBUG( "[SMGR] Start service TRY-IN"); + + SPELLmonitor m(m_lock); + DEBUG( "[SMGR] Start executor IN"); + config.setContextName(m_contextName); + config.setConfigFile(SPELLconfiguration::instance().getFile()); + + // Create and start the executor with the given configuration + + // If the open mode does not include VISIBLE, do not pass the controlling client + // This way we force the GUI to attach to a proc when it is started in non-visible + SPELLservice* exec = NULL; + + DEBUG( "[SMGR] Start executor in background"); + exec = new SPELLservice(config); + + try + { + LOG_INFO("Starting service " + exec->getModel().getInstanceId() ); + exec->start(); + + addInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() ); + addServiceModel( exec ); + + LOG_INFO("Service ready"); + } + catch(SPELLcoreException& ex) + { + // Delete recovery files just created for the new executor file + deleteServiceFiles(config); + DEBUG( "[SMGR] Start service OUT"); + THROW_EXCEPTION("Failed to start service", ex.what(), SPELL_ERROR_PROCESS); + } + DEBUG( "[SMGR] Start executor OUT"); +} + +//============================================================================= +// METHOD: SPELLexecutorManager::reconnectExecutors() +//============================================================================= +void SPELLserviceManager::reconnectServices() +{ + DEBUG( "[SMGR] Reconnecting orphan services"); + SPELLmonitor m(m_lock); + std::vector ids = m_persisTable->getRegisteredExecutors(); + m_pendingLogin.clear(); + for(std::vector::iterator it = ids.begin(); it != ids.end(); it++) + { + std::string instanceId = *it; + SPELLexecutorPersistency pers = m_persisTable->getExecutorPersistency(instanceId); + + if (getpgid(pers.pid) < 0) + { + DEBUG( "[SMGR] PID " + ISTR(pers.pid) + " for service "+instanceId+" not found"); + continue; + } + + SPELLserviceStartupParams config( instanceId, pers.timeId, true ); + config.setParentInstanceId(pers.parentId); + config.setIpcPort(pers.ipcPort); + config.setPID(pers.pid); + + SPELLservice* exec = new SPELLservice(config); + try + { + LOG_WARN("Reconnecting service " + instanceId + " listening on port " + ISTR(pers.ipcPort) ); + exec->start(); + m_services.insert( std::make_pair( exec->getModel().getInstanceId(), exec )); + m_pendingLogin.insert( std::make_pair( instanceId, exec ) ); + } + catch(SPELLcoreException& ex) + { + deleteServiceFiles(config); + } + } + DEBUG( "[SMGR] Reconnect services done"); +} + +//============================================================================= +// METHOD: SPELLexecutorManager::callback_executorReconnected() +//============================================================================= +void SPELLserviceManager::callback_serviceReconnected( const std::string& instanceId ) +{ + LOG_WARN("#######################################"); + LOG_WARN("Service " + instanceId + " reconnected"); + LOG_WARN("#######################################"); + SPELLmonitor m(m_lock); + ServiceMap::iterator it = m_pendingLogin.find(instanceId); + if (it != m_pendingLogin.end()) + { + SPELLservice* exec = it->second; + addInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() ); + addServiceModel( exec ); + m_pendingLogin.erase(it); + + SPELLexecutorOperation op; + op.instanceId = exec->getModel().getInstanceId(); + op.parentId = exec->getModel().getParentInstanceId(); + op.groupId = exec->getModel().getGroupId(); + op.originId = exec->getModel().getOriginId(); + op.status = exec->getModel().getStatus(); + op.type = SPELLexecutorOperation::EXEC_OP_OPEN; + + SPELLcontext::instance().notifyExecutorOperation( op ); + } +} + +//============================================================================= +// METHOD: SPELLexecutorManager::callback_executorNotReconnected() +//============================================================================= +void SPELLserviceManager::callback_serviceNotReconnected( const std::string& instanceId ) +{ + LOG_ERROR("#######################################"); + LOG_ERROR("Service " + instanceId + " failed to reconnect"); + LOG_ERROR("#######################################"); + SPELLmonitor m(m_lock); + ServiceMap::iterator it = m_pendingLogin.find(instanceId); + if (it != m_pendingLogin.end()) + { + m_persisTable->deregisterExecutor(it->second->getModel().getInstanceId()); + delete it->second; + m_pendingLogin.erase(it); + } +} + +////============================================================================= +//// METHOD: SPELLexecutorManager::recoverExecutor() +////============================================================================= +//void SPELLserviceManager::recoverExecutor( SPELLexecutorStartupParams& config, SPELLclient* controllingClient ) +//{ +// //TODO check maximum number of executors +// SPELLmonitor m(m_lock); +// config.setContextName(m_contextName); +// config.setConfigFile(SPELLconfiguration::instance().getFile()); +// +// // Create and start the executor with the given configuration +// +// // If the open mode does not include VISIBLE, do not pass the controlling client +// // This way we force the GUI to attach to a proc when it is started in non-visible +// SPELLexecutor* exec = new SPELLexecutor(config, controllingClient); +// try +// { +// LOG_INFO("Recovering executor " + exec->getModel().getInstanceId() ); +// exec->start(); +// +// addInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() ); +// addExecutorModel( exec ); +// +// LOG_INFO("Executor ready"); +// } +// catch(SPELLcoreException& ex) +// { +// // Delete recovery files just created for the new executor file +// deleteExecutorFiles(config); +// THROW_EXCEPTION("Failed to recover executor", ex.what(), SPELL_ERROR_PROCESS); +// } +//} + +//============================================================================= +// METHOD: SPELLexecutorManager::deleteExecutorFiles() +//============================================================================= +void SPELLserviceManager::deleteServiceFiles( const SPELLserviceStartupParams& config ) +{ + SPELLcontextConfig& ctxConfig = SPELLconfiguration::instance().getContext(m_contextName); + + std::string fileName = config.getTimeId() + "_Service_" + config.getInstanceId(); + + LOG_INFO("Deleting service files: " + fileName ); + + // Delete warmstart files + std::string wsDataDir = SPELLutils::getSPELL_DATA() + PATH_SEPARATOR + ctxConfig.getLocationPath("ws"); + std::list files = SPELLutils::getFilesInDir(wsDataDir); + + for(std::list::const_iterator it = files.begin(); it != files.end(); it++) + { + std::string completeFilename = *it; + if (completeFilename.find(fileName) != std::string::npos) + { + std::string path = wsDataDir + PATH_SEPARATOR + completeFilename; + if (SPELLutils::pathExists(path)) + { + SPELLutils::deleteFile(path); + LOG_INFO("Delete " + path ); + } + } + } + + // Delete Asrun files + std::string arDataDir = SPELLutils::getSPELL_DATA() + PATH_SEPARATOR + ctxConfig.getLocationPath("ar"); + + files = SPELLutils::getFilesInDir(arDataDir); + + for(std::list::const_iterator it = files.begin(); it != files.end(); it++) + { + std::string completeFilename = *it; + if (completeFilename.find(fileName) != std::string::npos) + { + std::string path = arDataDir + PATH_SEPARATOR + completeFilename; + if (SPELLutils::pathExists(path)) + { + SPELLutils::deleteFile(path); + LOG_INFO("Delete " + path ); + } + } + } +} + +//============================================================================= +// METHOD: SPELLexecutorManager::addExecutorModel() +//============================================================================= +void SPELLserviceManager::addServiceModel( SPELLservice* exec ) +{ + const std::string id = exec->getModel().getInstanceId(); + if (m_services.count(id) > 0) + { + delete m_services[id]; + m_services.erase(id); + } + m_services.insert( std::make_pair( exec->getModel().getInstanceId(), exec )); + DEBUG("[SMGR] Added executor: '" + exec->getModel().getInstanceId() + "'"); + m_persisTable->registerExecutor(exec->getModel().getInstanceId(), + exec->getModel().getTimeId(), + exec->getModel().getParentInstanceId(), + exec->getModel().getIpcPort(), + exec->getModel().getPID() ); +} + +//============================================================================= +// METHOD: SPELLexecutorManager::removeExecutorModel() +//============================================================================= +void SPELLserviceManager::removeServiceModel( const std::string& instanceId ) +{ + ServiceMap::iterator it = m_services.find(instanceId); + if (it != m_services.end()) + { + DEBUG("[SMGR] Removing service model: '" + instanceId + "'"); + m_persisTable->deregisterExecutor(it->second->getModel().getInstanceId()); + delete it->second; + m_services.erase(it); + DEBUG("[SMGR] Removed service: '" + instanceId + "'"); + } + else + { + LOG_ERROR("[SMGR]: No service to remove: '" + instanceId + "'"); + } +} + +//============================================================================= +// METHOD: SPELLexecutorManager::getInstanceId() +//============================================================================= +std::string SPELLserviceManager::getInstanceId( const std::string& procId ) +{ + SPELLmonitor m(m_lock); + + // We never remove instance numbers but we can live with it - memory consumption + // is not big and do not need to be concerned with race conditions between add and get + // due to simultaneous requests from *different* clients (e.g .GUI and Parent Exec). + + // Nevertheless attempt to clean now, protected by the lock, before getting an instance id. + // Just clean if no executors running. + if (m_services.size()==0) m_instances.clear(); + + std::string instanceId = ""; + InstanceMap::iterator it = m_instances.find(procId); + if ( it == m_instances.end() ) + { + instanceId = procId; + } + else + { + int instanceNum = 0; + while(hasInstanceNumber(procId, instanceNum)) instanceNum++; + addInstanceNumber(procId, instanceNum); + instanceId = procId; + } + LOG_INFO("Assigned instance id: '" + instanceId + "'"); + return instanceId; +} + +//============================================================================= +// METHOD: SPELLexecutorManager::addInstanceNumber() +//============================================================================= +void SPELLserviceManager::addInstanceNumber( const std::string& procId, int instanceNum ) +{ + InstanceMap::iterator it = m_instances.find(procId); + if (it == m_instances.end()) + { + InstanceList list; + list.push_back(instanceNum); + m_instances.insert( std::make_pair( procId, list ) ); + } + else + { + it->second.push_back(instanceNum); + } +} + +//============================================================================= +// METHOD: SPELLexecutorManager::hasInstanceNumber() +//============================================================================= +bool SPELLserviceManager::hasInstanceNumber( const std::string& procId, int instanceNum ) +{ + InstanceMap::iterator it = m_instances.find(procId); + InstanceList::iterator lit; + for( lit = it->second.begin(); lit != it->second.end(); lit++ ) + { + if (*lit == instanceNum) return true; + } + return false; +} + +//============================================================================= +// METHOD: SPELLexecutorManager::closeExecutor() +//============================================================================= +void SPELLserviceManager::closeService( const std::string& instanceId ) +{ + SPELLmonitor m(m_lock); + try + { + // Will raise exception if not found + SPELLservice* exec = getService(instanceId); + exec->close(); + removeServiceModel( exec->getModel().getInstanceId() ); + LOG_INFO("Service successfully closed: " + instanceId); + } + catch(SPELLcoreException& ex) + { + LOG_ERROR("Unable to find service '" + instanceId + "', cannot close"); + } +} + +//============================================================================= +// METHOD: SPELLexecutorManager::executorLost() +//============================================================================= +void SPELLserviceManager::serviceLost( SPELLservice& service ) +{ + LOG_WARN( "[SMGR] Service lost: " + service.getModel().getInstanceId()); + clearService(service.getModel().getInstanceId()); +} + +//============================================================================= +// METHOD: SPELLexecutorManager::killExecutor() +//============================================================================= +void SPELLserviceManager::killService( const std::string& instanceId ) +{ + try + { + SPELLmonitor m(m_lock); + // Will raise exception if not found + SPELLservice* exec = getService(instanceId); + exec->kill(); + removeServiceModel( exec->getModel().getInstanceId() ); + } + catch(SPELLcoreException& ex) + { + THROW_EXCEPTION("Failed to kill Service '" + instanceId + "' ", ex.what(), SPELL_ERROR_PROCESS); + } +} + +//============================================================================= +// METHOD: SPELLexecutorManager::clearExecutor() +//============================================================================= +void SPELLserviceManager::clearService( const std::string& instanceId ) +{ + SPELLmonitor m(m_lock); + m_toClear.push_back(instanceId); +} + +//============================================================================= +// METHOD: SPELLexecutorManager::clearModels +//============================================================================= +void SPELLserviceManager::clearModels() +{ + if (m_toClear.size()>0) + { + IdentifierList::iterator it; + for( it = m_toClear.begin(); it != m_toClear.end(); it++) + { + ServiceMap::iterator eit = m_services.find(*it); + if (eit != m_services.end()) + { + try + { + SPELLservice* exec = getService(*it); + removeServiceModel( exec->getModel().getInstanceId() ); + } + catch(SPELLcoreException& ex) + { + LOG_ERROR("Failed to remove executor model"); + }; + } + } + m_toClear.clear(); + if (m_services.empty()){ + m_instances.clear(); + } + } +} + +//============================================================================= +// METHOD: SPELLexecutorManager::getExecutor() +//============================================================================= +SPELLservice* SPELLserviceManager::getService( const std::string& instanceId ) +{ + DEBUG("[SMGR] Search for service: '" + instanceId + "'"); + int idx = instanceId.find("#"); + std::string id = instanceId; + if (idx >= 0) + id = id.substr(0,idx); + ServiceMap::iterator it = m_services.find(id); + if (it != m_services.end()) return it->second; + THROW_EXCEPTION("Cannot get service", "No such id: " + instanceId, SPELL_ERROR_EXECUTION ); +} + +//============================================================================= +// METHOD: SPELLexecutorManager::killAll() +//============================================================================= +void SPELLserviceManager::killAll() +{ + DEBUG( "[SMGR] Kill all Services"); + ServiceList list = getServiceList(); + ServiceList::iterator lit; + for( lit = list.begin(); lit != list.end(); lit++) + { + try + { + killService(*lit); + } + catch(SPELLcoreException& ex) + { + LOG_ERROR("Could not kill service: " + ex.what()); + } + } + DEBUG( "[SMGR] Kill all services done"); +} + +//============================================================================= +// METHOD: SPELLexecutorManager::getNumActiveExecutors() +//============================================================================= +unsigned int SPELLserviceManager::getNumActiveServices() +{ + DEBUG( "[SMGR] Get number of active services TRY-IN"); + SPELLmonitor m(m_lock); + DEBUG( "[SMGR] Get number of active services IN"); + clearModels(); + ServiceMap::iterator it; + unsigned int numActive = 0; + for( it = m_services.begin(); it != m_services.end(); it++) + { + if (it->second->isActive()) numActive++; + } + DEBUG( "[SMGR] Get number of active services OUT"); + return numActive; +} + +//============================================================================= +// METHOD: SPELLexecutorManager::getExecutorList() +//============================================================================= +SPELLserviceManager::ServiceList SPELLserviceManager::getServiceList() +{ + SPELLmonitor m(m_lock); + clearModels(); + ServiceList ids; + ServiceMap::iterator it; + for( it = m_services.begin(); it != m_services.end(); it++) + { + ids.push_back(it->first); + } + //DEBUG( "[SMGR] Get service list OUT"); + return ids; +} + +//============================================================================= +// METHOD: SPELLexecutorManager::buildExecutorInfo() +//============================================================================= +void SPELLserviceManager::buildServiceInfo( const std::string& serviceId, SPELLipcMessage& msg ) +{ + LOG_INFO("Building service information for " + serviceId ); + + try + { + // Will raise exception if not found + std::string procId; + std::string::size_type idx = serviceId.find("#"); + if (idx != std::string::npos) + procId = serviceId.substr(0,idx); + else + procId = serviceId; + SPELLservice* exec = getService(procId); + SPELLpyService& service = SPELLprocedureManager::instance().getService(procId); + + msg.set( MessageField::FIELD_PROC_ID, procId); + msg.set( MessageField::FIELD_PARENT_PROC, exec->getModel().getParentInstanceId() ); + msg.set( MessageField::FIELD_PARENT_PROC_LINE, ISTR(exec->getModel().getParentCallingLine()) ); + + // The group id of a main (without parent) procedure is the same as proc id. + std::string groupId = exec->getModel().getGroupId(); + if (groupId == "") groupId = procId; + msg.set( MessageField::FIELD_GROUP_ID, groupId ); + // The origin id is optional + msg.set( MessageField::FIELD_ORIGIN_ID, exec->getModel().getOriginId() ); + msg.set( MessageField::FIELD_PROC_NAME, service.getName() + "#0"); + msg.set( MessageField::FIELD_ASRUN_NAME, exec->getModel().getAsRunFilename() ); + msg.set( MessageField::FIELD_LOG_NAME, exec->getModel().getLogFilename() ); + SPELLexecutorStatus st = exec->getStatus(); + msg.set( MessageField::FIELD_EXEC_STATUS, SPELLdataHelper::executorStatusToString(st) ); + msg.set( MessageField::FIELD_CONDITION, exec->getModel().getCondition() ); + msg.set( MessageField::FIELD_STAGE_ID, exec->getModel().getStageId() ); + msg.set( MessageField::FIELD_STAGE_TL, exec->getModel().getStageTitle() ); + msg.set( MessageField::FIELD_CSP, exec->getModel().getStack() ); + msg.set( MessageField::FIELD_CODE_NAME, exec->getModel().getCode() ); + + if (exec->getModel().getUserAction().isSet()) + { + std::string action = exec->getModel().getUserAction().getLabel(); + LOG_INFO("User action: " + action); + msg.set( MessageField::FIELD_ACTION_LABEL, action ); + LOG_INFO("User action enabled: " + BSTR(exec->getModel().getUserAction().isEnabled())); + msg.set( MessageField::FIELD_ACTION_ENABLED, exec->getModel().getUserAction().isEnabled() ? "true" : "false" ); + switch(exec->getModel().getUserAction().getSeverity()) + { + case LanguageConstants::INFORMATION: + msg.set( MessageField::FIELD_ACTION_SEVERITY, MessageValue::DATA_SEVERITY_INFO ); + break; + case LanguageConstants::WARNING: + msg.set( MessageField::FIELD_ACTION_SEVERITY, MessageValue::DATA_SEVERITY_WARN ); + break; + case LanguageConstants::ERROR: + msg.set( MessageField::FIELD_ACTION_SEVERITY, MessageValue::DATA_SEVERITY_ERROR ); + break; + default: + msg.set( MessageField::FIELD_ACTION_SEVERITY, MessageValue::DATA_SEVERITY_INFO ); + break; + } + } + + LOG_INFO("[SMGR] Parent procedure : " + exec->getModel().getParentInstanceId()); + LOG_INFO("[SMGR] Status : " + SPELLdataHelper::executorStatusToString(st)); + LOG_INFO("[SMGR] ASRUN file : " + exec->getModel().getAsRunFilename()); + + + LOG_INFO("[SMGR] Procedure in background"); + msg.set( MessageField::FIELD_GUI_CONTROL, "" ); + msg.set( MessageField::FIELD_GUI_CONTROL_HOST, "" ); + + msg.set( MessageField::FIELD_OPEN_MODE, SPELLdataHelper::openModeToString(exec->getModel().getOpenMode()) ); + LOG_INFO("[SMGR] Open mode : " + SPELLdataHelper::openModeToString(exec->getModel().getOpenMode())); + } + catch(SPELLcoreException& ex) + { + LOG_ERROR("No service found to complete information"); + msg.set( MessageField::FIELD_PROC_ID, serviceId ); + msg.set( MessageField::FIELD_GROUP_ID, serviceId ); + msg.set( MessageField::FIELD_ORIGIN_ID, "???" ); + msg.set( MessageField::FIELD_PARENT_PROC, " " ); + msg.set( MessageField::FIELD_PARENT_PROC_LINE, " " ); + msg.set( MessageField::FIELD_PROC_NAME, "" ); + msg.set( MessageField::FIELD_ASRUN_NAME, " " ); + msg.set( MessageField::FIELD_EXEC_STATUS, SPELLdataHelper::executorStatusToString(STATUS_UNINIT) ); + msg.set( MessageField::FIELD_CONDITION, " " ); + msg.set( MessageField::FIELD_GUI_LIST, " " ); + msg.set( MessageField::FIELD_GUI_CONTROL, " " ); + msg.set( MessageField::FIELD_GUI_CONTROL_HOST, " " ); + msg.set( MessageField::FIELD_OPEN_MODE, " " ); + msg.set( MessageField::FIELD_STAGE_ID, " " ); + msg.set( MessageField::FIELD_STAGE_TL, " " ); + msg.set( MessageField::FIELD_CSP, " " ); + msg.set( MessageField::FIELD_CODE_NAME, " " ); + } +} diff --git a/lib/SPELL_CTX/src/SPELLsharedData.C b/lib/SPELL_CTX/src/SPELLsharedData.C index 7f27809..41567b4 100644 --- a/lib/SPELL_CTX/src/SPELLsharedData.C +++ b/lib/SPELL_CTX/src/SPELLsharedData.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the shared data tables container // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_DTA/Makefile.am b/lib/SPELL_DTA/Makefile.am index 5bc6b10..b831272 100644 --- a/lib/SPELL_DTA/Makefile.am +++ b/lib/SPELL_DTA/Makefile.am @@ -1,41 +1,46 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk +lib_LTLIBRARIES = libSPELL_DTA_v2.la libSPELL_DTA_v3.la -lib_LTLIBRARIES= libSPELL_DTA.la +libSPELL_DTA_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} -libSPELL_DTA_la_CPPFLAGS = ${AM_CPPFLAGS} -DWITH_DEBUG -libSPELL_DTA_la_LDFLAGS = -version-info 1:0:0 +libSPELL_DTA_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -libSPELL_DTA_la_SOURCES = \ - src/SPELLdtaContainerObjectMethods.C \ - src/SPELLdtaVariableObjectMethods.C \ - src/SPELLdtaVariable.C \ - src/SPELLdtaContainer.C \ - src/SPELLdtaModule.C - +libSPELL_DTA_v2_la_SOURCES = src/SPELLdtaContainerObjectMethods.C \ + src/SPELLdtaVariableObjectMethods.C \ + src/SPELLdtaVariable.C \ + src/SPELLdtaContainer.C \ + src/SPELLdtaModule.C + + +libSPELL_DTA_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_DTA_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_DTA_v3_la_SOURCES = src/SPELLdtaContainerObjectMethods.C \ + src/SPELLdtaVariableObjectMethods.C \ + src/SPELLdtaVariable.C \ + src/SPELLdtaContainer.C \ + src/SPELLdtaModule.C + \ No newline at end of file diff --git a/lib/SPELL_DTA/src/SPELLdtaContainer.C b/lib/SPELL_DTA/src/SPELLdtaContainer.C index 35927bc..bd0031c 100644 --- a/lib/SPELL_DTA/src/SPELLdtaContainer.C +++ b/lib/SPELL_DTA/src/SPELLdtaContainer.C @@ -5,7 +5,7 @@ // DESCRIPTION: Data variable container implementation // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -181,7 +181,7 @@ void SPELLdtaContainer::setValue( PyObject* key, PyObject* value ) { DEBUG("[DTAC] Creating a new variable to contain the value"); - PyObject* varClass = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "Var"); + PyObject* varClass = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "Var"); Py_INCREF(varClass); assert(varClass != NULL); PyObject* dict = PyDict_New(); @@ -233,7 +233,7 @@ PyObject* SPELLdtaContainer::getValue( PyObject* key ) if (!PyDict_Contains(m_dict, key)) { DEBUG("[DTAC] Variable is missing, asking for a value"); - PyObject* varClass = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "Var"); + PyObject* varClass = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "Var"); Py_XINCREF(varClass); PyObject* instance = SPELLpythonHelper::instance().newInstance(varClass, NULL, NULL); Py_XINCREF(instance); diff --git a/lib/SPELL_DTA/src/SPELLdtaContainerObjectMethods.C b/lib/SPELL_DTA/src/SPELLdtaContainerObjectMethods.C index 5e3a775..0a95e3f 100644 --- a/lib/SPELL_DTA/src/SPELLdtaContainerObjectMethods.C +++ b/lib/SPELL_DTA/src/SPELLdtaContainerObjectMethods.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of data container // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -65,7 +65,7 @@ int SPELLdtaContainerObject_Init( SPELLdtaContainerObject* self, PyObject* args, void SPELLdtaContainerObject_Dealloc( SPELLdtaContainerObject* self ) { delete self->container; - self->ob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ @@ -326,8 +326,7 @@ static PyMethodDef dictiter_methods[] = { PyTypeObject SPELLdtaContainerIterator_Type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(&PyType_Type,0) "container-keyiterator", /* tp_name */ sizeof(SPELLdtaContainerIteratorObject),/* tp_basicsize */ 0, /* tp_itemsize */ @@ -380,51 +379,42 @@ PyObject* SPELLdtaContainerObject_NewIterator( SPELLdtaContainerObject* containe //============================================================================ void SPELLdtaContainerObject_DeallocIterator( SPELLdtaContainerIteratorObject* di ) { - di->ob_type->tp_free( (PyObject*)di ); + Py_TYPE(di)->tp_free( (PyObject*)di ); } //============================================================================ // FUNCTION : SPELLdtaContainerObject_NextKey //============================================================================ -PyObject* SPELLdtaContainerObject_NextKey( SPELLdtaContainerIteratorObject* di ) +PyObject* SPELLdtaContainerObject_NextKey(SPELLdtaContainerIteratorObject* di) { - PyObject *key; - register Py_ssize_t i, mask; - register PyDictEntry *ep; + PyObject *key, *value; + Py_ssize_t i; + int result; + DEBUG("[DTAPY] Next iterator key on " + PYCREPR(di)); - DEBUG("[DTAPY] Next iterator key on " + PYCREPR(di)); + PyObject* d = (PyObject*) di->di_dict; - PyDictObject* d = di->di_dict; + if (d == NULL) + return NULL; + assert(PyDict_Check(d)); - DEBUG("[DTAPY] Dictionary: " + PYCREPR(d)); + i = di->di_pos; + if (i < 0) + goto fail; - if (d == NULL) return NULL; + result = PyDict_Next(d, &di->di_pos, &key, &value); - if (di->di_used != d->ma_used) - { - PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); - di->di_used = -1; /* Make this state sticky */ - LOG_ERROR("Dictionary changed size during iteration!!!"); - return NULL; - } - - i = di->di_pos; - if (i < 0) goto fail; - ep = d->ma_table; - mask = d->ma_mask; - while (i <= mask && ep[i].me_value == NULL) i++; - di->di_pos = i+1; - if (i > mask) goto fail; - di->len--; - key = ep[i].me_key; - if (key == NULL) goto fail; - Py_INCREF(key); - return key; -fail: - DEBUG("[DTAPY] No key found to iterate on"); - di->di_dict = NULL; - PyErr_Clear(); - return NULL; + if (!result) + goto fail; + + di->len--; + + Py_INCREF(key); + return key; +fail: DEBUG("[DTAPY] No key found to iterate on"); + di->di_dict = NULL; + PyErr_Clear(); + return NULL; } //============================================================================ diff --git a/lib/SPELL_DTA/src/SPELLdtaModule.C b/lib/SPELL_DTA/src/SPELLdtaModule.C index 1da117e..db7a5d2 100644 --- a/lib/SPELL_DTA/src/SPELLdtaModule.C +++ b/lib/SPELL_DTA/src/SPELLdtaModule.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of DTA module // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -54,7 +54,7 @@ static PyMethodDef SPELLdtaContainerObject_Methods[] = {"get", SPELLdtaContainerObject_Get, METH_VARARGS, "Get a value"}, {"has_key", SPELLdtaContainerObject_HasKey, METH_VARARGS, "Check if the key exists"}, {"keys", SPELLdtaContainerObject_Keys, METH_NOARGS, "Obtain the keys"}, - {"values", SPELLdtaContainerObject_Keys, METH_NOARGS, "Obtain the values"}, + {"values", SPELLdtaContainerObject_Values, METH_NOARGS, "Obtain the values"}, {"enableNotifications", SPELLdtaContainerObject_EnableNotifications, METH_NOARGS, "Enable value notifications"}, {"disableNotifications", SPELLdtaContainerObject_DisableNotifications, METH_NOARGS, "Disable value notifications"}, {NULL, NULL, 0, NULL} /* Sentinel */ @@ -91,8 +91,7 @@ static PyMappingMethods SPELLdtaContainerObject_MappingMethods = //============================================================================ static PyTypeObject SPELLdtaContainerObject_Type = { - PyObject_HEAD_INIT(NULL) /* basic object head */ - 0, /* var objects */ + PyVarObject_HEAD_INIT(NULL,0) /* basic object head */ "spell.lib.adapter.data.DataContainer", /* type name */ sizeof(SPELLdtaContainerObject), /* type size */ 0, /* item size */ @@ -145,8 +144,7 @@ static PyTypeObject SPELLdtaContainerObject_Type = //============================================================================ static PyTypeObject SPELLdtaVariableObject_Type = { - PyObject_HEAD_INIT(NULL) /* basic object head */ - 0, /* var objects */ + PyVarObject_HEAD_INIT(NULL,0) /* basic object head */ "spell.lib.adapter.data.Var", /* type name */ sizeof(SPELLdtaVariableObject), /* type size */ 0, /* item size */ @@ -197,8 +195,8 @@ static PyTypeObject SPELLdtaVariableObject_Type = ////////////////////////////////////////////////////////////////////////////// // PYTHON MODULE INITIALIZATION ////////////////////////////////////////////////////////////////////////////// -PyMODINIT_FUNC -initlibSPELL_DTA(void) + +MOD_INIT(libSPELL_DTA) { // Will hold the Python module PyObject* module; @@ -210,7 +208,7 @@ initlibSPELL_DTA(void) std::string err = "Unable to load type " + std::string(SPELLdtaContainerObject_Type.tp_name); PyErr_SetString( PyExc_RuntimeError, err.c_str()); std::cerr << "ERROR: " << err << std::endl; - return; + return MOD_ERROR_VAL; } // Allocate the new type for SPELL variable containers @@ -220,15 +218,17 @@ initlibSPELL_DTA(void) std::string err = "Unable to load type " + std::string(SPELLdtaVariableObject_Type.tp_name); PyErr_SetString( PyExc_RuntimeError, err.c_str()); std::cerr << "ERROR: " << err << std::endl; - return; + return MOD_ERROR_VAL; } // Initialize the module - module = Py_InitModule3("libSPELL_DTA", NULL, "Module for SPELL data containers"); + MOD_DEF(module,MOD_NAME(libSPELL_DTA),"Module for SPELL data containers",NULL); Py_INCREF(&SPELLdtaContainerObject_Type); PyModule_AddObject(module, "DataContainer", (PyObject *)&SPELLdtaContainerObject_Type); Py_INCREF(&SPELLdtaVariableObject_Type); PyModule_AddObject(module, "Var", (PyObject *)&SPELLdtaVariableObject_Type); + + return MOD_SUCCESS_VAL(module); } diff --git a/lib/SPELL_DTA/src/SPELLdtaVariable.C b/lib/SPELL_DTA/src/SPELLdtaVariable.C index 4b0e372..66f5f19 100644 --- a/lib/SPELL_DTA/src/SPELLdtaVariable.C +++ b/lib/SPELL_DTA/src/SPELLdtaVariable.C @@ -5,7 +5,7 @@ // DESCRIPTION: Data variable implementation // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -955,10 +955,14 @@ bool SPELLdtaVariable::promptForValue( std::string& message ) for(unsigned int idx = 0; idx < m_expected.size(); idx++) { std::string option = ""; - if (m_type == LanguageConstants::STRING || m_type == LanguageConstants::DATETIME || m_type == LanguageConstants::RELTIME ) + if (m_type == LanguageConstants::STRING) { option = "'" + m_expected[idx].str() + "'"; } + else if (m_type == LanguageConstants::DATETIME || m_type == LanguageConstants::RELTIME ) + { + option = m_expected[idx].str(); + } else { option = m_expected[idx].str(); diff --git a/lib/SPELL_DTA/src/SPELLdtaVariableObjectMethods.C b/lib/SPELL_DTA/src/SPELLdtaVariableObjectMethods.C index ebbbb89..580343a 100644 --- a/lib/SPELL_DTA/src/SPELLdtaVariableObjectMethods.C +++ b/lib/SPELL_DTA/src/SPELLdtaVariableObjectMethods.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of variable container // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -70,7 +70,7 @@ int SPELLdtaVariableObject_Init( SPELLdtaVariableObject* self, PyObject* args, P void SPELLdtaVariableObject_Dealloc( SPELLdtaVariableObject* self ) { delete self->var; - self->ob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ diff --git a/lib/SPELL_EXC/Makefile.am b/lib/SPELL_EXC/Makefile.am index 9a4fab4..733d639 100644 --- a/lib/SPELL_EXC/Makefile.am +++ b/lib/SPELL_EXC/Makefile.am @@ -1,62 +1,98 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -#libSPELL_EXC_la_CPPFLAGS = ${AM_CPPFLAGS} -DWITH_DEBUG - -lib_LTLIBRARIES= libSPELL_EXC.la -libSPELL_EXC_la_LDFLAGS = -version-info 3:0:0 -libSPELL_EXC_la_SOURCES = \ - src/SPELLgoto.C \ - src/SPELLbreakpoint.C \ - src/SPELLbreakpointType.C \ - src/SPELLbytecode.C \ - src/SPELLastAnalyzer.C \ - src/SPELLexecutor.C \ - src/SPELLexecutorImpl.C \ - src/SPELLimportChecker.C \ - src/SPELLexecutorPython.C \ - src/SPELLcallstack.C \ - src/SPELLexecutorUtils.C \ - src/SPELLinterpreter.C \ - src/SPELLgotoPython.C \ - src/SPELLstepPython.C \ - src/SPELLscheduler.C \ - src/SPELLchildManager.C \ - src/SPELLframeManager.C \ - src/SPELLlnotab.C \ - src/SPELLcontroller.C \ - src/SPELLcodeTreeNode.C \ - src/SPELLcodeTreeLine.C \ - src/SPELLexecutorConfiguration.C \ - src/SPELLexecutionModel.C \ - src/SPELLexecutionTrace.C \ - src/SPELLvariableMonitor.C \ - src/SPELLvariableManager.C \ - src/SPELLcommandMailbox.C - - +lib_LTLIBRARIES = libSPELL_EXC_v2.la libSPELL_EXC_v3.la + +libSPELL_EXC_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_EXC_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_EXC_v2_la_SOURCES = src/SPELLgoto.C \ + src/SPELLbreakpoint.C \ + src/SPELLbreakpointType.C \ + src/SPELLbytecode.C \ + src/SPELLastAnalyzer.C \ + src/SPELLexecutor.C \ + src/SPELLexecutorImpl.C \ + src/SPELLserviceImpl.C \ + src/SPELLimportChecker.C \ + src/SPELLexecutorPython.C \ + src/SPELLcallstack.C \ + src/SPELLexecutorUtils.C \ + src/SPELLinterpreter.C \ + src/SPELLserviceInterpreter.C \ + src/SPELLgotoPython.C \ + src/SPELLstepPython.C \ + src/SPELLscheduler.C \ + src/SPELLchildManager.C \ + src/SPELLframeManager.C \ + src/SPELLlnotab.C \ + src/SPELLcontroller.C \ + src/SPELLcodeTreeNode.C \ + src/SPELLcodeTreeLine.C \ + src/SPELLexecutorConfiguration.C \ + src/SPELLexecutionModel.C \ + src/SPELLexecutionTrace.C \ + src/SPELLvariableMonitor.C \ + src/SPELLvariableManager.C \ + src/SPELLresourceMonitor.C \ + src/SPELLresourceManager.C \ + src/SPELLcommandMailbox.C + + +libSPELL_EXC_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_EXC_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_EXC_v3_la_SOURCES = src/SPELLgoto.C \ + src/SPELLbreakpoint.C \ + src/SPELLbreakpointType.C \ + src/SPELLbytecode.C \ + src/SPELLastAnalyzer.C \ + src/SPELLexecutor.C \ + src/SPELLexecutorImpl.C \ + src/SPELLserviceImpl.C \ + src/SPELLimportChecker.C \ + src/SPELLexecutorPython.C \ + src/SPELLcallstack.C \ + src/SPELLexecutorUtils.C \ + src/SPELLinterpreter.C \ + src/SPELLserviceInterpreter.C \ + src/SPELLgotoPython.C \ + src/SPELLstepPython.C \ + src/SPELLscheduler.C \ + src/SPELLchildManager.C \ + src/SPELLframeManager.C \ + src/SPELLlnotab.C \ + src/SPELLcontroller.C \ + src/SPELLcodeTreeNode.C \ + src/SPELLcodeTreeLine.C \ + src/SPELLexecutorConfiguration.C \ + src/SPELLexecutionModel.C \ + src/SPELLexecutionTrace.C \ + src/SPELLvariableMonitor.C \ + src/SPELLvariableManager.C \ + src/SPELLresourceMonitor.C \ + src/SPELLresourceManager.C \ + src/SPELLcommandMailbox.C + \ No newline at end of file diff --git a/lib/SPELL_EXC/src/SPELLastAnalyzer.C b/lib/SPELL_EXC/src/SPELLastAnalyzer.C index 54dd55a..e00abbc 100644 --- a/lib/SPELL_EXC/src/SPELLastAnalyzer.C +++ b/lib/SPELL_EXC/src/SPELLastAnalyzer.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the AST analyzer // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -43,6 +43,8 @@ //============================================================================ SPELLastAnalyzer::SPELLastAnalyzer() { + m_lastLineType = NONE; + m_openLineNo = 0; DEBUG("[ASTN] AST analyzer created"); }; diff --git a/lib/SPELL_EXC/src/SPELLbreakpoint.C b/lib/SPELL_EXC/src/SPELLbreakpoint.C index 6521b82..6227245 100644 --- a/lib/SPELL_EXC/src/SPELLbreakpoint.C +++ b/lib/SPELL_EXC/src/SPELLbreakpoint.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the breakpoint manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLbreakpointType.C b/lib/SPELL_EXC/src/SPELLbreakpointType.C index d001050..2997ec8 100644 --- a/lib/SPELL_EXC/src/SPELLbreakpointType.C +++ b/lib/SPELL_EXC/src/SPELLbreakpointType.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the breakpoint types // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLbytecode.C b/lib/SPELL_EXC/src/SPELLbytecode.C index 11cb834..e4afc6c 100644 --- a/lib/SPELL_EXC/src/SPELLbytecode.C +++ b/lib/SPELL_EXC/src/SPELLbytecode.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the bytecode analyzer // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -36,9 +36,20 @@ // Macros for accessing opcodes +#if PY_MAJOR_VERSION >= 3 +#define INSTR_OFFSET() \ + (sizeof(_Py_CODEUNIT) * (int)(next_instr - first_instr)) +#define NEXTOPARG() do { \ + _Py_CODEUNIT word = *next_instr; \ + opcode = _Py_OPCODE(word); \ + oparg = _Py_OPARG(word); \ + next_instr++; \ + } while (0) +#else #define NEXTOP() (*next_instr++) #define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2]) #define INSTR_OFFSET() ((int)(next_instr - first_instr)) +#endif // Debugging macro #define DUMP DEBUG("[" + ISTR(info->lineno) +\ ":" + ISTR(info->offset) + "]: " + OPCODES[info->opcode] \ @@ -225,9 +236,13 @@ void SPELLbytecode::analyze() { assert( m_code != NULL ); // Pointer to initial instruction (used by macros) - unsigned char* first_instr = (unsigned char*) PyString_AS_STRING(m_code->co_code); +#if PY_MAJOR_VERSION >= 3 + _Py_CODEUNIT* first_instr = (_Py_CODEUNIT*) PyBytes_AsString(m_code->co_code); +#else + _Py_CODEUNIT* first_instr = (_Py_CODEUNIT*) PyString_AsString(m_code->co_code); +#endif // Pointer to current instruction (used by macros) - register unsigned char* next_instr = first_instr; + register _Py_CODEUNIT* next_instr = first_instr; // Opcode argument unsigned int oparg; // Stores the previous line @@ -235,10 +250,9 @@ void SPELLbytecode::analyze() // Stores the last opcode unsigned int prevOpCode = 0; // Opcode count in line - unsigned short opcodeCount = 0; + unsigned int opcodeCount = 0; // Will be true when there is no more bytecode to process - bool finished = false; unsigned int callDepth = 0; // Try block structure TryBlock tb; @@ -250,8 +264,12 @@ void SPELLbytecode::analyze() // Holds the bytecode offset for except and finally statements unsigned int except_offset = 0; unsigned int finally_offset = 0; + // Holds the current opcode +#if PY_MAJOR_VERSION >= 3 + unsigned int opcode; +#endif - while(not finished) + while(true) { // Create one BLine info structure per bytecode instruction BLine info; @@ -260,7 +278,20 @@ void SPELLbytecode::analyze() // Get the corresponding script line info.lineno = PyCode_Addr2Line(m_code, info.offset); // Obtain the opcode + +#if PY_MAJOR_VERSION >= 3 + NEXTOPARG(); + info.opcode = opcode; + +#else info.opcode = NEXTOP(); +#endif + // Track the end of the code + if (info.opcode == 0/*STOP_CODE*/) + { + m_lastAddr = info.offset; + break; + } // Track the number of opcodes per line in the lnotab. if ((prevLine>0) && (info.lineno != prevLine)) @@ -302,11 +333,11 @@ void SPELLbytecode::analyze() // We will ignore this, for the moment +#if PY_MAJOR_VERSION < 3 oparg = 0; - // To decide wether store the bline information or not - bool storeit = false; - if (HAS_ARG(info.opcode)) oparg = NEXTARG(); + if (HAS_ARG(info.opcode)) oparg = NEXTARG(); +#endif ////////////////////////////////////////////////////////////////////////////////// // PHASE 2 - BUILD AND STORE NEXT BLINE INFORMATION ////////////////////////////////////////////////////////////////////////////////// @@ -366,15 +397,12 @@ void SPELLbytecode::analyze() ////////////////////////////////////////////////////////////////////////////////// switch(info.opcode) { - case RETURN_VALUE: - m_lastAddr = info.offset; - finished = true; - break; case SETUP_EXCEPT: tb.try_lineno = info.lineno; except_offset = info.offset + oparg + 3; // This is the real destination offset break; case SETUP_FINALLY: + tb.try_lineno = info.lineno; finally_offset = info.offset + oparg + 3; // This is the 'finally' destination offset break; case END_FINALLY: diff --git a/lib/SPELL_EXC/src/SPELLcallstack.C b/lib/SPELL_EXC/src/SPELLcallstack.C index 3703a47..3daf9e7 100644 --- a/lib/SPELL_EXC/src/SPELLcallstack.C +++ b/lib/SPELL_EXC/src/SPELLcallstack.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the callstack model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -89,7 +89,7 @@ void SPELLcallstack::reset() //============================================================================= // METHOD : SPELLcallstack::getStack() //============================================================================= -const std::string& SPELLcallstack::getStack() +const std::string SPELLcallstack::getStack() { SPELLmonitor mon(m_lock); @@ -108,7 +108,7 @@ const std::string SPELLcallstack::getFullStack() //============================================================================= // METHOD : SPELLcallstack::getCodeName() //============================================================================= -const std::string& SPELLcallstack::getCodeName() +const std::string SPELLcallstack::getCodeName() { SPELLmonitor mon(m_lock); @@ -319,7 +319,8 @@ void SPELLcallstack::callbackEventReturn( PyFrameObject* frame, const std::strin // When moving the view node, we shall notify the client. // Do not remove the code on top. Just move the current node pointer. - m_currentNode = m_currentNode->getParent()->getParentCode(); + if (m_currentNode->getParent() != NULL) + m_currentNode = m_currentNode->getParent()->getParentCode(); // Store current line m_currentLine = line; diff --git a/lib/SPELL_EXC/src/SPELLchildManager.C b/lib/SPELL_EXC/src/SPELLchildManager.C index f5c3882..d3d7e7b 100644 --- a/lib/SPELL_EXC/src/SPELLchildManager.C +++ b/lib/SPELL_EXC/src/SPELLchildManager.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the child procedure manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLcodeTreeLine.C b/lib/SPELL_EXC/src/SPELLcodeTreeLine.C index feaa9a5..ed3e4fa 100644 --- a/lib/SPELL_EXC/src/SPELLcodeTreeLine.C +++ b/lib/SPELL_EXC/src/SPELLcodeTreeLine.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the execution line model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLcodeTreeNode.C b/lib/SPELL_EXC/src/SPELLcodeTreeNode.C index e36a4e8..33dbd55 100644 --- a/lib/SPELL_EXC/src/SPELLcodeTreeNode.C +++ b/lib/SPELL_EXC/src/SPELLcodeTreeNode.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the execution node model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLcommandMailbox.C b/lib/SPELL_EXC/src/SPELLcommandMailbox.C index 3572171..0048933 100644 --- a/lib/SPELL_EXC/src/SPELLcommandMailbox.C +++ b/lib/SPELL_EXC/src/SPELLcommandMailbox.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the command mailbox // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLcontroller.C b/lib/SPELL_EXC/src/SPELLcontroller.C index c605b89..058faf1 100644 --- a/lib/SPELL_EXC/src/SPELLcontroller.C +++ b/lib/SPELL_EXC/src/SPELLcontroller.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor controller // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -34,6 +34,7 @@ #include "SPELL_WRP/SPELLconstants.H" #include "SPELL_WRP/SPELLregistry.H" #include "SPELL_WRP/SPELLdriverManager.H" +#include "SPELL_WRP/SPELLpyHandle.H" // Local includes ---------------------------------------------------------- #include "SPELL_EXC/SPELLexecutor.H" #include "SPELL_EXC/SPELLcontroller.H" @@ -112,6 +113,15 @@ void SPELLcontroller::command( const ExecutorCommand& cmd, const bool queueIt, c executeCommand(cmd); } } +void SPELLcontroller::refreshStatus() { + LOG_INFO("Procedure status: " + SPELLexecutorUtils::statusToString(m_status)); + SPELLstatusInfo info(m_status); + info.condition = getCondition(); + info.actionLabel = SPELLexecutor::instance().getUserAction().getLabel(); + info.actionEnabled = SPELLexecutor::instance().getUserAction().isEnabled(); + + SPELLexecutor::instance().getCIF().notifyStatus( info ); +} //============================================================================= // METHOD : SPELLcontroller::setStatus @@ -119,6 +129,19 @@ void SPELLcontroller::command( const ExecutorCommand& cmd, const bool queueIt, c void SPELLcontroller::setStatus( const SPELLexecutorStatus& st ) { DEBUG("[C] Attempt to set status " + SPELLexecutorUtils::statusToString(st)); + + // Do not allow a status change (this may be manually invoked) in a final status + switch(m_status) + { + case STATUS_FINISHED: + case STATUS_ERROR: + case STATUS_ABORTED: + DEBUG("[C] In final status status " + SPELLexecutorUtils::statusToString(m_status) + " do not change status now. Check code."); + return; + default: + break; + } + bool newStatus = (st != m_status); if (newStatus) notifyBeforeStatusChange(m_status); @@ -311,8 +334,6 @@ void SPELLcontroller::executeCommand( const ExecutorCommand& cmd ) startCommandProcessing(); - notifyCommandToCore( cmd.id ); - if (cmd.id == CMD_ABORT) { doAbort(); @@ -390,10 +411,16 @@ void SPELLcontroller::executeCommand( const ExecutorCommand& cmd ) { doRecover(); } + else if (cmd.id == CMD_RESOURCES) + { + SPELLexecutor::instance().getResourceManager().callResourceMonitorFromClient( cmd.arg ); + } else { LOG_ERROR("[C] UNRECOGNISED COMMAND: " + cmd.id); } + notifyCommandToCore( cmd.id ); + m_mailbox.commandProcessed(); // The command has finished, release the dispatcher @@ -761,7 +788,11 @@ void SPELLcontroller::doSkip() /** \todo Should try to go to upper frame instead of stepping. // This is the issue that obligues us to put a return statement // at the end of each function. */ - doStep(false); + //doStep(false); + // For now just send a warning + SPELLexecutor::instance().getCIF().warning("Cannot execute 'Skip' on this line. Use 'Step' or 'Goto line number' instead." + "(This may happen for 'return' and 'try' block).", + LanguageConstants::SCOPE_SYS ); } } } @@ -1234,3 +1265,12 @@ void SPELLcontroller::notifyAfterDriverOperation() (*it)->callbackAfterDriverOperation(); } } + + +//============================================================================= +// METHOD : SPELLscheduler::raiseInformationEventToGCS() +//============================================================================= +void SPELLcontroller::raiseInformationEventToGCS( const std::string& message ) { + SPELLsafePythonOperations ops("SPELLcontroller::raiseInformationEventToGCS()"); + raiseEvent(message); +} \ No newline at end of file diff --git a/lib/SPELL_EXC/src/SPELLexecutionModel.C b/lib/SPELL_EXC/src/SPELLexecutionModel.C index 07fdcaf..7c1c345 100644 --- a/lib/SPELL_EXC/src/SPELLexecutionModel.C +++ b/lib/SPELL_EXC/src/SPELLexecutionModel.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the execution model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLexecutionTrace.C b/lib/SPELL_EXC/src/SPELLexecutionTrace.C index c184a45..1c36fb4 100644 --- a/lib/SPELL_EXC/src/SPELLexecutionTrace.C +++ b/lib/SPELL_EXC/src/SPELLexecutionTrace.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the execution trace model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLexecutor.C b/lib/SPELL_EXC/src/SPELLexecutor.C index 92ff4d9..d345e34 100644 --- a/lib/SPELL_EXC/src/SPELLexecutor.C +++ b/lib/SPELL_EXC/src/SPELLexecutor.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor singleton access // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLexecutorConfiguration.C b/lib/SPELL_EXC/src/SPELLexecutorConfiguration.C index 0d165b0..58c14ff 100644 --- a/lib/SPELL_EXC/src/SPELLexecutorConfiguration.C +++ b/lib/SPELL_EXC/src/SPELLexecutorConfiguration.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor configuration // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -70,7 +70,10 @@ SPELLexecutorConfig::SPELLexecutorConfig( const SPELLexecutorConfig& refConfig ) m_blocking = refConfig.isBlocking(); m_saveStateMode = refConfig.getSaveStateMode(); m_watchVariables = refConfig.isWatchEnabled(); + m_resourcesDisplay = refConfig.isResourcesDisplayEnabled(); + m_localResourceSupport = refConfig.isLocalResourcesSupported(); m_forceTcConfirm = refConfig.isForceTcConfirm(); + m_forcePromptConfirm = refConfig.isForcePromptConfirm(); m_controlClient = refConfig.getControlClient(); m_controlHost = refConfig.getControlHost(); m_headless = refConfig.isHeadless(); @@ -97,7 +100,10 @@ SPELLexecutorConfig& SPELLexecutorConfig::operator=( SPELLexecutorConfig& refCon m_blocking = refConfig.isBlocking(); m_saveStateMode = refConfig.getSaveStateMode(); m_watchVariables = refConfig.isWatchEnabled(); + m_resourcesDisplay = refConfig.isResourcesDisplayEnabled(); + m_localResourceSupport = refConfig.isLocalResourcesSupported(); m_forceTcConfirm = refConfig.isForceTcConfirm(); + m_forcePromptConfirm = refConfig.isForcePromptConfirm(); m_controlClient = refConfig.getControlClient(); m_controlHost = refConfig.getControlHost(); m_headless = refConfig.isHeadless(); @@ -129,7 +135,10 @@ void SPELLexecutorConfig::reset() m_runInto = true; m_watchVariables = false; + m_resourcesDisplay = false; + m_localResourceSupport = false; m_forceTcConfirm = false; + m_forcePromptConfirm = false; m_controlClient = ""; m_controlHost = ""; m_contextName = ""; diff --git a/lib/SPELL_EXC/src/SPELLexecutorImpl.C b/lib/SPELL_EXC/src/SPELLexecutorImpl.C index 3bf29fc..580ec4b 100644 --- a/lib/SPELL_EXC/src/SPELLexecutorImpl.C +++ b/lib/SPELL_EXC/src/SPELLexecutorImpl.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -29,6 +29,7 @@ // Local includes ---------------------------------------------------------- #include "SPELL_EXC/SPELLexecutor.H" #include "SPELL_EXC/SPELLexecutorImpl.H" +#include "SPELL_EXC/SPELLexecutorUtils.H" // Project includes -------------------------------------------------------- #include "SPELL_PRD/SPELLprocedureManager.H" #include "SPELL_SYN/SPELLmonitor.H" @@ -54,8 +55,6 @@ static int static_dispatch( PyObject* obj, PyFrameObject* frame, int what, PyObj return SPELLexecutor::instance().dispatch(obj, frame, what, args); } -static SPELLexecutorConfig EMPTY_CONFIGURATION; - //============================================================================= // FUNCTION: convert dispatch data type to string //============================================================================= @@ -104,6 +103,7 @@ SPELLexecutorImpl::SPELLexecutorImpl() m_controller = NULL; m_childMgr = NULL; m_varManager = NULL; + m_resourceManager = NULL; m_userAction.reset(); m_gotoTarget = ""; @@ -129,6 +129,15 @@ SPELLexecutorImpl::~SPELLexecutorImpl() //============================================================================= // METHOD : SPELLexecutorImpl::initialize() //============================================================================= + +void SPELLexecutorImpl::refreshStatus() +{ + if (m_controller != NULL) + { + m_controller->refreshStatus(); + } +} + void SPELLexecutorImpl::initialize( SPELLcif* cif, SPELLcontrollerIF* controller, SPELLschedulerIF* scheduler, @@ -146,6 +155,7 @@ void SPELLexecutorImpl::initialize( SPELLcif* cif, m_callstack = callstack; m_frameManager = frame; m_varManager = new SPELLvariableManager(*frame); + m_resourceManager = new SPELLresourceManager(*frame); // The order is important here! addDispatchListener(m_frameManager); @@ -156,13 +166,13 @@ void SPELLexecutorImpl::initialize( SPELLcif* cif, //============================================================================= // METHOD : SPELLexecutorImpl::getConfiguration() //============================================================================= -SPELLexecutorConfig& SPELLexecutorImpl::getConfiguration() const +SPELLexecutorConfig& SPELLexecutorImpl::getConfiguration() { if (m_cif != NULL) { return m_cif->getExecutorConfig(); } - return EMPTY_CONFIGURATION; + return m_emptyConfig; }; //============================================================================= @@ -223,8 +233,11 @@ void SPELLexecutorImpl::prepare( const std::string& instanceId, const SPELLconte LOG_INFO("[E] Blocking mode : " + BSTR( getConfiguration().isBlocking() )); LOG_INFO("[E] Browsable lib : " + getConfiguration().getBrowsableLibStr() ); LOG_INFO("[E] TC Confirm : " + BSTR( getConfiguration().isForceTcConfirm() )); + LOG_INFO("[E] Prompt Confirm : " + BSTR( getConfiguration().isForcePromptConfirm() )); LOG_INFO("[E] Save state mode : " + getConfiguration().getSaveStateMode() ); LOG_INFO("[E] Watch variables : " + BSTR(getConfiguration().isWatchEnabled()) ); + LOG_INFO("[E] Resources Display: " + BSTR(getConfiguration().isResourcesDisplayEnabled()) ); + LOG_INFO("[E] Local resources support: " + BSTR(getConfiguration().isLocalResourcesSupported()) ); LOG_INFO("[E] Input directory : " + m_inputDir ); LOG_INFO("[E] Output directory : " + m_outputDir ); LOG_INFO("[E] Run Into : " + BSTR(getConfiguration().isRunInto())); @@ -306,7 +319,7 @@ void SPELLexecutorImpl::installCallingArguments() // Initialize now the data container for Calling Arguments Py_INCREF(argDict); DEBUG("[E] Argument dictionary: " + PYREPR(argDict)); - PyObject* classObj = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "DataContainer"); + PyObject* classObj = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "DataContainer"); PyObject* argTuple = PyTuple_New(1); PyObject* argsName = STRPY("Calling Arguments"); PyTuple_SetItem(argTuple,0,argsName); @@ -341,7 +354,7 @@ void SPELLexecutorImpl::installCallingArguments() //============================================================================= void SPELLexecutorImpl::installInternalVariables() { - PyObject* classObj = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "DataContainer"); + PyObject* classObj = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "DataContainer"); PyObject* argTuple = PyTuple_New(1); PyObject* argsName = STRPY("Internal Variables"); PyTuple_SetItem(argTuple,0,argsName); @@ -403,22 +416,34 @@ void SPELLexecutorImpl::executeInternal( bool doReset ) m_controller->enableRunInto( getConfiguration().isRunInto() ); // The client will know that the executor is ready to go - m_controller->setStatus(STATUS_LOADED); + // Take into account initialization errors + SPELLexecutorStatus status = m_controller->getStatus(); + LOG_INFO("Initial status check: " + SPELLexecutorUtils::statusToString(status) ); + SPELLexecutionResult result = EXECUTION_UNKNOWN; + if (status != STATUS_ERROR) + { + m_controller->setStatus(STATUS_LOADED); - // If in automatic and backgorund mode, set the controller in play mode accordingly - // IMPORTANT If in automatic and foreground mode, it is the GUI who sends the run command - if ( getConfiguration().isHeadless() || (getConfiguration().isAutomatic() && (!getConfiguration().isVisible()) ) ) - { - DEBUG("[E] Set autorun"); - m_controller->setAutoRun(); - } + // If in automatic and backgorund mode, set the controller in play mode accordingly + // IMPORTANT If in automatic and foreground mode, it is the GUI who sends the run command + if ( getConfiguration().isHeadless() || (getConfiguration().isAutomatic() && (!getConfiguration().isVisible()) ) ) + { + DEBUG("[E] Set autorun"); + m_controller->setAutoRun(); + } - DEBUG("[E] Launching execution"); - // Execute the procedure/script. This triggers the procedure - // execution under dispatcher control. - SPELLexecutionResult result = m_frameManager->execute(); + DEBUG("[E] Launching execution"); + // Execute the procedure/script. This triggers the procedure + // execution under dispatcher control. + result = m_frameManager->execute(); - DEBUG("[E] Execution done, checking result (" + ISTR(result) + ")"); + DEBUG("[E] Execution done, checking result (" + ISTR(result) + ")"); + } + else + { + LOG_ERROR("Initialization error"); + result = EXECUTION_ERROR; + } // Check execution result and proceed accordingly. // Frame will be reset and environment unloaded if needed, depending on the case. @@ -669,9 +694,6 @@ void SPELLexecutorImpl::loadExecutionEnvironment() // Check for Python errors SPELLpythonHelper::instance().checkError(); - // Load SCDB and GDB - SPELLdatabaseManager::instance().loadBuiltinDatabases(); - // Create proc dictionary object and install it PyObject* procObj = PyDict_New(); PyObject* pname = SSTRPY(m_instanceId); @@ -689,10 +711,48 @@ void SPELLexecutorImpl::loadExecutionEnvironment() PyDict_SetItemString( procObj, DatabaseConstants::PARENT.c_str(), parentId); SPELLpythonHelper::instance().install( procObj, DatabaseConstants::PROC ); + SPELLpythonHelper::instance().checkError(); - SPELLpythonHelper::instance().importUserLibraries( m_libPath ); - + // Load SCDB and GDB + SPELLdatabaseManager::instance().loadBuiltinDatabases(); SPELLpythonHelper::instance().checkError(); + + bool success = true; + std::string importErrors = ""; + + if (m_libPath != "") + { + if (m_libPath.find(",") != std::string::npos) + { + std::vector items = SPELLutils::tokenize(m_libPath,","); + std::vector::const_iterator cit; + for(cit = items.begin(); cit != items.end(); cit++) + { + success = SPELLpythonHelper::instance().importUserLibraries( *cit, importErrors ) && success; + } + } + else + { + try + { + success = SPELLpythonHelper::instance().importUserLibraries( m_libPath, importErrors ) && success; + } + catch(SPELLcoreException& ex) + { + importErrors += "\n - Failed to import user libraries from '" + m_libPath + "': " + ex.what(); + } + } + } + else + { + LOG_INFO("No user libraries defined"); + } + + + if (!success) + { + LOG_ERROR("Errors detected in UserLib: " + importErrors); + } // Tell the execution frame that the environment has been updated m_frameManager->filterDictUpdated(); @@ -723,6 +783,11 @@ void SPELLexecutorImpl::loadDriver() setForceTcConfirmInternal(true); } + if (getConfiguration().isForcePromptConfirm()) + { + setForcePromptConfirmInternal(true); + } + // Load the driver language specifics SPELLcontextConfig& ctxConfig = SPELLconfiguration::instance().getContext( getConfiguration().getContextName() ); std::string driverName = ctxConfig.getDriverName(); @@ -1068,6 +1133,9 @@ int SPELLexecutorImpl::dispatch( PyObject* obj, PyFrameObject* frame, int what, if(!m_controller->checkAborted()) { m_frameManager->terminate(); + if (what == PyTrace_EXCEPTION) + // We haven't raised an exception in case we trace an exception therefore return 0 (no error) + return 0; return -1; } @@ -1198,6 +1266,18 @@ void SPELLexecutorImpl::setForceTcConfirm( const bool force ) } } +//============================================================================= +// METHOD : SPELLexecutorImpl::setForceTcConfirm +//============================================================================= +void SPELLexecutorImpl::setForcePromptConfirm( const bool force ) +{ + if (getConfiguration().isForcePromptConfirm() != force ) + { + LOG_INFO("[EXEC] Set force Prompt confirmation to " + BSTR(force)); + getConfiguration().setForcePromptConfirm(force); + setForcePromptConfirmInternal(force); + } +} //============================================================================= // METHOD : SPELLexecutorImpl::command //============================================================================= @@ -1210,7 +1290,18 @@ void SPELLexecutorImpl::setForceTcConfirmInternal( bool force ) SPELLpythonHelper::instance().callMethod( tc, "forceTcConfirm", arg, NULL ); } } - +//============================================================================= +// METHOD : SPELLexecutorImpl::command +//============================================================================= +void SPELLexecutorImpl::setForcePromptConfirmInternal( bool force ) +{ + PyObject* tc = SPELLregistry::instance().get("CIF"); + if (tc != NULL) + { + PyObject* arg = force ? Py_True : Py_False; + SPELLpythonHelper::instance().callMethod( tc, "forcePromptConfirm", arg, NULL ); + } +} //============================================================================= // METHOD : SPELLexecutorImpl::command //============================================================================= @@ -1292,7 +1383,8 @@ void SPELLexecutorImpl::finish( const std::string& message ) //============================================================================= void SPELLexecutorImpl::processLock() { - SPELLmonitor m(m_cmdLock); + // TODO: No reason to lock here. Remove once validated. + //SPELLmonitor m(m_cmdLock); m_controller->executionLock(); } @@ -1301,7 +1393,8 @@ void SPELLexecutorImpl::processLock() //============================================================================= void SPELLexecutorImpl::processUnlock() { - SPELLmonitor m(m_cmdLock); + // TODO: No reason to lock here. Remove once validated. + //SPELLmonitor m(m_cmdLock); m_controller->executionUnlock(); } @@ -1568,9 +1661,13 @@ void SPELLexecutorImpl::displayStage( const std::string& id, const std::string& Py_INCREF(pyId); Py_INCREF(pyDesc); + // Get the previous step value if any + PyObject* prev = PyDict_GetItemString(proc, DatabaseConstants::STEP.c_str()); + + // Set the new value PyDict_SetItemString( proc, DatabaseConstants::STEP.c_str(), list); - PyObject* prev = PyDict_GetItemString(proc, DatabaseConstants::STEP.c_str()); + // If there was a previous value, set it as PREVIOUS if (prev != NULL) { PyDict_SetItemString( proc, DatabaseConstants::PREV_STEP.c_str(), prev); diff --git a/lib/SPELL_EXC/src/SPELLexecutorPython.C b/lib/SPELL_EXC/src/SPELLexecutorPython.C index d243498..84e04c2 100644 --- a/lib/SPELL_EXC/src/SPELLexecutorPython.C +++ b/lib/SPELL_EXC/src/SPELLexecutorPython.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor Python bindings // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -179,6 +179,17 @@ static PyObject* Executor_DisableUserAction( PyObject* self, PyObject* args ); // DESCRIPTION : set current step id and description //============================================================================ static PyObject* Executor_SetStep( PyObject* self, PyObject* args ); + +//============================================================================ +// FUNCTION : Executor_SetByStep +//============================================================================ +static PyObject* Executor_SetByStep( PyObject* self, PyObject* args ); + +//============================================================================ +// FUNCTION : Executor_SetExecutionDelay +//============================================================================ +static PyObject* Executor_GetByStep( PyObject* self, PyObject* args ); + //============================================================================ // FUNCTION : Executor_Notify // DESCRIPTION : Notify arbitrary data @@ -232,8 +243,10 @@ static PyMethodDef Executor_Methods[] = {"dismissUserAction", Executor_DismissUserAction, METH_NOARGS, "Unset the user action function"}, {"enableUserAction", Executor_EnableUserAction, METH_NOARGS, "Enable the user action function"}, {"disableUserAction", Executor_DisableUserAction, METH_NOARGS, "Disable the user action function"}, - {"setStep" , Executor_SetStep, METH_VARARGS, "Set current step name"}, - {"setExecutionDelay", Executor_SetExecutionDelay, METH_VARARGS, "Set execution delay"}, + {"setStep" , Executor_SetStep, METH_VARARGS, "Set current step name"}, + {"setByStep" , Executor_SetByStep, METH_VARARGS, "Set the ByStep configuration"}, + {"getByStep" , Executor_GetByStep, METH_NOARGS, "Get the ByStep configuration"}, + {"setExecutionDelay", Executor_SetExecutionDelay, METH_VARARGS, "Set execution delay"}, {"notify", Executor_Notify, METH_VARARGS, "Notify items"}, {"getControllingHost", Executor_GetControllingHost, METH_NOARGS, "Get the controlling host"}, {NULL, NULL, 0, NULL} /* Sentinel */ @@ -244,8 +257,7 @@ static PyMethodDef Executor_Methods[] = //============================================================================ static PyTypeObject Executor_Type = { - PyObject_HEAD_INIT(NULL) - 0, //ob_size + PyVarObject_HEAD_INIT(NULL,0) "executor.Executor", //tp_name sizeof(PyExecutorObject), //tp_basicsize 0, //tp_itemsize @@ -298,7 +310,7 @@ static int Executor_Init( PyExecutorObject* self, PyObject* args, PyObject* kwds //============================================================================ static void Executor_Dealloc( PyExecutorObject* self ) { - self->ob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ @@ -725,7 +737,11 @@ static PyObject* Executor_SetUserAction( PyObject* self, PyObject* args ) DEBUG("[EXECPY] Set user action"); PyObject* funcObj = PyTuple_GetItem(args,0); std::string label = PYSTR(PyTuple_GetItem(args, 1)); +#if PY_MAJOR_VERSION >= 3 + std::string funcName = PYSTR( ((PyFunctionObject*)funcObj)->func_name ); +#else std::string funcName = PYSTR( PyObject_GetAttrString( funcObj, "func_name" ) ); +#endif PyObject* configObj = PyTuple_GetItem(args,2); unsigned int severity = LanguageConstants::INFORMATION; SPELLpyHandle pySev = SSTRPY(LanguageModifiers::Severity); @@ -808,7 +824,7 @@ static PyObject* Executor_SetStep( PyObject* self, PyObject* args ) PyObject* idObj = PyTuple_GetItem(args,0); PyObject* descObj = PyTuple_GetItem(args,1); - SPELLexecutor::instance().displayStage( PYSSTR(idObj), PYSSTR(descObj) ); + SPELLexecutor::instance().stageReached( PYSSTR(idObj), PYSSTR(descObj) ); Py_RETURN_NONE; } @@ -835,6 +851,34 @@ static PyObject* Executor_SetExecutionDelay( PyObject* self, PyObject* args ) Py_RETURN_NONE; } +//============================================================================ +// FUNCTION : Executor_SetByStep +//============================================================================ +static PyObject* Executor_SetByStep( PyObject* self, PyObject* args ) +{ + DEBUG("[EXECPY] Set ByStep configuration"); + + PyObject* byStep = PyTuple_GetItem(args,0); + SPELLexecutor::instance().setByStep(PyObject_IsTrue(byStep)); + + Py_RETURN_NONE; +} + +//============================================================================ +// FUNCTION : Executor_SetExecutionDelay +//============================================================================ +static PyObject* Executor_GetByStep( PyObject* self, PyObject* args ) +{ + DEBUG("[EXECPY] Get ByStep configuration"); + + if (SPELLexecutor::instance().getConfiguration().isByStep()){ + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } + +} + //============================================================================ // FUNCTION : Executor_GetControllingHost //============================================================================ diff --git a/lib/SPELL_EXC/src/SPELLexecutorUtils.C b/lib/SPELL_EXC/src/SPELLexecutorUtils.C index 7d401df..0fc863b 100644 --- a/lib/SPELL_EXC/src/SPELLexecutorUtils.C +++ b/lib/SPELL_EXC/src/SPELLexecutorUtils.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor utilities // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLframeManager.C b/lib/SPELL_EXC/src/SPELLframeManager.C index c92a60a..a29c5e8 100644 --- a/lib/SPELL_EXC/src/SPELLframeManager.C +++ b/lib/SPELL_EXC/src/SPELLframeManager.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the Python frame manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -46,6 +46,7 @@ //============================================================================= SPELLframeManager::SPELLframeManager() : SPELLdispatchListener(), + m_resourceMonitor(new SPELLresourceChangeListener()), m_modelMap() { m_warmStart = NULL; @@ -56,6 +57,8 @@ SPELLframeManager::SPELLframeManager() m_model = NULL; m_filename = ""; m_definitions = NULL; + m_inError = false; + m_terminated = false; } //============================================================================= @@ -88,6 +91,7 @@ void SPELLframeManager::initialize( const std::string& scriptFile ) // Enable or disable monitoring according to configuration SPELLvariableMonitor::s_enabled = SPELLexecutor::instance().getConfiguration().isWatchEnabled(); + SPELLresourceMonitor::s_enabled = SPELLexecutor::instance().getConfiguration().isResourcesDisplayEnabled(); // Compile the script and create the Python frame // to execute bytecode @@ -242,8 +246,8 @@ void SPELLframeManager::createInitialFrame() Py_XDECREF(m_currentFrame); m_currentFrame = NULL; } - - updateCurrentFrame( m_initialFrame, true ); + m_currentFrame = m_initialFrame; + //updateCurrentFrame( m_initialFrame, true ); DEBUG("[EF] Initial frame ready"); } @@ -305,7 +309,7 @@ void SPELLframeManager::terminate() if (!m_terminated) { DEBUG("[EF] Terminating execution"); - SPELLpythonHelper::instance().acquireGIL(); + SPELLsafePythonOperations ops("SPELLframeManager::terminate"); // Note: we substract 3 bytes since the last two instructions are always // resembling a "return None" statement. We want the instruction previous // to the last one here. @@ -316,9 +320,16 @@ void SPELLframeManager::terminate() int lasti = it->second->getLastAddress() -3 ; int lineno = it->second->getLastLine(); DEBUG("[EF] Setting lasti " + ISTR(lasti) + " lineno " + ISTR(lineno) + " on " + PYCREPR(frame)); - SPELLpythonHelper::instance().setNewLine(frame,lineno,lasti); - DEBUG("Frame stack top " + PSTR(frame->f_stacktop)); - DEBUG("Frame value stack " + PSTR(frame->f_valuestack)); + try + { + SPELLpythonHelper::instance().setNewLine(frame,lineno,lasti); + DEBUG("Frame stack top " + PSTR(frame->f_stacktop)); + DEBUG("Frame value stack " + PSTR(frame->f_valuestack)); + } + catch(SPELLcoreException& ex) + { + LOG_ERROR("Unable to set lasti in frame " + PYCREPR(frame)); + } } m_terminated = true; DEBUG("[EF] Terminating execution finished"); @@ -338,6 +349,7 @@ const SPELLexecutionResult SPELLframeManager::execute() while(frame!= NULL) { DEBUG("[EF] Running frame " + PYCREPR(frame)); + SPELLpythonHelper::instance().checkError(); PyEval_EvalFrame( frame ); DEBUG("[EF] Frame finished " + PYCREPR(frame)); DEBUG("[EF] Next frame " + PYCREPR(frame)); @@ -543,7 +555,14 @@ const bool SPELLframeManager::goNextLine() else { DEBUG("[F] Go next line " + ISTR(new_lineno) + " at " + ISTR(new_lasti)); - controllerContinue = setNewLine( new_lineno, new_lasti ); + try + { + controllerContinue = setNewLine( new_lineno, new_lasti ); + } + catch (SPELLcoreException& ex) + { + controllerContinue = false; + } } } @@ -586,7 +605,24 @@ const bool SPELLframeManager::goLine( const int& new_lineno, bool report ) { SPELLsafePythonOperations ops("SPELLframeManager::goLine()"); DEBUG("[F] Go-to line " + ISTR(new_lineno) + " on model " + PSTR(m_model)); +#if PY_MAJOR_VERSION >= 3 + bool result = false; + try + { + result = setNewLine( new_lineno, 0 ); + DEBUG("[F] Go new line " + ISTR(new_lineno)); + if (report) + { + SPELLexecutor::instance().getCIF().write("Jump to line " + ISTR(new_lineno), LanguageConstants::SCOPE_SYS ); + } + } + catch(SPELLcoreException& ex) + { + SPELLexecutor::instance().getCIF().warning("Unable to go to line " + ISTR(new_lineno) + ", " + ex.what(), LanguageConstants::SCOPE_SYS ); + } + return result; +#else // We cannot jump in the middle of a block if (m_ast.isInsideBlock(new_lineno)) { @@ -610,7 +646,7 @@ const bool SPELLframeManager::goLine( const int& new_lineno, bool report ) } // We cannot jump inside blocks - bool inTry = getModel().isInTryBlock(new_lineno); + /*bool inTry = getModel().isInTryBlock(new_lineno); bool inExc = getModel().isInExceptBlock(new_lineno); bool inFin = getModel().isInFinallyBlock(new_lineno); if (inTry | inExc | inFin ) @@ -621,7 +657,7 @@ const bool SPELLframeManager::goLine( const int& new_lineno, bool report ) SPELLexecutor::instance().getCIF().warning("Unable to go to line " + ISTR(new_lineno), LanguageConstants::SCOPE_SYS ); } return false; - } + }*/ int new_lasti = getModel().offset(new_lineno); if ( new_lasti == -1 ) @@ -650,6 +686,7 @@ const bool SPELLframeManager::goLine( const int& new_lineno, bool report ) } return result; +#endif } //============================================================================= @@ -690,6 +727,8 @@ void SPELLframeManager::runScript( const std::string& script ) SPELLpythonHelper::instance().checkError(); // See model update its information getModel().update(); + // Disable local resource analyze due to performance loss + //getResourceMonitor().analyze(); DEBUG("[EF] Executing script OUT"); } catch (SPELLcoreException& ex) @@ -769,8 +808,10 @@ void SPELLframeManager::callbackEventLine( PyFrameObject* frame, const std::stri m_warmStart->notifyLine(); } } - // See model update its information (including variable monitor if enabled) + // See model update its information (including variable/resource monitor if enabled) getModel().update(); + // Disable local resource analyze due to performance loss + //getResourceMonitor().analyze(); DEBUG("[EF] Reset error mode"); m_inError = false; @@ -964,12 +1005,13 @@ void SPELLframeManager::copyDatabase( const std::string& database, PyFrameObject if (db == NULL) { // New reference - db = SPELLpythonHelper::instance().getObject("__main__", database); + db = SPELLpythonHelper::instance().getObject(BUILTINS, database); } if (db) { DEBUG("[EF] Copy database now"); Py_INCREF(db); + Py_INCREF(db); PyDict_SetItemString(toFrame->f_globals, database.c_str(), db); PyDict_SetItemString(toFrame->f_locals, database.c_str(), db); } @@ -977,6 +1019,7 @@ void SPELLframeManager::copyDatabase( const std::string& database, PyFrameObject { LOG_ERROR("Unable to copy database reference: " + database + " on " + PYCREPR(toFrame)); } + SPELLpythonHelper::instance().checkError(); } //============================================================================= @@ -1086,6 +1129,8 @@ void SPELLframeManager::createFrameModel( int callLine, PyFrameObject* frame ) // Initialize the variable monitor m_model->getVariableMonitor().initialize(); + // Initialize the resource monitor + getResourceMonitor().initialize(); m_modelMap.insert( std::make_pair( code_id, m_model )); diff --git a/lib/SPELL_EXC/src/SPELLgoto.C b/lib/SPELL_EXC/src/SPELLgoto.C index 19ef47a..7c0fae9 100644 --- a/lib/SPELL_EXC/src/SPELLgoto.C +++ b/lib/SPELL_EXC/src/SPELLgoto.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the goto mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -35,10 +35,21 @@ // Macros for accessing opcodes +#if PY_MAJOR_VERSION >= 3 +#define INSTR_OFFSET() \ + (sizeof(_Py_CODEUNIT) * (int)(next_instr - first_instr)) +#define NEXTOPARG() do { \ + _Py_CODEUNIT word = *next_instr; \ + opcode = _Py_OPCODE(word); \ + oparg = _Py_OPARG(word); \ + next_instr++; \ + } while (0) + +#else #define NEXTOP() (*next_instr++) #define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2]) #define INSTR_OFFSET() ((int)(next_instr - first_instr)) - +#endif static const std::string STEP_CALL("Step"); static const std::string GOTO_CALL("Goto"); @@ -84,19 +95,25 @@ void SPELLgoto::analyze() // Assume there is no INIT step m_initLine = -1; // Pointer to initial instruction (used by macros) - unsigned char* first_instr = (unsigned char*) PyString_AS_STRING(m_code->co_code); +#if PY_MAJOR_VERSION >= 3 + _Py_CODEUNIT* first_instr = (_Py_CODEUNIT*) PyBytes_AsString(m_code->co_code); + // Size of the code to analyze + const unsigned int code_size = PyBytes_Size(m_code->co_code); +#else + _Py_CODEUNIT* first_instr = (_Py_CODEUNIT*) PyString_AsString(m_code->co_code); // Size of the code to analyze const unsigned int code_size = PyString_Size(m_code->co_code); +#endif // Pointer to current instruction (used by macros) - register unsigned char* next_instr = first_instr; + register _Py_CODEUNIT* next_instr = first_instr; // Holds the current line unsigned int lineno; // Holds the current instruction offset register unsigned int offset; // Holds the current opcode - register unsigned int opcode; + register int opcode; // Opcode argument - register unsigned int oparg; + register int oparg; // Holds the last loaded name std::string loaded_name,loaded_const = ""; @@ -105,22 +122,38 @@ void SPELLgoto::analyze() // Hold the goto information std::string step_id,step_title,goto_id = ""; register unsigned short const1 = 1; - +#if PY_MAJOR_VERSION >= 3 + int extendedArg = 0; +#endif offset = INSTR_OFFSET(); while (offset < code_size) { +#if PY_MAJOR_VERSION >= 3 + NEXTOPARG(); +#else // Obtain the opcode opcode = NEXTOP(); // Get the opcode argument oparg = 0; if (HAS_ARG(opcode)) oparg = NEXTARG(); - +#endif switch(opcode) { +#if PY_MAJOR_VERSION >= 3 + case EXTENDED_ARG: + { + extendedArg = (extendedArg << 8) + oparg; + break; + } +#endif case LOAD_NAME: case LOAD_GLOBAL: { +#if PY_MAJOR_VERSION >= 3 + oparg = oparg + (extendedArg << 8); + extendedArg = 0; +#endif loaded_name = PYSTR(PyTuple_GetItem(m_code->co_names,oparg)); if (loaded_name == STEP_CALL) { @@ -138,6 +171,10 @@ void SPELLgoto::analyze() } case LOAD_CONST: { +#if PY_MAJOR_VERSION >= 3 + oparg = oparg + (extendedArg << 8); + extendedArg = 0; +#endif PyObject* pyConst = PyTuple_GetItem(m_code->co_consts,oparg); if (pyConst != Py_None) { @@ -162,7 +199,10 @@ void SPELLgoto::analyze() } case CALL_FUNCTION: { - if (loaded_name == STEP_CALL) +#if PY_MAJOR_VERSION >= 3 + extendedArg = 0; +#endif + if (loaded_name == STEP_CALL) { // Get the corresponding script line lineno = PyCode_Addr2Line(m_code, offset); @@ -186,6 +226,13 @@ void SPELLgoto::analyze() const1 = 1; break; } + default: + { +#if PY_MAJOR_VERSION >= 3 + extendedArg = 0; +#endif + break; + } }// End switch // // Inform about errors, but ignore them at this analysis diff --git a/lib/SPELL_EXC/src/SPELLgotoPython.C b/lib/SPELL_EXC/src/SPELLgotoPython.C index 0ca7caf..eae7813 100644 --- a/lib/SPELL_EXC/src/SPELLgotoPython.C +++ b/lib/SPELL_EXC/src/SPELLgotoPython.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the goto Python bindings // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -80,8 +80,7 @@ static PyMethodDef Goto_Methods[] = //============================================================================ static PyTypeObject Goto_Type = { - PyObject_HEAD_INIT(NULL) - 0, //ob_size + PyVarObject_HEAD_INIT(NULL,0) "executor.Goto", //tp_name sizeof(PyGotoObject), //tp_basicsize 0, //tp_itemsize @@ -135,7 +134,7 @@ static int Goto_Init( PyGotoObject* self, PyObject* args, PyObject* kwds ) //============================================================================ static void Goto_Dealloc( PyGotoObject* self ) { - self->ob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ diff --git a/lib/SPELL_EXC/src/SPELLimportChecker.C b/lib/SPELL_EXC/src/SPELLimportChecker.C index 04cdb52..7f8c5ee 100644 --- a/lib/SPELL_EXC/src/SPELLimportChecker.C +++ b/lib/SPELL_EXC/src/SPELLimportChecker.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the import detector // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLinterpreter.C b/lib/SPELL_EXC/src/SPELLinterpreter.C index 27d4d36..d7f5408 100644 --- a/lib/SPELL_EXC/src/SPELLinterpreter.C +++ b/lib/SPELL_EXC/src/SPELLinterpreter.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the custom interpreter // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -161,6 +161,7 @@ void SPELLinterpreter::mainLoop() // Create and connect all execution control objects if (prepareObjects()) { + SPELLsafePythonOperations ops("Executor execute"); // Now try to initialize (compile) the execution frame. if (prepareExecution()) { @@ -346,7 +347,7 @@ const bool SPELLinterpreter::prepareObjects() { DEBUG(" Initializing Python interface"); SPELLpythonHelper::instance().initialize(); - + SPELLsafePythonOperations ops("Executor Init"); // Install log support asap Log_Install(); @@ -377,6 +378,8 @@ const bool SPELLinterpreter::prepareObjects() m_callstack = new SPELLcallstack(); // Create and initialize the execution frame m_frameManager = new SPELLframeManager(); + + DEBUG(" Initializing executor"); // Setup the CIF now try @@ -391,10 +394,10 @@ const bool SPELLinterpreter::prepareObjects() ::exit(EIO); } - DEBUG(" Initializing executor"); // Initialize the executor with the objects m_executor->initialize(m_cif, m_controller, m_scheduler, m_callstack, m_frameManager); + // Prepare and configure warm start mechanism now DEBUG(" Preparing warm start"); prepareWarmStart( ctxConfig ); diff --git a/lib/SPELL_EXC/src/SPELLlnotab.C b/lib/SPELL_EXC/src/SPELLlnotab.C index 18c6038..dec7e41 100644 --- a/lib/SPELL_EXC/src/SPELLlnotab.C +++ b/lib/SPELL_EXC/src/SPELLlnotab.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the LNotab analyzer // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLresourceManager.C b/lib/SPELL_EXC/src/SPELLresourceManager.C new file mode 100644 index 0000000..611f41a --- /dev/null +++ b/lib/SPELL_EXC/src/SPELLresourceManager.C @@ -0,0 +1,190 @@ +// ################################################################################ +// FILE : SPELLresourceManager.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the procedure resource manager +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +// Local includes ---------------------------------------------------------- +#include "SPELL_EXC/SPELLresourceManager.H" +#include "SPELL_EXC/SPELLexecutor.H" +#include "SPELL_EXC/SPELLexecutorUtils.H" +#include "SPELL_EXC/SPELLcommand.H" +// Project includes -------------------------------------------------------- +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLpythonHelper.H" + +// GLOBALS //////////////////////////////////////////////////////////////////// + +//============================================================================= +// CONSTRUCTOR : SPELLresourceManager::SPELLresourceManager() +//============================================================================= +SPELLresourceManager::SPELLresourceManager( SPELLframeManager& frame ) +: m_frameManager(frame), +m_changeResourceQueue(5) +{ + DEBUG("[RMGR] Created"); +} + +//============================================================================= +// DESTRUCTOR: SPELLresourceManager::~SPELLresourceManager() +//============================================================================= +SPELLresourceManager::~SPELLresourceManager() +{ + DEBUG("[RMGR] Destroyed"); +} + +//============================================================================= +// METHOD : SPELLresourceManager::setEnabled() +//============================================================================= +void SPELLresourceManager::setEnabled( bool enabled ) +{ + SPELLresourceMonitor::s_enabled = enabled; + LOG_INFO("[RMGR] Display of resources enabled: " + BSTR(enabled) ); +} + +//============================================================================= +// METHOD : SPELLresourceManager::setEnabled() +//============================================================================= +bool SPELLresourceManager::isEnabled() +{ + return SPELLresourceMonitor::s_enabled; +} + +//============================================================================= +// METHOD : SPELLresourceManager::getResources() +//============================================================================= +void SPELLresourceManager::getResources() +{ + DEBUG("[RMGR] Retrieve all resources"); + + if(isStatusValid()) + { + ExecutorCommand cmd; + cmd.id = CMD_RESOURCES; + cmd.arg = RESOURCE_MONITOR_GET_RESOURCES; + + // Call through controller + SPELLexecutor::instance().command(cmd, false); + } + else + { + SPELLexecutorStatus st = SPELLexecutor::instance().getStatus(); + std::string status = SPELLexecutorUtils::statusToString(st); + LOG_WARN("[RMGR] Status is not valid for resource analysis: " + status); + } +} + +//============================================================================= +// METHOD : SPELLresourceManager::analyze() +//============================================================================= +void SPELLresourceManager::analyze() +{ + m_frameManager.getResourceMonitor().analyze(); +} + + +//============================================================================= +// METHOD : SPELLresourceManager::changeResource() +//============================================================================= +void SPELLresourceManager::changeResource( SPELLresourceInfo& resource ) +{ + DEBUG("[RMGR] Change resource " + resource.resourceName); + + if(isStatusValid()) + { + try + { + ExecutorCommand cmd; + cmd.id = CMD_RESOURCES; + cmd.arg = RESOURCE_MONITOR_CHANGE_RESOURCE; + + m_changeResourceQueue.push(resource); + // Call through controller + SPELLexecutor::instance().command(cmd, false); + + LOG_INFO("[RMGR] Resource modification submitted: " + + resource.resourceName + ": globalValue = " + + resource.resourceGlobalValue + + ", localValue = " + resource.resourceLocalValue); + } + catch( SPELLcoreException& ex ) + { + LOG_ERROR("[RMGR] Unable to assign resource value: " + ex.what()); + } + } + else + { + SPELLexecutorStatus st = SPELLexecutor::instance().getStatus(); + std::string status = SPELLexecutorUtils::statusToString(st); + LOG_WARN("[RMGR] Status is not valid for resource analysis: " + status); + } +} + +void SPELLresourceManager::callResourceMonitorFromClient(std::string monitorTask) +{ + if (monitorTask == RESOURCE_MONITOR_CHANGE_RESOURCE) + { + SPELLresourceInfo resource = m_changeResourceQueue.pull(); + m_frameManager.getResourceMonitor().changeResource(resource); + } + else if (monitorTask == RESOURCE_MONITOR_GET_RESOURCES) + { + m_frameManager.getResourceMonitor().getResources(); + } + else + { + LOG_ERROR("[RMGR] Invalid monitorTask in resource manager"); + } +} + +//============================================================================= +// METHOD : SPELLresourceManager::isStatusValid() +//============================================================================= +bool SPELLresourceManager::isStatusValid() +{ + bool valid = false; + if (m_frameManager.isReady()) + { + SPELLexecutorStatus st = SPELLexecutor::instance().getStatus(); + switch(st) + { + case STATUS_PAUSED: + case STATUS_WAITING: + case STATUS_PROMPT: + case STATUS_FINISHED: + case STATUS_INTERRUPTED: + case STATUS_ABORTED: + valid = true; + break; + default: + break; + } + } + else + { + LOG_WARN("[RMGR] Frame manager is not ready for resource analysis"); + } + return valid; +} diff --git a/lib/SPELL_EXC/src/SPELLresourceMonitor.C b/lib/SPELL_EXC/src/SPELLresourceMonitor.C new file mode 100644 index 0000000..b84ae05 --- /dev/null +++ b/lib/SPELL_EXC/src/SPELLresourceMonitor.C @@ -0,0 +1,474 @@ +// ################################################################################ +// FILE : SPELLresourceMonitor.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the procedure resource monitor +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +// Local includes ---------------------------------------------------------- +#include "SPELL_EXC/SPELLresourceMonitor.H" +#include "SPELL_EXC/SPELLexecutor.H" +// Project includes -------------------------------------------------------- +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLutils.H" +#include "SPELL_WRP/SPELLconstants.H" +#include "SPELL_UTIL/SPELLpythonMonitors.H" +#include "SPELL_WRP/SPELLpyHandle.H" + +// GLOBALS //////////////////////////////////////////////////////////////////// +#define EMPTY_STRING "" + +bool SPELLresourceMonitor::s_enabled = false; + +//============================================================================= +// CONSTRUCTOR : SPELLresourceMonitor::SPELLresourceMonitor +//============================================================================= +SPELLresourceMonitor::SPELLresourceMonitor( SPELLresourceChangeListener* listener) +: m_listener(listener) +{ + DEBUG("[RD] Created resource monitor"); + m_initialized = false; +} + +//============================================================================= +// DESTRUCTOR : SPELLresourceMonitor::~SPELLresourceMonitor +//============================================================================= +SPELLresourceMonitor::~SPELLresourceMonitor() +{ + delete m_listener; + // Do not delete! borrowed reference + m_listener = NULL; + m_resources.clear(); + DEBUG("[RD] Destroyed"); +} + +//============================================================================= +// METHOD: SPELLresourceMonitor::retrieveResources() +//============================================================================= +void SPELLresourceMonitor::retrieveResources( ResourceMap &resultingMap, bool onlyLocal ) +{ + + resultingMap.clear(); + + SPELLsafePythonOperations ops("SPELLresourceMonitor::retrieveResources()"); + // Retrieve the resources + + for (long isLocal=0; isLocal<=1; ++isLocal) + { + if(isLocal) + { + if (!SPELLexecutor::instance().getConfiguration().isLocalResourcesSupported()) + { + continue; + } + } + else + { + if (onlyLocal) + { + continue; + } + } + + DEBUG("[RD] Get resources from procedure, with 'IsLocal' = " + BSTR(bool(isLocal))); + + PyObject* pyIsLocal = PyBool_FromLong(isLocal); + PyObject* dict = SPELLpythonHelper::instance().callFunction("spell.utils.resources_utils", "getResourcesUtil", pyIsLocal, NULL); + /*PyObject* args = PyTuple_New(0); + PyObject* kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "IsLocal", pyIsLocal); + PyObject* dict = SPELLpythonHelper::instance().callSpellFunction("GetResources", args, kwargs); + Py_XDECREF(args); + Py_XDECREF(kwargs);*/ + SPELLpythonHelper::instance().checkError(); + Py_XDECREF(pyIsLocal); + + SPELLpyHandle itemList = PyDict_Keys(dict); + unsigned int numItems = PyList_Size(itemList.get()); + for( unsigned int index = 0; index" + //if (value == "") value = EMPTY_STRING; + + if (isLocal) + { + // override previously set value. If not set (when onlyLocal is true), other fields are + // initialized by the default ResourceInfo initializer (called from analyser) + resultingMap[resourceName].resourceLocalValue = value; + } + else + { + std::string gcsName; + std::map::iterator itNM = m_resourceNameMapping.find(resourceName); + if (itNM != m_resourceNameMapping.end()) + { + gcsName = itNM->second; + } + else + { + gcsName = resourceName; + } + + // get the accepted values list + std::map > >::iterator it = m_resourceAcceptedValues.find(resourceName); + // first set the local value to the empty, wil be updated in the second iteration + if (it != m_resourceAcceptedValues.end()) + { + resultingMap.insert( std::make_pair(resourceName, SPELLresourceInfo(resourceName, type, value, "", it->second, gcsName)) ); + } + else + { + resultingMap.insert( std::make_pair(resourceName, SPELLresourceInfo(resourceName, type, value, "", std::vector >(), gcsName)) ); + } + } + + Py_XDECREF(object); + } + } +} + +//============================================================================= +// METHOD: SPELLresourceMonitor::retrieveResourceValueRangeAndNameMap() +//============================================================================= +void SPELLresourceMonitor::retrieveResourceValueRangeAndNameMap() +{ + m_resourceAcceptedValues.clear(); + + SPELLsafePythonOperations ops("SPELLresourceMonitor::retrieveResourceValueRangeAndNameMap()"); + + // Retrieved accepted values lists or resources + PyObject* dict = SPELLpythonHelper::instance().callFunction("spell.utils.resources_utils","getResourceAcceptedValuesUtil",NULL); + SPELLpyHandle itemList = PyDict_Keys(dict); + unsigned int numItems = PyList_Size(itemList.get()); + for( unsigned int index = 0; index > valueVector; + for(Py_ssize_t i = 0; i < PyList_Size(object); i++) { + PyObject *tuple = PyList_GetItem(object, i); + Py_XINCREF(tuple); + PyObject *value1 = PyTuple_GetItem(tuple, 0); + PyObject *value2 = PyTuple_GetItem(tuple, 1); + valueVector.push_back( std::make_pair( PYSSTR( value1 ), PYSSTR( value2 ) ) ); + Py_XDECREF(tuple); + } + Py_XDECREF(object); + + m_resourceAcceptedValues.insert( std::make_pair(resourceName, valueVector )); + } + + m_resourceNameMapping.clear(); + + dict = SPELLpythonHelper::instance().callFunction("spell.utils.resources_utils","getResourceNameMapUtil",NULL); + itemList = PyDict_Keys(dict); + numItems = PyList_Size(itemList.get()); + for( unsigned int index = 0; index allResources; + + SPELLresourceMonitor::ResourceMap::const_iterator it; + for( it = m_resources.begin(); it != m_resources.end(); it++) + { + allResources.push_back(it->second); + } + + m_listener->resourceList( allResources ); +} + +//============================================================================= +// METHOD: SPELLresourceMonitor::changeResource() +//============================================================================= +void SPELLresourceMonitor::changeResource( SPELLresourceInfo& resource ) +{ + SPELLsafePythonOperations ops("SPELLresourceMonitor::changeResource()"); + + DEBUG("[RD] Request changing resource " + resource.resourceName); + + if (!m_initialized) initialize(); + + ResourceMap::iterator it = m_resources.find(resource.resourceName); + + for (long isLocal=0; isLocal<=1; ++isLocal) + { + std::string *resourceVal; + if (isLocal) + { + resourceVal = &(resource.resourceLocalValue); + if (it != m_resources.end() && *resourceVal == it->second.resourceLocalValue) + continue; + } + else + { + resourceVal = &(resource.resourceGlobalValue); + if (it != m_resources.end() && *resourceVal == it->second.resourceGlobalValue) + continue; + } + + // Evaluate the value for the resource + PyObject* value = NULL; + // If resourceValue is empty string, do not change value + if (*resourceVal == "") + { + continue; //value = STRPY(""); + } + else + { + // Build assignment expression. We need to check first, if there + // are double quotes, convert them to single quotes + SPELLutils::replace(*resourceVal, "\"", "'"); + DEBUG("[RD] Evaluating value expression: " + *resourceVal ); + // Check value correctness and evaluate it + value = SSTRPY((*resourceVal)); //SPELLpythonHelper::instance().eval(*resourceVal, false); + } + + *resourceVal = PYSSTR(value); + + DEBUG("[RD] Setting " + resource.resourceName + " to " + PYREPR(value) + " 'IsLocal' is " + BSTR(bool(isLocal))); + + // create args + PyObject* pyIsLocal = PyBool_FromLong(isLocal); + PyObject* pyName = SSTRPY(resource.resourceName); + PyObject* retVal = SPELLpythonHelper::instance().callFunction("spell.utils.resources_utils", "setResourceUtil", pyName, value, pyIsLocal, NULL); + /*PyObject* args = PyTuple_New(2); + PyTuple_SetItem(args, 0, pyName); + PyTuple_SetItem(args, 1, value); + PyObject* kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "IsLocal", pyIsLocal); + // Call set resource + PyObject* retVal = SPELLpythonHelper::instance().callSpellFunction("SetResource", args, kwargs); + // release + Py_XDECREF(args); + Py_XDECREF(kwargs);*/ + SPELLpythonHelper::instance().checkError(); + Py_XDECREF(pyIsLocal); + Py_XDECREF(pyName); + Py_XDECREF(value); + + if ((int) PyInt_AsLong(retVal) != 1) + { + DEBUG("[RD] Setting resource " + resource.resourceName + " to " + (*resourceVal) + " failed. 'IsLocal' is " + BSTR(bool(isLocal))); + // setting resource failed, do nothing + return; + } + + DEBUG("[RD] Setting resource " + resource.resourceName + " to " + (*resourceVal) + " success. 'IsLocal' is " + BSTR(bool(isLocal))); + //if (*resourceVal == "") *resourceVal = EMPTY_STRING; + } + + // Update the resource in the internal model and notify to listeners + if (it != m_resources.end() && (resource.resourceGlobalValue != "" || resource.resourceLocalValue != "")) + { + std::vector changed; + if (resource.resourceGlobalValue != "") + { + it->second.resourceGlobalValue = resource.resourceGlobalValue; + } + if (resource.resourceLocalValue != "") + { + it->second.resourceLocalValue = resource.resourceLocalValue; + } + LOG_INFO("[RD] resource changed by user: " + resource.resourceName + + ", current global value: " + it->second.resourceGlobalValue + + ", current local value " + it->second.resourceLocalValue ); + changed.push_back(it->second); + m_listener->resourceChanged( changed ); + } +} + +//============================================================================= +// METHOD: SPELLresourceMonitor::getResource() +//============================================================================= +void SPELLresourceMonitor::getResource( SPELLresourceInfo& resource ) +{ + if (!m_initialized) initialize(); + ResourceMap::iterator it = m_resources.find(resource.resourceName); + if (it != m_resources.end()) + { + resource.resourceGlobalValue = it->second.resourceGlobalValue; + if (resource.resourceGlobalValue == "") resource.resourceGlobalValue = EMPTY_STRING; + resource.resourceLocalValue = it->second.resourceLocalValue; + if (resource.resourceLocalValue == "") resource.resourceLocalValue = EMPTY_STRING; + resource.resourceType = it->second.resourceType; + } + else + { + resource.resourceGlobalValue = "???"; + resource.resourceLocalValue = "???"; + resource.resourceType = "???"; + } +} + +//============================================================================= +// METHOD: SPELLresourceMonitor::shouldDiscard() +//============================================================================= +bool SPELLresourceMonitor::shouldDiscard( const std::string& resourceName ) +{ + return false; +} + +//============================================================================= +// METHOD: SPELLresourceMonitor::analyze() +//============================================================================= +void SPELLresourceMonitor::analyze() +{ + if (!SPELLresourceMonitor::s_enabled) return; + + if (!m_initialized) initialize(); + + SPELLsafePythonOperations ops("SPELLresourceMonitor::analyze()"); + + DEBUG("[RD] Analyze changes"); + + std::vector changed; + + ResourceMap tempResourceMap; + + // Retrieve local resources + retrieveResources(tempResourceMap, true); + + ResourceMap::iterator it, itKeep; + for(it = tempResourceMap.begin(); it != tempResourceMap.end(); ++it) + { + std::string resourceName = it->first; + //std::cout << resourceName << " -> " << shouldDiscard(resourceName,object) << std::endl; + if (shouldDiscard(resourceName)) continue; + + itKeep = m_resources.find(resourceName); + + // The resource is new + if (itKeep == m_resources.end()) + { + LOG_INFO("[RD] Error: There should be no new global resource, but got '" + resourceName + "'"); + } + // The resource exists, compare values + else + { + bool hasChanged = false; + if (itKeep->second.resourceLocalValue != it->second.resourceLocalValue) + { + LOG_INFO("[RD] Resource local value change: " + resourceName + ", current value: " + it->second.resourceLocalValue + ", previous: " + itKeep->second.resourceLocalValue ); + itKeep->second.resourceLocalValue = it->second.resourceLocalValue; + hasChanged = true; + } + if (hasChanged) + { + changed.push_back(itKeep->second); + } + } + } + + if ( changed.size()>0 ) + { + m_listener->resourceChanged( changed ); + } +} + +//============================================================================= +// METHOD: SPELLresourceChangeListener::resourceChanged() +//============================================================================= +void SPELLresourceChangeListener::resourceChanged( const std::vector& changed ) +{ + if (SPELLresourceMonitor::s_enabled) + { + SPELLexecutor::instance().getCIF().notifyResourceChange( changed ); + } +} + +//============================================================================= +// METHOD: SPELLresourceChangeListener::resourceList() +//============================================================================= +void SPELLresourceChangeListener::resourceList( const std::vector& resources ) +{ + if (SPELLresourceMonitor::s_enabled) + { + SPELLexecutor::instance().getCIF().notifyResourceList( resources ); + } +} diff --git a/lib/SPELL_EXC/src/SPELLscheduler.C b/lib/SPELL_EXC/src/SPELLscheduler.C index 7977a76..f254d6e 100644 --- a/lib/SPELL_EXC/src/SPELLscheduler.C +++ b/lib/SPELL_EXC/src/SPELLscheduler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the executor scheduler // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -60,7 +60,9 @@ SPELLscheduler::SPELLscheduler( bool useSafeCalls ) m_result.reset(); m_silentCheck = false; m_defaultPromptWarningDelay = 30; - + m_abortTimer = false; + m_pyTM = NULL; + m_notificationPeriodIndex = 0; DEBUG("[SCH] Scheduler created"); } @@ -78,26 +80,34 @@ SPELLscheduler::~SPELLscheduler() //============================================================================= void SPELLscheduler::startWait( const SPELLscheduleCondition& condition ) { - DEBUG("[SCH] Starting wait"); + LOG_INFO("Starting wait"); + // If there is a condition already ongoing, cancel it + if (m_condition.type != SPELLscheduleCondition::SCH_NONE) + { + { + SPELLmonitor m(m_checkLock); + finishWaitInternal(false, false); + } + // Wait for the timer to finish otherwise we might cause a deadlock when starting the next timer + if (m_timer != NULL) + { + m_timer->join(); + } + } - // If there is a condition already ongoing, cancel it - if (m_condition.type != SPELLscheduleCondition::SCH_NONE) - { - finishWait(false,false); - } + SPELLmonitor m(m_checkLock); - // Store the condition data m_condition = condition; - DEBUG(" Condition type: " + ISTR(m_condition.type)); - DEBUG(" Target time : " + m_condition.targetTime.toString()); - DEBUG(" Expression : " + m_condition.expression); - DEBUG(" Message : " + m_condition.message); - DEBUG(" Period : " + m_condition.period.toString()); - DEBUG(" Timeout : " + m_condition.timeout.toString()); - DEBUG(" List : " + PYREPR(m_condition.getVerification())); - DEBUG(" Configuration : " + PYREPR(m_condition.getConfig())); - DEBUG(" Prompt user : " + BSTR(m_condition.promptUser)); + LOG_INFO(" Condition type: " + ISTR(m_condition.type)); + LOG_INFO(" Target time : " + m_condition.targetTime.toString()); + LOG_INFO(" Expression : " + m_condition.expression); + LOG_INFO(" Message : " + m_condition.message); + LOG_INFO(" Period : " + m_condition.period.toString()); + LOG_INFO(" Timeout : " + m_condition.timeout.toString()); + LOG_INFO(" List : " + PYREPR(m_condition.getVerification())); + LOG_INFO(" Configuration : " + PYREPR(m_condition.getConfig())); + LOG_INFO(" Prompt user : " + BSTR(m_condition.promptUser)); // Reset filters @@ -191,12 +201,12 @@ void SPELLscheduler::startWait( const SPELLscheduleCondition& condition ) //============================================================================= void SPELLscheduler::startPrompt( const SPELLtime& timeout, bool headless ) { - DEBUG("[SCH] Starting prompt (to: " + timeout.toString() + ")"); + LOG_INFO("Starting prompt (to: " + timeout.toString() + ")"); // If there is a condition already ongoing, cancel it if (m_condition.type != SPELLscheduleCondition::SCH_NONE) { - finishWait(false,false); + finishWaitInternal(false,false); } // Store the condition data @@ -217,6 +227,7 @@ void SPELLscheduler::startPrompt( const SPELLtime& timeout, bool headless ) DEBUG("[SCH] Timeout given from the adapter"); m_condition.timeout = timeout; } + DEBUG("[SCH] Prompt timeout: " + m_condition.timeout.toString()); // Reset filters @@ -281,7 +292,7 @@ void SPELLscheduler::startTimer() { DEBUG("Using default period of 1 second"); SPELLtime defaultPeriod(1,0,true); - m_timer = new SPELLtimer( 200, *this ); + m_timer = new SPELLtimer( 200, *dynamic_cast(this) ); } m_timer->start(); } @@ -300,35 +311,52 @@ bool SPELLscheduler::timerCallback( unsigned long elapsed ) } else { - SPELLsafePythonOperations ops("SPELLscheduler::timerCallback()"); - // Depending on the condition type, we perform one check or another - switch(m_condition.type) - { - case SPELLscheduleCondition::SCH_TIME: - case SPELLscheduleCondition::SCH_PROMPT: - { - abortCheck = checkTime(); - break; - } - case SPELLscheduleCondition::SCH_EXPRESSION: - { - abortCheck = checkExpression(); - break; - } - case SPELLscheduleCondition::SCH_CHILD: - { - abortCheck = checkChildProcedure(); - break; - } - case SPELLscheduleCondition::SCH_VERIFICATION: - { - abortCheck = checkVerification(); - break; - } - default: - break; - } + SPELLtime lockTime; + // We need the check Lock as well otherwise we might deadlock when executing timerCallback and startWait at the same time + do { + //SPELLmonitor m(m_checkLock); + bool locked = m_checkLock.trylock(); + if (!locked) { + SPELLtime currentTime; + SPELLtime diff = currentTime - lockTime; + if (diff.getSeconds() > 5 || m_abortTimer) { + return false; + } + usleep(100000); + continue; + } + + SPELLsafePythonOperations ops("SPELLscheduler::timerCallback()"); + // Depending on the condition type, we perform one check or another + switch(m_condition.type) + { + case SPELLscheduleCondition::SCH_TIME: + case SPELLscheduleCondition::SCH_PROMPT: + { + abortCheck = checkTime(); + break; + } + case SPELLscheduleCondition::SCH_EXPRESSION: + { + abortCheck = checkExpression(); + break; + } + case SPELLscheduleCondition::SCH_CHILD: + { + abortCheck = checkChildProcedure(); + break; + } + case SPELLscheduleCondition::SCH_VERIFICATION: + { + abortCheck = checkVerification(); + break; + } + default: + break; + } + m_checkLock.unlock(); + } while (false); // Periodic notifications with message and interval. We shall not be // aborting, there shall be a defined notification period, a message // to show shall be available and the time since the last notification @@ -339,6 +367,7 @@ bool SPELLscheduler::timerCallback( unsigned long elapsed ) (m_condition.message != "") && (currentTime - m_lastNotificationTime)>=m_notificationPeriod ) { + SPELLsafePythonOperations ops("SPELLscheduler::timerCallback()"); DEBUG("[SCH] Issuing user message"); SPELLexecutor::instance().getCIF().write(m_condition.message, LanguageConstants::SCOPE_PROC ); @@ -378,7 +407,9 @@ void SPELLscheduler::notifyTime( bool finished, bool success ) if (!finished) { SPELLtime currentTime; - std::string remaining = (m_checkTargetTime - currentTime).toString(); + auto diff = (m_checkTargetTime - currentTime); + diff.set(diff.getSeconds(),diff.getMilliseconds(),0); + std::string remaining = diff.toString(); ItemNotification item; item.type = NOTIFY_TIME; item.name = "COUNTDOWN"; @@ -814,7 +845,14 @@ bool SPELLscheduler::interruptWait() //============================================================================= void SPELLscheduler::finishWait( bool setStatus, bool keepLock ) { - SPELLmonitor m(m_checkLock); + finishWaitInternal(setStatus,keepLock); +} + +//============================================================================= +// METHOD : SPELLscheduler::finishWait +//============================================================================= +void SPELLscheduler::finishWaitInternal( bool setStatus, bool keepLock ) +{ if (waiting()) { DEBUG("[SCH] Finish wait status"); @@ -866,7 +904,12 @@ void SPELLscheduler::wait() // This may block the execution for a long time, so we need to allow other Python threads // to kick in SPELLsafeThreadOperations ops("SPELLscheduler::wait()"); + DEBUG("[SCH] Wait on event IN"); m_waitingEvent.wait(); +// if (m_timer != NULL){ +// m_timer->join(); +// } + DEBUG("[SCH] Wait on event OUT"); }; //============================================================================= @@ -997,7 +1040,7 @@ bool SPELLscheduler::waitCondition( std::string condition ) else if (PyDict_Contains( pycond.get(), pyUntil.get() )) { std::string until_time = PYREPR(PyDict_GetItemString( pycond.get(), Until.c_str())); - until_time = "TIME(" + until_time + ").abs()"; + until_time = "long(TIME(" + until_time + ").abs())"; // New reference SPELLpyHandle theTime = SPELLpythonHelper::instance().eval(until_time,false); @@ -1094,4 +1137,17 @@ void SPELLscheduler::setPromptWarningDelay( unsigned int secs ) { LOG_INFO("[SCH] Update prompt warning default delay to " + ISTR(secs) + " seconds"); m_defaultPromptWarningDelay = secs; + // Set Default timeout in case the current condition waits for a Prompt + if (m_condition.type == SPELLscheduleCondition::SCH_PROMPT) + { + m_condition.timeout.set(m_defaultPromptWarningDelay,0); + } +} + +//============================================================================= +// METHOD : SPELLscheduler::raiseWarningEventToGCS() +//============================================================================= +void SPELLscheduler::raiseWarningEventToGCS( const std::string& message ) { + SPELLsafePythonOperations ops("SPELLscheduler::raiseWarningEventToGCS()"); + raiseEvent(message); } diff --git a/lib/SPELL_EXC/src/SPELLserviceImpl.C b/lib/SPELL_EXC/src/SPELLserviceImpl.C new file mode 100644 index 0000000..61db8b1 --- /dev/null +++ b/lib/SPELL_EXC/src/SPELLserviceImpl.C @@ -0,0 +1,1739 @@ +// ################################################################################ +// FILE : SPELLexecutorImpl.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the executor +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +// Local includes ---------------------------------------------------------- +#include "SPELL_EXC/SPELLexecutor.H" +#include "SPELL_EXC/SPELLserviceImpl.H" +#include "SPELL_EXC/SPELLexecutorImpl.H" + +#include "SPELL_EXC/SPELLexecutorUtils.H" +// Project includes -------------------------------------------------------- +#include "SPELL_PRD/SPELLprocedureManager.H" +#include "SPELL_SYN/SPELLmonitor.H" +#include "SPELL_CFG/SPELLconfiguration.H" +#include "SPELL_DTA/SPELLdtaContainer.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLpythonHelper.H" +#include "SPELL_UTIL/SPELLpythonMonitors.H" +#include "SPELL_WRP/SPELLdriverManager.H" +#include "SPELL_WRP/SPELLdatabaseManager.H" +#include "SPELL_WRP/SPELLpyHandle.H" +#include "SPELL_WRP/SPELLregistry.H" +#include "SPELL_WRP/SPELLconstants.H" +#include "SPELL_CFG/SPELLbrowsableLibMode.H" + +using namespace PythonConstants; + +// GLOBALS //////////////////////////////////////////////////////////////////// + +// Bridge for C-API dispatching callback +static int static_dispatch( PyObject* obj, PyFrameObject* frame, int what, PyObject* args ) +{ + return SPELLexecutor::instance().dispatch(obj, frame, what, args); +} + +std::string dispatchDataType( int what ); + +//============================================================================= +// CONSTRUCTOR : SPELLserviceImpl::SPELLserviceImpl +//============================================================================= +SPELLserviceImpl::SPELLserviceImpl() + : SPELLexecutorIF(), + m_importChecker() +{ + m_initialized = false; + m_initStepDone = false; + m_initLines.clear(); + m_cif = NULL; + m_frameManager = NULL; + m_instanceId = ""; + m_parentId = ""; + m_childId = ""; + m_servicePath = ""; + + m_scheduler = NULL; + m_callstack = NULL; + m_controller = NULL; + m_childMgr = NULL; + m_varManager = NULL; + m_resourceManager = NULL; + + m_userAction.reset(); + m_gotoTarget = ""; + + m_childMgr = new SPELLchildManager(); + + DEBUG("[E] SPELLexecutor created"); +} + +//============================================================================= +// DESTRUCTOR : SPELLexecutorImpl::~SPELLexecutorImpl +//============================================================================= +SPELLserviceImpl::~SPELLserviceImpl() +{ + DEBUG("[E] SPELLservice destroyed"); + if (m_childMgr) + { + delete m_childMgr; + } + +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::initialize() +//============================================================================= + +void SPELLserviceImpl::refreshStatus() +{ + if (m_controller != NULL) + { + m_controller->refreshStatus(); + } +} + +void SPELLserviceImpl::initialize( SPELLcif* cif, + SPELLcontrollerIF* controller, + SPELLschedulerIF* scheduler, + SPELLcallstackIF* callstack, + SPELLframeManager* frame ) +{ + assert( cif != NULL ); + assert( controller != NULL ); + assert( scheduler != NULL ); + assert( callstack != NULL ); + assert( frame != NULL ); + m_cif = cif; + m_controller = controller; + m_scheduler = scheduler; + m_callstack = callstack; + m_frameManager = frame; + m_varManager = new SPELLvariableManager(*frame); + m_resourceManager = new SPELLresourceManager(*frame); + + // The order is important here! + addDispatchListener(m_frameManager); + addDispatchListener(m_callstack); + addDispatchListener(m_controller); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::getConfiguration() +//============================================================================= +SPELLexecutorConfig& SPELLserviceImpl::getConfiguration() +{ + if (m_cif != NULL) + { + return m_cif->getExecutorConfig(); + } + return m_emptyConfig; +}; + +//============================================================================= +// METHOD : SPELLexecutorImpl::getStatus() +//============================================================================= +const SPELLexecutorStatus SPELLserviceImpl::getStatus() const +{ + if (m_controller != NULL) + { + return m_controller->getStatus(); + } + return STATUS_UNKNOWN; +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::getInstanceId +//============================================================================= +const std::string SPELLserviceImpl::getInstanceId() const +{ + return m_instanceId; +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::prepare +//============================================================================= +void SPELLserviceImpl::prepare( const std::string& instanceId, const SPELLcontextConfig& ctxConfig ) +{ + assert( m_cif != NULL ); + assert( m_controller != NULL ); + assert( m_scheduler != NULL ); + assert( m_callstack != NULL ); + assert( m_frameManager != NULL ); + + LOG_INFO("[E] Preparing service execution"); + + // Check for Python errors + SPELLpythonHelper::instance().checkError(); + + // See constants.H + // We do this on preparation stage because these values shall not be reset + // on procedure reload. The user may have changed them in the meantime. + if (!m_initialized) + { + m_instanceId = instanceId; + + //Get from CTX Config + m_inputDir = SPELLutils::resolvePath( ctxConfig.getInputDirectory() ); + m_outputDir = SPELLutils::resolvePath( ctxConfig.getOutputDirectory() ); + + // Report the current configuration + LOG_INFO("EXECUTOR CONFIGURATION (" + getInstanceId() + ")"); + LOG_INFO("[E] Headless : " + BSTR(getConfiguration().isHeadless()) ); + LOG_INFO("[E] Parent : " + getConfiguration().getParentProcId() ); + LOG_INFO("[E] Arguments : " + getConfiguration().getArguments() ); + LOG_INFO("[E] Condition : " + getConfiguration().getCondition() ); + LOG_INFO("[E] Automatic mode : " + BSTR( getConfiguration().isAutomatic() )); + LOG_INFO("[E] Visible mode : " + BSTR( getConfiguration().isVisible() )); + LOG_INFO("[E] Blocking mode : " + BSTR( getConfiguration().isBlocking() )); + LOG_INFO("[E] Browsable lib : " + getConfiguration().getBrowsableLibStr() ); + LOG_INFO("[E] TC Confirm : " + BSTR( getConfiguration().isForceTcConfirm() )); + LOG_INFO("[E] Prompt Confirm : " + BSTR( getConfiguration().isForcePromptConfirm() )); + LOG_INFO("[E] Save state mode : " + getConfiguration().getSaveStateMode() ); + LOG_INFO("[E] Watch variables : " + BSTR(getConfiguration().isWatchEnabled()) ); + LOG_INFO("[E] resources display: " + BSTR(getConfiguration().isResourcesDisplayEnabled()) ); + LOG_INFO("[E] Local resource support: " + BSTR(getConfiguration().isLocalResourcesSupported()) ); + LOG_INFO("[E] Input directory : " + m_inputDir ); + LOG_INFO("[E] Output directory : " + m_outputDir ); + LOG_INFO("[E] Run Into : " + BSTR(getConfiguration().isRunInto())); + LOG_INFO("[E] Exec Delay : " + ISTR(getConfiguration().getExecDelay())); + LOG_INFO("[E] Prompt Delay : " + ISTR(getConfiguration().getPromptWarningDelay())); + LOG_INFO("[E] By Step : " + BSTR(getConfiguration().isByStep())); + LOG_INFO("[E] Max Verbosity : " + ISTR(getConfiguration().getMaxVerbosity())); + + m_scheduler->setPromptWarningDelay(getConfiguration().getPromptWarningDelay()); + + m_initialized = true; + } + + // Check that no previous errors are there + SPELLpythonHelper::instance().checkError(); + + // Setup extra environment stuff + // 1. Procedure arguments and internal variables. + // If there are arguments available we need to evaluate + // them in the Python environment and to install them in the execution environment + // via the ARGS and IVARS global objects. + installCallingArguments(); + installInternalVariables(); + + // 2. Process condition and open mode + // If there is a condition available, we set it to the controller. The controller + // will read and evaluate it and hold the execution until the condition is + // fullfilled. + if (getConfiguration().getCondition() != "") + { + m_controller->setCondition( getConfiguration().getCondition() ); + } + + // Reset any user action function previously set + m_userAction.reset(); + + // Configure the initial step over mode in the callstack + if (getConfiguration().isRunInto()==true) + { + m_callstack->stepOver( SO_ALWAYS_INTO ); + } + else + { + m_callstack->stepOver( SO_ALWAYS_OVER ); + } + + LOG_INFO("[E] Executor prepared"); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::installCallingArguments +//============================================================================= +void SPELLserviceImpl::installCallingArguments() +{ + DEBUG("[E] Installing calling arguments"); + + PyObject* argDict = NULL; + if (getConfiguration().getArguments() != "") + { + try + { + // Evaluate the argument string. It is expected to be a Python dictionary. + // No error check is done for this. + argDict = SPELLpythonHelper::instance().eval(getConfiguration().getArguments(),false); + } + catch(SPELLcoreException& ex) + { + m_cif->error( "Unable to install arguments data holder: " + ex.what(), LanguageConstants::SCOPE_SYS ); + argDict = PyDict_New(); + } + } + else + { + // In case of no arguments given, we install an empty Python dictionary. + argDict = PyDict_New(); + } + + + // Initialize now the data container for Calling Arguments + Py_INCREF(argDict); + DEBUG("[E] Argument dictionary: " + PYREPR(argDict)); + PyObject* classObj = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "DataContainer"); + PyObject* argTuple = PyTuple_New(1); + PyObject* argsName = STRPY("Calling Arguments"); + PyTuple_SetItem(argTuple,0,argsName); + Py_INCREF(argsName); + Py_INCREF(argTuple); + PyObject* args = SPELLpythonHelper::instance().newInstance(classObj, argTuple, NULL); + + DEBUG("[E] Calling arguments instance: " + PYREPR(args) + " type: " + PYCREPR(PyObject_Type(args))); + + // Now assign the passed arguments. Disable notifications for DTA + SPELLdtaContainer::setGlobalNotificationsEnabled(false); + SPELLpyHandle argKeys = PyDict_Keys(argDict); + unsigned int numKeys = PyList_Size(argKeys.get()); + for(unsigned int idx = 0; idxreset(); + } + DEBUG("[E] Reset status"); + m_controller->reset(); + m_importChecker.reset(); + // Reset CIF closure lock always + m_cif->resetClose(); + + // Establish initial run-into value now (after reset) + m_controller->enableRunInto( getConfiguration().isRunInto() ); + + // The client will know that the executor is ready to go + // Take into account initialization errors + SPELLexecutorStatus status = m_controller->getStatus(); + LOG_INFO("Initial status check: " + SPELLexecutorUtils::statusToString(status) ); + SPELLexecutionResult result = EXECUTION_UNKNOWN; + if (status != STATUS_ERROR) + { + m_controller->setStatus(STATUS_LOADED); + + DEBUG("[E] Set autorun"); + m_controller->setAutoRun(); + + DEBUG("[E] Launching execution"); + // Execute the procedure/script. This triggers the procedure + // execution under dispatcher control. + //result = m_frameManager->execute(); + + SPELLpyService& service = SPELLprocedureManager::instance().getService(m_instanceId); + + service.start(); + + DEBUG("[E] Execution done, checking result (" + ISTR(result) + ")"); + } + else + { + LOG_ERROR("Initialization error"); + result = EXECUTION_ERROR; + } + + // Check execution result and proceed accordingly. + // Frame will be reset and environment unloaded if needed, depending on the case. + + switch(result) + { + case EXECUTION_ERROR: + { + DEBUG("[E] Result ERROR"); + m_initStepDone = true; + continueExecuting = executorFinishedWithErrors(); + if (continueExecuting) + { + // We will recover, so do not reset entities + resetEntities = false; + } + break; + } + case EXECUTION_SUCCESS: + case EXECUTION_TERMINATED: + { + DEBUG("[E] Result SUCCESS/TERMINATED"); + m_initStepDone = false; + continueExecuting = executorFinishedRight(); + break; + } + case EXECUTION_ABORTED: + { + DEBUG("[E] Result ABORTED"); + m_initStepDone = false; + continueExecuting = executorAborted(); + break; + } + default: + { + DEBUG("[E] Execution result unknown: " + ISTR(result)); + m_initStepDone = false; + unloadDriver(true); + continueExecuting = false; + break; + } + } + } + while(continueExecuting); + + // This may be redundant, but does not harm. + PyEval_SetTrace( NULL, NULL ); + + DEBUG("[E] Execution finished"); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::reloadOrClose +//============================================================================= +bool SPELLserviceImpl::reloadOrClose() +{ + DEBUG("[E] Waiting for CIF closure"); + // Wait the close or reload command from the user + m_cif->waitClose(); + // This tells us if user wants to reload, not close + if (m_controller->shouldReload()) + { + DEBUG("[E] Clear asrun"); + m_cif->clearAsRun(); + DEBUG("[E] Reload driver"); + // We are reloading, load again the execution environment and reset the frame + loadDriver(); + DEBUG("[E] Reset frame"); + m_frameManager->reset(); + DEBUG("[E] Reload environment"); + loadExecutionEnvironment(); + return true; + } + else + { + // Completely unload execution environment if we are not reloading + unloadDriver(true); + return false; + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::executorAborted +//============================================================================= +bool SPELLserviceImpl::executorAborted() +{ + DEBUG("[E] Execution finished due to abort"); + // Cleanup the runtime exception that lead to the abort of the interpretation + SPELLerror::instance().clearErrors(); + // Set the status aborted here, not before. Otherwise, the GUI would be notified + // before the driver actually unloads, and this may take time. + getController().setStatus(STATUS_ABORTED); + // Procedure has aborted, so unload the driver and execution environment right away + unloadDriver(false); + // Wait until the user decides to close or to reload + return reloadOrClose(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::executorFinishedRight +//============================================================================= +bool SPELLserviceImpl::executorFinishedRight() +{ + DEBUG("[E] Service Execution finished successfully"); + // Cleanup the runtime exception that lead to the termination of the interpretation + SPELLerror::instance().clearErrors(); + + // Mark the procedure as finished + m_controller->setFinished(); + + // Procedure has finished, so unload the driver and execution environment right away + unloadDriver(false); + // This call may be misleading but the behavior at this point is the same as the aborted state + return reloadOrClose(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::executorFinishedWithErrors +//============================================================================= +bool SPELLserviceImpl::executorFinishedWithErrors() +{ + DEBUG("[E] Service Execution finished with errors"); + // Will return true if the error was recoverable AND + // the user chooses to recover. + AfterError errorHandlingResult = handleExecutionError(); + bool continueExecuting = false; + + // If the user does not want to (either closing or reloading) + switch(errorHandlingResult) + { + case CANCEL_RECOVER: + { + // This tells us if user wants to reload, not close + if(m_controller->shouldReload()) + { + // If we are reloading, just dont unload the execution environment, reset the + // frame and start over + m_frameManager->reset(); + continueExecuting = true; + } + else + { + // Unload the environment if we dont recover + unloadDriver(true); + } + // Else will close and not reload/recover + break; + } + case RECOVER_SUCCESS: + { + // To re-execute. But do not reset the frame and dont unload the environment. + continueExecuting = true; + break; + } + case RECOVER_FAILED: + case CANNOT_RECOVER: + { + // Unload the environment, could not recover it + unloadDriver(false); + // We will need to wait users choice + DEBUG("[E] Waiting for CIF closure (recovery failed)"); + // Wait the close or reload command from the user + m_cif->resetClose(); + m_cif->waitClose(); + // This may be misleading, but the behavior at this point is the same as aborted + continueExecuting = reloadOrClose(); + break; + } + default: + break; + } + return continueExecuting; +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::save +//============================================================================= +void SPELLserviceImpl::save() +{ + DEBUG("[E] Saving on demand"); + try + { + // Restore the state from persistent file + m_frameManager->saveState(); + } + catch(SPELLcoreException& ex) + { + std::string msg = "Save state failed: " + std::string(ex.what()); + m_cif->notifyError( msg, ex.what(), true); + LOG_ERROR(msg); + } + DEBUG("[E] Saving on demand done"); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::recover +//============================================================================= +void SPELLserviceImpl::recover() +{ + DEBUG("[E] Recovering service execution"); + + try + { + // Load the SPELL driver + loadDriver(); + + // Load the builtin databases, etc. + loadExecutionEnvironment(); + + // Restore the state from persistent file + m_frameManager->restoreState(); + + // Re-create the internal callstack model + m_frameManager->replayStack( m_callstack ); + } + catch(SPELLcoreException& ex) + { + std::string msg = "Recovery failed, could not restore state: " + std::string(ex.what()); + m_cif->notifyError( msg, ex.what(), true); + LOG_ERROR(msg); + PyEval_SetTrace( NULL, NULL ); + DEBUG("[E] Waiting for CIF closure"); + m_cif->waitClose(); + return; + } + DEBUG("[E] Execution recovery finished"); + executeInternal(false); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::finalize +//============================================================================= +void SPELLserviceImpl::finalize() +{ + DEBUG("[E] Finalizing, user request closure"); + // Release the CIF lock, the controller received the close command + // so we can proceed + m_cif->canClose(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::loadExecutionEnvironment +//============================================================================= +void SPELLserviceImpl::loadExecutionEnvironment() +{ + DEBUG("[E] Loading execution environment"); + + // Check for Python errors + SPELLpythonHelper::instance().checkError(); + + // Load SCDB and GDB + SPELLdatabaseManager::instance().loadBuiltinDatabases(); + + // Create proc dictionary object and install it + PyObject* procObj = PyDict_New(); + PyObject* pname = SSTRPY(m_instanceId); + PyObject* arguments = SSTRPY(getConfiguration().getArguments()); + PyObject* outputDataDir = SSTRPY( m_outputDir ); + PyObject* inputDataDir = SSTRPY( m_inputDir ); + PyObject* parentId = SSTRPY( getConfiguration().getParentProcId() ); + + PyDict_SetItemString( procObj, DatabaseConstants::NAME.c_str(), pname); + PyDict_SetItemString( procObj, DatabaseConstants::ARGS.c_str(), arguments); + PyDict_SetItemString( procObj, DatabaseConstants::STEP.c_str(), Py_None); + PyDict_SetItemString( procObj, DatabaseConstants::PREV_STEP.c_str(), Py_None); + PyDict_SetItemString( procObj, DatabaseConstants::OUTPUT_DATA.c_str(), outputDataDir); + PyDict_SetItemString( procObj, DatabaseConstants::INPUT_DATA.c_str(), inputDataDir); + PyDict_SetItemString( procObj, DatabaseConstants::PARENT.c_str(), parentId); + + SPELLpythonHelper::instance().install( procObj, DatabaseConstants::PROC ); + SPELLpythonHelper::instance().checkError(); + + bool success = true; + std::string importErrors = ""; + + if (m_libPath != "") + { + if (m_libPath.find(",") != std::string::npos) + { + std::vector items = SPELLutils::tokenize(m_libPath,","); + std::vector::const_iterator cit; + for(cit = items.begin(); cit != items.end(); cit++) + { + success = success && SPELLpythonHelper::instance().importUserLibraries( *cit, importErrors ); + } + } + else + { + try + { + success = success && SPELLpythonHelper::instance().importUserLibraries( m_libPath, importErrors ); + } + catch(SPELLcoreException& ex) + { + importErrors += "\n - Failed to import user libraries from '" + m_libPath + "': " + ex.what(); + } + } + } + else + { + LOG_INFO("No user libraries defined"); + } + + + if (!success) + { + THROW_EXCEPTION("Initialization failed", "\nErrors detected in UserLib: " + importErrors, SPELL_ERROR_EXECUTION); + } + + // Tell the execution frame that the environment has been updated + m_frameManager->filterDictUpdated(); + + DEBUG("[E] Loading execution environment done"); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::loadDriver +//============================================================================= +void SPELLserviceImpl::loadDriver() +{ + DEBUG("#############################################################"); + DEBUG("[E] Load driver - start"); + + // Check for Python errors + SPELLpythonHelper::instance().checkError(); + + SPELLnoCommandProcessing nc; + + LOG_INFO("Loading driver on context " + getConfiguration().getContextName()); + // Prepare and load the SPELL driver + SPELLdriverManager::instance().setup( getConfiguration().getContextName() ); + + // Enable TC confirmation if so said the config + if (getConfiguration().isForceTcConfirm()) + { + setForceTcConfirmInternal(true); + } + + if (getConfiguration().isForcePromptConfirm()) + { + setForcePromptConfirmInternal(true); + } + + // Load the driver language specifics + SPELLcontextConfig& ctxConfig = SPELLconfiguration::instance().getContext( getConfiguration().getContextName() ); + std::string driverName = ctxConfig.getDriverName(); + SPELLdriverConfig& drvConfig = SPELLconfiguration::instance().getDriver( driverName ); + + std::string path = drvConfig.getPath() + PATH_SEPARATOR + drvConfig.getIdentifier(); + + path = SPELLutils::resolvePath(path); + + DEBUG("[E] Driver files loaded in " + path); + + // Import modifiers + std::string package = ""; + std::string moduleFile = path + PATH_SEPARATOR + "modifiers.py"; + DEBUG("[E] Checking for module " + moduleFile); + if (SPELLutils::isFile( moduleFile )) + { + package = drvConfig.getIdentifier() + ".modifiers"; + DEBUG("[E] Importing driver package " + package); + SPELLpythonHelper::instance().importAllFrom( package ); + } + + // Import constants + moduleFile = path + PATH_SEPARATOR + "constants.py"; + DEBUG("[E] Checking for module " + moduleFile); + if (SPELLutils::isFile( moduleFile )) + { + package = drvConfig.getIdentifier() + ".constants"; + DEBUG("[E] Importing driver package " + package); + SPELLpythonHelper::instance().importAllFrom( package ); + } + + // Import functions + moduleFile = path + PATH_SEPARATOR + "functions.py"; + DEBUG("[E] Checking for module " + moduleFile); + if (SPELLutils::isFile( path + PATH_SEPARATOR + "functions.py" )) + { + package = drvConfig.getIdentifier() + ".functions"; + DEBUG("[E] Importing driver package " + package); + SPELLpythonHelper::instance().importAllFrom( package ); + } + SPELLpythonHelper::instance().checkError(); + + DEBUG("[E] Load driver - end"); + DEBUG("#############################################################"); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::unloadDriver +//============================================================================= +void SPELLserviceImpl::unloadDriver( bool shutdown ) +{ + try + { + DEBUG("[E] Unload driver - start"); + + SPELLnoCommandProcessing nc; + + // Just cleanup driver if reload/recover will be done + SPELLdriverManager::instance().cleanup(shutdown); + + DEBUG("[E] Unload driver - end"); + } + catch(SPELLcoreException& ex) + { + throw ex; + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::handleExecutionError +//============================================================================= +const SPELLserviceImpl::AfterError SPELLserviceImpl::handleExecutionError() +{ + AfterError result = CANNOT_RECOVER; + SPELLcoreException* exc = SPELLerror::instance().getError(); + bool canRestore = m_frameManager->haveWarmStart(); + bool fatalError = exc->isFatal() || (!canRestore); + LOG_ERROR("[E] Execution failed: " + exc->what() + " can restore: " + BSTR(canRestore) + ", fatal: " + BSTR(exc->isFatal())); + + // If the error is inside user library, we do not allow recovery + // to browsable lib ON to show where the error was. + std::string location = SPELLerror::instance().getErrorLocation(); + DEBUG("[E] Error location is " + location); + if ((location != "")&& (m_libPath != "")) + { + if (location.find(m_libPath) == 0) + { + m_controller->setError( "Error happened in user library: " + exc->getError(), exc->getReason(), true ); + return CANNOT_RECOVER; + } + } + + DEBUG("[E] Notify error to controller"); + // Otherwise notify the error normally + m_controller->setError( "Execution aborted: " + exc->getError(), exc->getReason(), fatalError ); + + // If the execution frame has warmstart information + if ( canRestore ) + { + // Wait user request to reload or abort + LOG_INFO("[E] Waiting for recover command"); + m_cif->waitClose(); + // This will tell us if the user wants recovery or not + bool doRecover = m_controller->shouldRecover(); + LOG_INFO("[E] Recovery flag: " + ( doRecover ? STR("enabled") : STR("disabled"))); + DEBUG("Do recover flag: " + BSTR(doRecover)); + if (doRecover) + { + LOG_INFO("[E] Recovering execution"); + m_cif->warning("Recovering execution from failure", LanguageConstants::SCOPE_SYS ); + try + { + try + { + // No commands processed in the meantime + SPELLnoCommandProcessing nc; + // Recover the state in the frame + m_frameManager->fixState(); + // Set the callstack in recovery mode so that + // the next module call event is not processed, and + // therefore add a spurious element to the stack + m_callstack->setRecoveryMode(); + } + catch(SPELLcoreException& ex) + { + throw ex; + } + + // Now re-invoke execution + DEBUG("[E] Re-executing"); + PyErr_Clear(); + result = RECOVER_SUCCESS; + } + catch(SPELLcoreException& ex) + { + std::string msg = "[E] Recovery failed: " + ex.what(); + LOG_ERROR(msg); + DEBUG(msg); + m_cif->notifyError("Recovery failed", ex.what(), true); + result = RECOVER_FAILED; + } + } + else + { + LOG_WARN("[E] Recovery cancelled by user"); + m_cif->warning("Recovery cancelled, procedure will be aborted", LanguageConstants::SCOPE_SYS ); + result = CANCEL_RECOVER; + } + } + else + { + LOG_ERROR("Recovery failed, warm start mechanism disabled"); + m_cif->notifyError("Recovery failed", "Warm start mechanism disabled", true); + // result is already CANNOT_RECOVER + } + return result; +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::dispatch +//============================================================================= +int SPELLserviceImpl::dispatch( PyObject* obj, PyFrameObject* frame, int what, PyObject* args ) +{ + //SPELLmonitor m(m_dspLock); + + // Do not dispatch if the notified code is not a procedure + std::string file = PYSTR(frame->f_code->co_filename); + + //DEBUG("[DISPATCH] Processing file '" + file + "'") + //DEBUG("[DISPATCH] Proc path: '" + m_procPath + "'") + //DEBUG("[DISPATCH] Lib path: '" + m_libPath + "'") + + bool notProc = (file.find(m_servicePath) == std::string::npos); + bool notUserLib = true; + if (notProc) + { + notUserLib = (m_libPath == "") || (file.find(m_libPath) == std::string::npos); + if (notUserLib) return 0; + } + + // Filter importing state + std::string name = PYSTR(frame->f_code->co_name); + // Do not dispatch if the interpreter is importing a file + if (m_importChecker.isImporting(what,file,frame->f_lineno,name)) return 0; + + // Extract the rest of information + std::string path = PYSTR(frame->f_code->co_filename); + + // Will provide procedure or user library id + std::string procId = this->m_instanceId; + + int lineno = frame->f_lineno; + std::string etype = dispatchDataType(what); + + //DEBUG("[DISPATCH] START Dispatch event in " + procId + ":" + ISTR(lineno)); + //DEBUG(" (" + name + ") at " + PYCREPR(frame)); + //DEBUG(" event type " + etype); +// std::cerr << "################################################################################" << std::endl; +// std::cerr << "[DISPATCH] Dispatch event in " + procId + ":" + ISTR(lineno) + " (" + name + ") at " + PYCREPR(frame) << std::endl; +// std::cerr << "################################################################################" << std::endl; + + // Notify the frame manager to update the frame. This way, the internal models are + // created/updated at the proper time following the procedure execution. This call + // must be done before any other call to the frame manager that makes use of the + // 'procedure execution model object', because it is first created at this point. + m_frameManager->updateCurrentFrame(frame, what ); + + // INIT step feature + // IMPORTANT for this first if, there is no frame model until the first CALL dispatch + // has been processed. So we cannot use getModel() until then. That is why we have + // first the check to be PyTrace_LINE. + if (!m_initStepDone && + what == PyTrace_LINE && + m_frameManager->isAtInitialFrame() && + m_frameManager->getModel().hasInitStep()) + { + getCIF().disableNotifications(); + + if (checkInitStep(lineno)) + { + m_initLines.push_back(lineno); + return 0; + } + else + { + LOG_INFO("INIT step mode finished"); + // Use the callstack to notify the executed lines during INIT step, all together, + // to the controlling client. We do not care about dispatch and control during + // init mode, but we want to mark the appropriate lines as executed. + std::list::const_iterator it; + for( it = m_initLines.begin(); it != m_initLines.end(); it++ ) + { + getCallstack().callbackEventLine(frame, procId, (*it), name); + } + m_initLines.clear(); + + // Re-enable notifications once INIT step is reached + getCIF().enableNotifications(); + } + } + + // Browsable lib feature: if the flag is enabled, allow browsing inside the user library. + // this means that dispatch shall continue when notUserLib is false --> we make it true. + notUserLib = notUserLib | (getConfiguration().getBrowsableLib()==ON); + + // By-step feature: if enabled, pause on each Step statement + // Note that checkByStep cannot be used on the very first CALL notification + // as the current SPELLexecutionModel is not created yet, therefore there would + // be a segmentation fault. + if ( (what == PyTrace_LINE) && getConfiguration().isByStep()) checkByStep(lineno); + + // Breakpoint feature: pause on the breakpoints + checkBreakpoint(procId,lineno); + + // Hold the dispatching mechanism if there are commmands to be processed, + // and until the command finishes + { + SPELLsafeThreadOperations ops("SPELLexecutorImpl::dispatch()"); + m_controller->waitCommand(); + } + + // Repeat flag is used for certain cases of skip mechanism. + bool repeat = true; + // Will be false if the execution has been aborted (the controller knows this) + // if the execution has been aborted, dispatching wont be done in control objects below. + bool statusOk = true; + while(repeat) + { + // Check aborted state beforehand + statusOk = m_controller->checkAborted(); + repeat = false; + + // Here is the in-language goto mechanism implementation. Whenever the current line is + // a line with a programmed goto (there is a target line in the Goto model) the frame + // lineno will be changed accordingly. + if (m_gotoTarget != "") + { + try + { + repeat = repeat || m_frameManager->goLabel(m_gotoTarget, false, true); + lineno = frame->f_lineno; + m_gotoTarget = ""; + } + catch(SPELLcoreException& ex) + { + m_gotoTarget = ""; + abort(ex.what(),true); + statusOk = false; + } + } + + // If not aborted and not in User library, perform the data dispatch to each control object + if (statusOk && notUserLib) + { + //DEBUG("[DISPATCH] Will do dispatch"); + switch(what) + { + case PyTrace_EXCEPTION: + { + DEBUG("[DISPATCH] Exception " + procId + ":" + ISTR(lineno) ); + DEBUG("[DISPATCH] Args: " + PYREPR(args) ); + DEBUG("[DISPATCH] Going to error state"); + + notifyErrorEvent( frame, procId, lineno, name ); + + if ( processException( args, lineno ) ) + { + DEBUG("[DISPATCH] Exception is SPELL"); + return 0; + } + + DEBUG("[DISPATCH] Python exception"); + statusOk = false; + break; + } + case PyTrace_LINE: + { + notifyLineEvent( frame, procId, lineno, name ); + break; + } + case PyTrace_CALL: + { + // No Call/Return events for Services ar necessary + if (m_frameManager->isAtInitialFrame()) + notifyCallEvent( frame, procId, lineno, name ); + break; + } + case PyTrace_RETURN: + { + // No Call/Return events for Services ar necessary + if (m_frameManager->isAtInitialFrame()) + notifyReturnEvent( frame, procId, lineno, name ); + break; + } + default: + LOG_ERROR("[DISPATCH] Uncontrolled event " + procId + ":" + ISTR(lineno) ); + break; + } + } + lineno = frame->f_lineno; + repeat = m_controller->shallRepeat(); + } + + // If we are terminating/aborting the execution, tell the frame to move to the end of + // the bytecode. This way we guarantee nothing will be executed. + if(!m_controller->checkAborted()) + { + m_frameManager->terminate(); + return -1; + } + + return 0; +// DEBUG("[DISPATCH] EXIT dispatch event in " + procId + ":" + ISTR(frame->f_lineno)); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::processException +//============================================================================= +bool SPELLserviceImpl::processException( PyObject* data, int lineno ) +{ + // Check if it is a SPELL exception (syntax, driver, etc). If so, + // we want to KEEP the dispatching mechanism on because we still are + // executing a procedure normally. + // Handle name errors + PyObject* errValue = PyTuple_GetItem(data,1); + bool isSpell = SPELLpythonHelper::instance().isInstance( errValue, "SpellException", "spell.lib.exception" ); + + // If we are in a try block there will be no error report, + // but inform the user about the catched exception + if (m_frameManager->getModel().isInTryBlock( lineno )) + { + PyObject* errType = PyTuple_GetItem(data,0); + PyObject* errTb = PyTuple_GetItem(data,2); + SPELLcoreException* ex = SPELLerror::instance().errorToException( errType, errType, errValue, errTb ); + if (isSpell) + { + m_cif->write( "SPELL exception: " + PYREPR(errValue), LanguageConstants::SCOPE_SYS); + } + else if (ex) + { + m_cif->write( ex->what(), LanguageConstants::SCOPE_SYS ); + } + } + + return isSpell; +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::setRunInto +//============================================================================= +void SPELLserviceImpl::setRunInto( const bool enabled ) +{ + if (getConfiguration().isRunInto() != enabled) + { + LOG_INFO("[EXEC] Run into flag set to " + (enabled ? STR("ENABLED") : STR("DISABLED"))); + getConfiguration().setRunInto(enabled); + m_controller->enableRunInto(enabled); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::setByStep +//============================================================================= +void SPELLserviceImpl::setByStep( const bool enabled ) +{ + if (getConfiguration().isByStep() != enabled) + { + LOG_INFO("[EXEC] By step flag set to " + (enabled ? STR("ENABLED") : STR("DISABLED"))); + getConfiguration().setByStep(enabled); + /** \todo configure for dispatch */ + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::setBrowsableLib +//============================================================================= +void SPELLserviceImpl::setBrowsableLib( const SPELLbrowsableLibMode& browsable ) +{ + if (getConfiguration().getBrowsableLib() != browsable) + { + getConfiguration().setBrowsableLib(browsable); + LOG_INFO("[EXEC] Browsable lib flag set to " + browsableLibModeToString(browsable) ); + /** \todo configure for dispatch */ + } +} + + +//============================================================================= +// METHOD : SPELLexecutorImpl::setBrowsableLib +//============================================================================= +void SPELLserviceImpl::setBrowsableLibStr( const std::string& browsableStr ) +{ + if (getConfiguration().getBrowsableLibStr() != browsableStr) + { + getConfiguration().setBrowsableLibStr(browsableStr); + LOG_INFO("[EXEC] Browsable lib flag set to " + browsableStr); + /** \todo configure for dispatch */ + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::setExecDelay +//============================================================================= +void SPELLserviceImpl::setExecDelay( const int delay ) +{ + if (getConfiguration().getExecDelay() != delay) + { + LOG_INFO("[EXEC] Execution delay set to " + ISTR(delay) + " milliseconds"); + getConfiguration().setExecDelay(delay); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::setPromptWarningDelay +//============================================================================= +void SPELLserviceImpl::setPromptWarningDelay( const int delay ) +{ + if (getConfiguration().getPromptWarningDelay() != delay) + { + LOG_INFO("[EXEC] Prompt warning delay set to " + ISTR(delay)); + getConfiguration().setPromptWarningDelay(delay); + m_scheduler->setPromptWarningDelay(delay); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::setForceTcConfirm +//============================================================================= +void SPELLserviceImpl::setForceTcConfirm( const bool force ) +{ + if (getConfiguration().isForceTcConfirm() != force ) + { + LOG_INFO("[EXEC] Set force TC confirmation to " + BSTR(force)); + getConfiguration().setForceTcConfirm(force); + setForceTcConfirmInternal(force); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::setForceTcConfirm +//============================================================================= +void SPELLserviceImpl::setForcePromptConfirm( const bool force ) +{ + if (getConfiguration().isForcePromptConfirm() != force ) + { + LOG_INFO("[EXEC] Set force Prompt confirmation to " + BSTR(force)); + getConfiguration().setForcePromptConfirm(force); + setForcePromptConfirmInternal(force); + } +} +//============================================================================= +// METHOD : SPELLexecutorImpl::command +//============================================================================= +void SPELLserviceImpl::setForceTcConfirmInternal( bool force ) +{ + PyObject* tc = SPELLregistry::instance().get("TC"); + if (tc != NULL) + { + PyObject* arg = force ? Py_True : Py_False; + SPELLpythonHelper::instance().callMethod( tc, "forceTcConfirm", arg, NULL ); + } +} +//============================================================================= +// METHOD : SPELLexecutorImpl::command +//============================================================================= +void SPELLserviceImpl::setForcePromptConfirmInternal( bool force ) +{ + PyObject* tc = SPELLregistry::instance().get("CIF"); + if (tc != NULL) + { + PyObject* arg = force ? Py_True : Py_False; + SPELLpythonHelper::instance().callMethod( tc, "forcePromptConfirm", arg, NULL ); + } +} +//============================================================================= +// METHOD : SPELLexecutorImpl::command +//============================================================================= +void SPELLserviceImpl::command( const ExecutorCommand& cmd, const bool high_priority ) +{ + SPELLmonitor m(m_cmdLock); + DEBUG("[E] Issuing command " + cmd.id); + m_controller->command( cmd, (cmd.id != CMD_ABORT), high_priority ); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::abort +//============================================================================= +void SPELLserviceImpl::abort( const std::string& message, bool systemAborted ) +{ + SPELLmonitor m(m_cmdLock); + + // Send the finish message if any + if (message != "") + { + m_cif->warning(message, systemAborted ? LanguageConstants::SCOPE_SYS : LanguageConstants::SCOPE_PROC ); + } + + // Abort command is a special case which needs this method to process + // abort requests coming from the SPELL framework, not the user (in the + // former case abort shall be immediate, whereas in the latter the abort + // command shall wait till the language execution lock is released) + ExecutorCommand cmd_abort; + cmd_abort.id = CMD_ABORT; + m_controller->command( cmd_abort, false, true ); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::pause +//============================================================================= +void SPELLserviceImpl::pause() +{ + SPELLmonitor m(m_cmdLock); + + // Pause command is a special case which needs this method to process + // pause requests coming from the SPELL framework, not the user. + ExecutorCommand cmd_pause; + cmd_pause.id = CMD_PAUSE; + m_controller->command( cmd_pause, false, true ); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::interrupt +//============================================================================= +void SPELLserviceImpl::interrupt() +{ + SPELLmonitor m(m_cmdLock); + ExecutorCommand cmd_int; + cmd_int.id = CMD_INTERRUPT; + m_controller->command( cmd_int, false, true ); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::finish +//============================================================================= +void SPELLserviceImpl::finish( const std::string& message ) +{ + SPELLmonitor m(m_cmdLock); + + // Send the finish message if any + if (message != "") + { + m_cif->warning(message, LanguageConstants::SCOPE_PROC ); + } + // Finish command is a special case which needs this method to process + // finish requests coming from the SPELL framework, not the user. + ExecutorCommand cmd_finish; + cmd_finish.id = CMD_FINISH; + m_controller->command( cmd_finish, false, true ); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::processLock +//============================================================================= +void SPELLserviceImpl::processLock() +{ + // TODO: No reason to lock here. Remove once validated. + //SPELLmonitor m(m_cmdLock); + m_controller->executionLock(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::processUnlock +//============================================================================= +void SPELLserviceImpl::processUnlock() +{ + // TODO: No reason to lock here. Remove once validated. + //SPELLmonitor m(m_cmdLock); + m_controller->executionUnlock(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::canSkip +//============================================================================= +const bool SPELLserviceImpl::canSkip() +{ + // Allow skipping if in wait or interrupted state + SPELLexecutorStatus status = m_controller->getStatus(); + if ((status == STATUS_WAITING)||(status == STATUS_INTERRUPTED)||(status == STATUS_PROMPT)) return true; + return m_frameManager->canSkip(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::goNextLine +//============================================================================= +const bool SPELLserviceImpl::goNextLine() +{ + unsigned int currentLine = m_frameManager->getCurrentLine(); + if (m_frameManager->getAST().isBlockStart(currentLine)) + { + DEBUG("[E] Skipping entire code block"); + unsigned int nextLine = m_frameManager->getAST().getBlockEnd(currentLine); + return goLine(nextLine); + } + else + { + DEBUG("[E] Skipping single line"); + // When we skip the line, we dont want the callstack and trace model to register the current line + m_callstack->skipCurrentLine(); + return m_frameManager->goNextLine(); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::goLabel +//============================================================================= +const bool SPELLserviceImpl::goLabel( const std::string& label, bool programmed ) +{ + if (programmed) + { + m_gotoTarget = label; + return true; + } + else + { + m_gotoTarget = ""; + // It is a manual goto: we want to report + bool result = m_frameManager->goLabel(label, true, false); + if (result) + { + // When we skip the line, we dont want the callstack and trace model to register the current line + m_callstack->skipCurrentLine(); + } + else + { + m_cif->warning("Unable to go to label '" + label + "'", LanguageConstants::SCOPE_SYS ); + } + return result; + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::goLine +//============================================================================= +const bool SPELLserviceImpl::goLine( const int new_lineno ) +{ + // The frame manager will go to the given line only if possible, checks done inside + bool result = m_frameManager->goLine( new_lineno, true ); + if (result) + { + // When we skip the line, we dont want the callstack and trace model to register the current line + m_callstack->skipCurrentLine(); + } + return result; +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::setBreakpoint +//============================================================================= +const bool SPELLserviceImpl::setBreakpoint( const std::string& file, + const unsigned int line, + const SPELLbreakpointType type ) +{ + return m_frameManager->getBreakpoints().setBreakpoint( file, line, type ); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::checkBreakpoint +//============================================================================= +void SPELLserviceImpl::checkBreakpoint( const std::string& file, const unsigned int line ) +{ + if (m_controller->getStatus() == STATUS_RUNNING) + { + if (m_frameManager->getBreakpoints().checkBreakpoint(file,line)) + { + DEBUG("[BYSTEP] Pausing procedure on breakpoint"); + LOG_INFO("Breakpoint on line " + ISTR(line)); + pause(); + } + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::clearBreakpoints +//============================================================================= +void SPELLserviceImpl::clearBreakpoints() +{ + m_frameManager->getBreakpoints().clearBreakpoints(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::checkByStep +//============================================================================= +const bool SPELLserviceImpl::checkByStep( const int& frameLine ) +{ + // Only if we are not in background (headless) + if (getConfiguration().isHeadless()) return false; + + if (m_frameManager->getModel().isLabel(frameLine)) + { + DEBUG("[BYSTEP] Pausing procedure"); + pause(); + return true; + } + return false; +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::checkInitStep +//============================================================================= +const bool SPELLserviceImpl::checkInitStep( const int& frameLine ) +{ + bool abortDispatching = false; + // Only if there is an INIT step in the code + if (m_frameManager->getModel().hasInitStep()) + { + // Abort the dispatching unless the current line is the INIT line + abortDispatching = true; + if(m_frameManager->getModel().isInitStep( frameLine )) + { + LOG_INFO("Pausing on INIT step on line " + ISTR(frameLine)); + m_initStepDone = true; + // Only if we are not in background (headless) + if (!getConfiguration().isHeadless()) pause(); + // Continue dispatching so that the + // controller holds the execution in PAUSE + abortDispatching = false; + } + } + return abortDispatching; +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::runScript +//============================================================================= +const bool SPELLserviceImpl::runScript( const std::string& script ) +{ + m_cif->setManualMode(true); + bool result = true; + try + { + m_frameManager->runScript( script ); + } + catch(SPELLcoreException& ex) + { + result = false; + m_cif->warning("Failed to execute script: " + ex.what(), LanguageConstants::SCOPE_SYS ); + } + m_cif->setManualMode(false); + return result; +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::executeUserAction() +//============================================================================= +void SPELLserviceImpl::executeUserAction() +{ + if (m_userAction.isEnabled()) + { + LOG_INFO("Executing user action function '" + m_userAction.getAction() + "'"); + try + { + SPELLpythonHelper::instance().checkError(); + m_cif->warning("Running user action '" + m_userAction.getAction() + "'", LanguageConstants::SCOPE_SYS ); + std::string actionScript = m_userAction.getAction() + "()"; + m_frameManager->runScript( actionScript ); + } + catch(SPELLcoreException& ex) + { + LOG_ERROR("Failed to execute user action: " + ex.what()); + m_cif->error("Failed to execute user action: " + ex.what(), LanguageConstants::SCOPE_SYS ); + } + } + else + { + LOG_WARN("Cannot execute user action, not enabled"); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::setUserAction() +//============================================================================= +void SPELLserviceImpl::setUserAction( const SPELLuserAction& action ) +{ + m_userAction = action; + m_cif->notifyUserActionSet(action.getLabel(),action.getSeverity()); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::enableUserAction() +//============================================================================= +void SPELLserviceImpl::enableUserAction( bool enable ) +{ + m_userAction.enable(enable); + m_cif->notifyUserActionEnable(enable); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::dismissUserAction() +//============================================================================= +void SPELLserviceImpl::dismissUserAction() +{ + m_userAction.reset(); + m_cif->notifyUserActionUnset(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl::stageReached +//============================================================================= +void SPELLserviceImpl::stageReached( const std::string& id, const std::string& title ) +{ + displayStage(id,title); + // Notify the event to the excecution frame + m_frameManager->eventStage(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl:: +//============================================================================= +void SPELLserviceImpl::displayStage( const std::string& id, const std::string& title ) +{ + if (title != "") + { + m_cif->write("Step " + id + ": " + title, LanguageConstants::SCOPE_STEP ); + } + else + { + m_cif->write("Step " + id, LanguageConstants::SCOPE_STEP ); + } + // Change also in callstack + m_callstack->setStage(id,title); + + // Update the data in the procedure + PyObject* proc = getVariableManager().getVariableRef(DatabaseConstants::PROC); + if (proc != NULL) + { + SPELLsafePythonOperations ops("SPELLexecutor::displayStage()"); + PyObject* pyId = SSTRPY(id); + PyObject* pyDesc = SSTRPY(title); + PyObject* list = PyList_New(2); + PyList_SetItem(list,0,pyId); + PyList_SetItem(list,1,pyDesc); + Py_INCREF(pyId); + Py_INCREF(pyDesc); + + // Get the previous step value if any + PyObject* prev = PyDict_GetItemString(proc, DatabaseConstants::STEP.c_str()); + + // Set the new value + PyDict_SetItemString( proc, DatabaseConstants::STEP.c_str(), list); + + // If there was a previous value, set it as PREVIOUS + if (prev != NULL) + { + PyDict_SetItemString( proc, DatabaseConstants::PREV_STEP.c_str(), prev); + } + } + + // prepares the message to be sent to GUI + m_cif->resetClose(); +} + +//============================================================================= +// METHOD : SPELLexecutorImpl:: +//============================================================================= +void SPELLserviceImpl::addDispatchListener( SPELLdispatchListener* listener ) +{ + if (std::find(m_listeners.begin(), m_listeners.end(), listener) == m_listeners.end()) + { + DEBUG( "Added listener " + listener->getId() ); + m_listeners.push_back(listener); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl:: +//============================================================================= +void SPELLserviceImpl::removeDispatchListener( SPELLdispatchListener* listener ) +{ + SPELLdispatchListeners::iterator it = std::find(m_listeners.begin(), m_listeners.end(), listener); + if (it != m_listeners.end()) + { + DEBUG( "Removed listener " + listener->getId() ); + m_listeners.erase(it); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl:: +//============================================================================= +void SPELLserviceImpl::notifyLineEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name ) +{ + //DEBUG( "Notify listeners: line event"); + SPELLdispatchListeners::iterator it; + for( it = m_listeners.begin(); it != m_listeners.end(); it++) + { + //DEBUG( " - notify dispatch listener " + (*it)->getId() ); + (*it)->callbackEventLine( frame, file, line, name ); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl:: +//============================================================================= +void SPELLserviceImpl::notifyCallEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name ) +{ + //DEBUG( "Notify listeners: call event"); + SPELLdispatchListeners::iterator it; + for( it = m_listeners.begin(); it != m_listeners.end(); it++) + { + //DEBUG( " - notify dispatch listener " + (*it)->getId() ); + (*it)->callbackEventCall( frame, file, line, name ); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl:: +//============================================================================= +void SPELLserviceImpl::notifyReturnEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name ) +{ + //DEBUG( "Notify listeners: return event"); + SPELLdispatchListeners::iterator it; + for( it = m_listeners.begin(); it != m_listeners.end(); it++) + { + //DEBUG( " - notify dispatch listener " + (*it)->getId() ); + (*it)->callbackEventReturn( frame, file, line, name ); + } +} + +//============================================================================= +// METHOD : SPELLexecutorImpl:: +//============================================================================= +void SPELLserviceImpl::notifyErrorEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name ) +{ + DEBUG( "Notify listeners: error event"); + SPELLdispatchListeners::iterator it; + for( it = m_listeners.begin(); it != m_listeners.end(); it++) + { + DEBUG( " - notify dispatch listener " + (*it)->getId() ); + (*it)->callbackEventError( frame, file, line, name ); + } + DEBUG( "Notify listeners: error event done"); +} diff --git a/lib/SPELL_EXC/src/SPELLserviceInterpreter.C b/lib/SPELL_EXC/src/SPELLserviceInterpreter.C new file mode 100644 index 0000000..c099963 --- /dev/null +++ b/lib/SPELL_EXC/src/SPELLserviceInterpreter.C @@ -0,0 +1,532 @@ +// ################################################################################ +// FILE : SPELLinterpreter.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the custom interpreter +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// System includes --------------------------------------------------------- +// Local includes ---------------------------------------------------------- +#include "SPELL_EXC/SPELLserviceInterpreter.H" +#include "SPELL_EXC/SPELLgoto.H" +#include "SPELL_EXC/SPELLexecutor.H" +#include "SPELL_EXC/SPELLexecutorStatus.H" +#include "SPELL_EXC/SPELLcontroller.H" +#include "SPELL_EXC/SPELLscheduler.H" +#include "SPELL_EXC/SPELLcallstack.H" +#include "SPELL_EXC/SPELLexecutorImpl.H" +#include "SPELL_PRD/SPELLservicePython.H" +// Project includes -------------------------------------------------------- +#include "SPELL_PRD/SPELLprocedureManager.H" +#include "SPELL_UTIL/SPELLerror.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLpythonHelper.H" +#include "SPELL_UTIL/SPELLutils.H" +#include "SPELL_CFG/SPELLconfiguration.H" +#include "SPELL_WRP/SPELLregistry.H" +#include "SPELL_WRP/SPELLdriverManager.H" +#include "SPELL_WS/SPELLwsWarmStartImpl.H" +#include "SPELL_WS/SPELLwsStartupInfo.H" +#include "SPELL_CIF/SPELLcif.H" +#include "SPELL_WRP/SPELLdatabaseManager.H" + +// GLOBALS ///////////////////////////////////////////////////////////////// + +// Interpreter singleton instance +static SPELLserviceInterpreter* s_instance = NULL; + +// Warmstart location name +static const std::string WS_LOCATION = "ws"; +static const std::string ASRUN_LOCATION = "ar"; + +//============================================================================= +// CONSTRUCTOR: SPELLinterpreter::SPELLinterpreter +//============================================================================= +SPELLserviceInterpreter::SPELLserviceInterpreter() +{ + m_serviceImpl = NULL; + m_cif = NULL; + m_controller = NULL; + m_scheduler = NULL; + m_callstack = NULL; + m_frameManager = NULL; + m_warmStart = NULL; + m_servicePath = ""; + m_service = ""; +} + +//============================================================================= +// DESTRUCTOR: SPELLinterpreter::~SPELLinterpreter +//============================================================================= +SPELLserviceInterpreter::~SPELLserviceInterpreter() +{ + DEBUG("[*] Cleaning up"); + if (m_warmStart != NULL) + { + DEBUG("[*] Cleaning warm start mechanism"); + delete m_warmStart; + m_warmStart = NULL; + } + if (m_callstack != NULL) + { + delete m_callstack; + m_callstack = NULL; + } + if (m_controller != NULL) + { + delete m_controller; + m_controller = NULL; + } + if (m_scheduler != NULL) + { + delete m_scheduler; + m_scheduler = NULL; + } + if (m_serviceImpl != NULL) + { + delete m_serviceImpl; + m_serviceImpl = NULL; + } + SPELLpythonHelper::instance().finalize(); + DEBUG("[*] End"); +} + +//============================================================================= +// METHOD : SPELLinterpreter::instance +//============================================================================= +SPELLserviceInterpreter& SPELLserviceInterpreter::instance() +{ + if (s_instance == NULL) + { + s_instance = new SPELLserviceInterpreter(); + } + return *s_instance; +} + +//============================================================================= +// METHOD : SPELLinterpreter::initialize +//============================================================================= +void SPELLserviceInterpreter::initialize( const SPELLinterpreterConfig& config, SPELLcif* cif ) +{ + LOG_INFO("[*] Initializing interpreter"); + + m_cif = cif; + m_service = config.procId; + m_config = config; +} + +//============================================================================= +// METHOD : SPELLinterpreter::mainLoop +//============================================================================= +void SPELLserviceInterpreter::mainLoop() +{ + // Load the SPELL configuration (will fail with exception if there is an error) + SPELLconfiguration::instance().loadConfig(m_config.configFile); + + // Configure the time format if defined in configuration + std::string format = SPELLconfiguration::instance().getCommonParameter("TdsTimeFormat"); + if (format.length()!=0) + { + if (format.compare ("1") == 0) + { + SPELLutils::setTimeFormat(TIME_FORMAT_SLASH); + } + else if (format.compare("0")==0) + { + SPELLutils::setTimeFormat(TIME_FORMAT_DOT); + } + } + + LOG_INFO("[***] Start main loop"); + + // Create and connect all execution control objects + if (prepareObjects()) + { + SPELLsafePythonOperations ops("Service Init"); + // Now try to initialize (compile) the execution frame. + if (prepareExecution()) + { + // If we are in recovery mode: + if (m_config.recover) + { + recover(); + } + else // Or we are in running mode + { + execute(); + } + } + + // After the execution cycle, wait for the user/server to autorize closure + DEBUG("[***] Main loop waiting for CIF"); + m_cif->waitClose(); + + // Once all is finished, stop controller + DEBUG("[***] Stopping command controller"); + m_controller->stop(); + + DEBUG("[***] Cleaning CIF"); + m_cif->cleanup(false); + } + + // Cleanup all warm start files + if (m_warmStart) + { + m_warmStart->cleanup(); + } + + LOG_INFO("[***] End main loop"); +} + +//============================================================================= +// METHOD : SPELLinterpreter::prepareWarmStart +//============================================================================= +void SPELLserviceInterpreter::prepareWarmStart( const SPELLcontextConfig& ctxConfig ) +{ + // Prepare warmstart file if applicable + if (m_config.warmstart) + { + char* home = getenv("SPELL_DATA"); + if (home == NULL) + { + std::string msg = "Unable to setup persistent file, no SPELL_DATA environment variable defined"; + LOG_ERROR(" " + msg); + m_cif->error(msg, LanguageConstants::SCOPE_SYS ); + m_config.warmstart = false; + return; + } + + // Get the location of WS files + std::string wsdir = ctxConfig.getLocationPath( WS_LOCATION ); + std::string saveMode = ctxConfig.getExecutorParameter(ExecutorConstants::SaveStateMode); + + // Prepare the WS configuration + SPELLwsStartupInfo startup; + + if (saveMode == "DISABLED") + { + LOG_WARN("Warmstart disabled by configuration"); + startup.persistentFile = ""; + } + else + { + startup.persistentFile = STR(home) + PATH_SEPARATOR + wsdir + PATH_SEPARATOR; + // Check that the directory exists + if (!SPELLutils::pathExists(startup.persistentFile)) + { + std::string msg = "Unable to setup persistent file, warm-start directory not found: " + startup.persistentFile; + LOG_ERROR(" " + msg); + m_cif->error(msg, LanguageConstants::SCOPE_SYS ); + m_config.warmstart = false; + return; + } + + // Character replacements for constructing the file ids + std::string theId = m_service; + SPELLutils::replace( theId, ".py", "" ); + SPELLutils::replace( theId, "..", "" ); + SPELLutils::replace( theId, "//", "/" ); + SPELLutils::replace( theId, PATH_SEPARATOR, "__" ); + startup.persistentFile += m_config.timeId + "_Executor_" + theId; + LOG_INFO("Warm start persistent file: " + startup.persistentFile); + } + + + LOG_INFO("Warm start files location: " + wsdir); + LOG_INFO("Warm start working mode: " + saveMode); + LOG_INFO("Warm start service file: " + m_service); + + + // Set the configured working mode + startup.workingMode = StringToWorkingMode(saveMode); + + // Set the procedure file + startup.procedureFile = m_service; + + // Set the recovery file if any + if (m_config.persis != "") + { + startup.recoveryFile = STR(home) + PATH_SEPARATOR + wsdir + PATH_SEPARATOR + m_config.persis; + startup.performRecovery = true; + } + + try + { + // Create the warm start support + m_warmStart = new SPELLwsWarmStartImpl(); + // Initialize it + m_warmStart->initialize( startup ); + // Set the warm start support in the execution frame + m_frameManager->setWarmStart( m_warmStart ); + } + catch(SPELLcoreException& ex) + { + if (m_warmStart != NULL) delete m_warmStart; + m_warmStart = NULL; + throw ex; + } + } + else + { + m_cif->warning("ATTENTION: no warmstart mechanism is being used", LanguageConstants::SCOPE_SYS ); + LOG_WARN("[***] No warmstart mechanism will be used"); + } +} + +//============================================================================= +// METHOD : SPELLinterpreter::prepareCIF +//============================================================================= +void SPELLserviceInterpreter::prepareCIF( const SPELLcontextConfig& ctxConfig ) +{ + DEBUG(" Setup client interface"); + + // Create the configuration for the CIF + SPELLcifStartupInfo cifStartup; + cifStartup.procId = m_service; + cifStartup.procName = "service startups"; + cifStartup.contextName = m_config.ctxName; + cifStartup.contextPort = m_config.ctxPort; + cifStartup.timeId = m_config.timeId; + + m_cif->setup( cifStartup ); +} + +//============================================================================= +// METHOD : SPELLinterpreter::prepareObjects +//============================================================================= +void SPELLserviceInterpreter::recoverCIF( const SPELLcontextConfig& ctxConfig ) +{ + char* home = getenv("SPELL_DATA"); + if (home == NULL) + { + std::string msg = "Unable to recover CIF asrun, no SPELL_DATA environment variable defined"; + LOG_ERROR(" " + msg); + m_cif->error(msg, LanguageConstants::SCOPE_SYS ); + return; + } + + // Get the location of WS files + std::string ardir = ctxConfig.getLocationPath( ASRUN_LOCATION ); + + std::string originalAsRun = std::string(home) + PATH_SEPARATOR + ardir + PATH_SEPARATOR + m_config.persis + ".ASRUN"; + + m_cif->useAsRun( originalAsRun ); +} + +//============================================================================= +// METHOD : SPELLinterpreter::prepareObjects +//============================================================================= +const bool SPELLserviceInterpreter::prepareObjects() +{ + LOG_INFO("[***] Preparing objects"); + // Setup the client interface. The standalone one does + // just a few value initializations, the server one + // does the login in the context process + assert(m_cif != NULL); + bool result = true; + try + { + DEBUG(" Initializing Python interface"); + SPELLpythonHelper::instance().initialize(); + SPELLsafePythonOperations ops("Service Init"); + // Install log support asap + Log_Install(); + SpellService_Install(); + DEBUG(" Loading execution framework functions"); + // Setup the execution environment + SPELLpythonHelper::instance().loadFramework(); + + // Load the configuration on python side for the language and drivers + SPELLconfiguration::instance().loadPythonConfig(m_config.configFile); + // Get the context configuration + SPELLcontextConfig& ctxConfig = SPELLconfiguration::instance().getContext(m_config.ctxName); + + + // User library + m_libPath = SPELLprocedureManager::instance().getLibPath(); + + DEBUG(" Creating and linking"); + // Create the executor instance + m_serviceImpl = new SPELLserviceImpl(); + // Set the reference for the static accessor (Python layer and others) + SPELLexecutor::setInstance( m_serviceImpl ); + + m_controller = new SPELLcontroller( m_config.procId ); + m_scheduler = new SPELLscheduler(false); + m_callstack = new SPELLcallstack(); + // Create and initialize the execution frame + m_frameManager = new SPELLframeManager(); + + DEBUG(" Initializing Service"); + // Initialize the executor with the objects + m_serviceImpl->initialize(m_cif, m_controller, m_scheduler, m_callstack, m_frameManager); + + // Setup the CIF now + try + { + prepareCIF( ctxConfig ); + } + catch(SPELLcoreException& ex) + { + // If we have no CIF there is no way to communicate anything. Bail out + LOG_ERROR("[FATAL] Failed to setup CIF: cannot start executor."); + LOG_ERROR("[FATAL] Error was: " + ex.what()); + ::exit(EIO); + } + + + // Install the CIF object in the SPELL registry + DEBUG(" Installing client interface"); + ClientIF_Install(); + + // Setup procedure manager + DEBUG(" Preparing procedure manager"); + SPELLdriverManager::instance().setup(m_config.ctxName); + SPELLdatabaseManager::instance().loadBuiltinDatabases(); + SPELLprocedureManager::instance().setup(m_config.ctxName); + SPELLpyService& service = SPELLprocedureManager::instance().getService(m_service); + m_servicePath = service.getBasePath(); + + // Prepare and configure warm start mechanism now + DEBUG(" Preparing warm start"); + prepareWarmStart( ctxConfig ); + + // Let the executor prepare all the rest it needs for execution. Anything done here + // shall be independent from reloads/aborts, etc. + m_serviceImpl->prepare( m_service, ctxConfig ); + + DEBUG(" Starting controller"); + m_controller->begin(); + + // If we are in recovery mode, recover also the original asrun file + if (m_config.persis != "") + { + recoverCIF( ctxConfig ); + } + + LOG_INFO("[***] Objects ready"); + } + catch(SPELLcoreException& ex) + { + std::string msg = "[***] Failed to create objects: " + ex.what(); + LOG_ERROR(msg); + // Notify error only if we have a way to do it, that is, no CIF failure. + if (m_controller) + { + m_controller->setError( "Failed to initialize: " + ex.getError(), ex.getReason(), true); + } + result = false; + } + return result; +} + +//============================================================================= +// METHOD : SPELLinterpreter::prepareExecution +//============================================================================= +const bool SPELLserviceInterpreter::prepareExecution() +{ + LOG_INFO("[***] Preparing execution"); + try + { + DEBUG(" Installing executor binding"); + Executor_Install(); + + DEBUG(" Installing goto bindings"); + Goto_Install(); + Step_Install(); + + + + if (m_config.script) + { + // In this case the proc path is just the script + //m_procPath = m_procedure; + LOG_INFO(" Compiling script"); + + } + else + { + LOG_INFO(" Compiling procedure"); + // Compile and create initial execution frame + SPELLpyService& service = SPELLprocedureManager::instance().getService(m_service); + m_frameManager->initialize(service.getMainServiceFile()); + } + + // Set the procedures path + m_serviceImpl->setProcedurePath( m_servicePath ); + // Set the user library path + m_serviceImpl->setLibraryPath( m_libPath ); + + LOG_INFO("Executor procedure path: " + m_servicePath); + LOG_INFO("Executor library path: " + m_libPath); + + } + catch(SPELLcoreException& ex) + { + LOG_ERROR(" Catched error during preparation: " + ex.what()); + m_controller->setError( "Error during preparation: " + ex.getError(), ex.getReason(), true); + return false; + } + LOG_INFO("[***] Execution ready"); + return true; +} + +//============================================================================= +// METHOD : SPELLinterpreter::execute +//============================================================================= +void SPELLserviceInterpreter::execute() +{ + // Setup procedure manager + LOG_INFO("[*] Starting execution"); + + try + { + m_serviceImpl->execute(); + } + catch(SPELLcoreException& ex) + { + LOG_ERROR("[FATAL] Error during execution: " + ex.what()); + m_controller->setError( "Error during execution: " + ex.getError(), ex.getReason(), ex.isFatal()); + } + + LOG_INFO("[*] Execution finished"); +} + +//============================================================================= +// METHOD : SPELLinterpreter::recover +//============================================================================= +void SPELLserviceInterpreter::recover() +{ + // Setup procedure manager + LOG_INFO("[*] Recovering execution from persistent file"); + try + { + m_serviceImpl->recover(); + } + catch(SPELLcoreException& ex) + { + LOG_ERROR("[FATAL] Error during recovery: " + ex.what()); + /** \todo handle exception: send error */ + } + LOG_INFO("[*] Execution finished"); +} diff --git a/lib/SPELL_EXC/src/SPELLstepPython.C b/lib/SPELL_EXC/src/SPELLstepPython.C index 5754b94..94655fc 100644 --- a/lib/SPELL_EXC/src/SPELLstepPython.C +++ b/lib/SPELL_EXC/src/SPELLstepPython.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the Step Python bindings // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -80,8 +80,7 @@ static PyMethodDef Step_Methods[] = //============================================================================ static PyTypeObject Step_Type = { - PyObject_HEAD_INIT(NULL) - 0, //ob_size + PyVarObject_HEAD_INIT(NULL,0) "executor.Step", //tp_name sizeof(PyStepObject), //tp_basicsize 0, //tp_itemsize @@ -135,7 +134,7 @@ static int Step_Init( PyStepObject* self, PyObject* args, PyObject* kwds ) //============================================================================ static void Step_Dealloc( PyStepObject* self ) { - self->ob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ diff --git a/lib/SPELL_EXC/src/SPELLvariableManager.C b/lib/SPELL_EXC/src/SPELLvariableManager.C index 6888142..e16445b 100644 --- a/lib/SPELL_EXC/src/SPELLvariableManager.C +++ b/lib/SPELL_EXC/src/SPELLvariableManager.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the procedure variable manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_EXC/src/SPELLvariableMonitor.C b/lib/SPELL_EXC/src/SPELLvariableMonitor.C index c04e91e..bbbbcab 100644 --- a/lib/SPELL_EXC/src/SPELLvariableMonitor.C +++ b/lib/SPELL_EXC/src/SPELLvariableMonitor.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the procedure variable monitor // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -92,12 +92,16 @@ void SPELLvariableMonitor::retrieveGlobalVariables() std::string varName = PYSSTR(key); PyObject* object = PyDict_GetItem( dict, key ); + if (object == NULL) continue; + + Py_XINCREF(object); + if (shouldDiscard(varName,object)) continue; DEBUG("[VM] Processing " + varName); std::string type = PYSSTR( PyObject_Type(object) ); - std::string value = PYREPR( object ); + std::string value = PYCREPR( object ); DEBUG("[VM] Type : " + type); DEBUG("[VM] Value : " + value); @@ -107,6 +111,8 @@ void SPELLvariableMonitor::retrieveGlobalVariables() if (value == "") value = EMPTY_STRING; m_globalVariables.insert( std::make_pair(varName, SPELLvarInfo(varName, type, value, true)) ); + + Py_XDECREF(object); } } @@ -150,7 +156,7 @@ void SPELLvariableMonitor::retrieveLocalVariables() DEBUG("[VM] Processing " + varName); std::string type = PYSSTR( PyObject_Type(object) ); DEBUG("[VM] Type : " + type); - std::string value = PYREPR( object ); + std::string value = PYCREPR( object ); DEBUG("[VM] Value : " + value); DEBUG("[VM] Global : " + BSTR(false)); @@ -312,6 +318,12 @@ PyObject* SPELLvariableMonitor::getVariableRef( const std::string& name ) { return PyDict_GetItemString(m_frame->f_globals, name.c_str()); } + PyObject* builtins = PyEval_GetBuiltins(); + if (PyDict_Contains(builtins, pyName.get())) + { + return PyDict_GetItemString(builtins, name.c_str()); + } + return NULL; } @@ -369,13 +381,15 @@ bool SPELLvariableMonitor::shouldDiscard( const std::string& varName, PyObject* // Ignore internal flags if (varName == "__USERLIB__") return true; + if (varName.substr(0,2) == "__" ) return true; + + // Ignore callables and complex objects if (SPELLpythonHelper::instance().isInstance(value, "Database", "spell.lib.adapter.databases.database")) return true; if (PyCallable_Check(value)) return true; if (PyFunction_Check(value)) return true; if (PyClass_Check(value)) return true; if (PyModule_Check(value)) return true; - if (PyInstance_Check(value)) return true; return false; } @@ -406,7 +420,7 @@ void SPELLvariableMonitor::analyze() PyObject* key = PyList_GetItem( globalsItemList.get(), index ); PyObject* object = PyDict_GetItem( dict, key ); std::string varName = PYSTR(key); - + //std::cout << varName << " -> " << shouldDiscard(varName,object) << std::endl; if (shouldDiscard(varName,object)) continue; it = m_globalVariables.find(varName); diff --git a/lib/SPELL_IPC/Makefile.am b/lib/SPELL_IPC/Makefile.am index 27b40f2..713afe3 100644 --- a/lib/SPELL_IPC/Makefile.am +++ b/lib/SPELL_IPC/Makefile.am @@ -1,47 +1,61 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_IPC.la -CPPFLAGS += -Wno-pragmas -libSPELL_IPC_la_LDFLAGS = -version-info 3:0:0 -libSPELL_IPC_la_SOURCES = \ - src/SPELLipcDataChunk.C \ - src/SPELLipcIncoming.C \ - src/SPELLipcMessage.C \ - src/SPELLipcServerInterface.C \ - src/SPELLipcServerInterfaceSingle.C \ - src/SPELLipcChannel.C \ - src/SPELLsocket.C \ - src/SPELLipcClientInterface.C \ - src/SPELLipcHelper.C \ - src/SPELLipcInput.C \ - src/SPELLipcMessageMailbox.C \ - src/SPELLipcOutput.C \ - src/SPELLipcTrash.C - - +lib_LTLIBRARIES = libSPELL_IPC_v2.la libSPELL_IPC_v3.la + +libSPELL_IPC_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} -Wno-pragmas + +libSPELL_IPC_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_IPC_v2_la_SOURCES = src/SPELLipcDataChunk.C \ + src/SPELLipcIncoming.C \ + src/SPELLipcMessage.C \ + src/SPELLipcServerInterface.C \ + src/SPELLipcServerInterfaceSingle.C \ + src/SPELLipcChannel.C \ + src/SPELLsocket.C \ + src/SPELLipcClientInterface.C \ + src/SPELLipcHelper.C \ + src/SPELLipcInput.C \ + src/SPELLipcMessageMailbox.C \ + src/SPELLipcOutput.C \ + src/SPELLipcTrash.C + +libSPELL_IPC_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} -Wno-pragmas + +libSPELL_IPC_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_IPC_v3_la_SOURCES = src/SPELLipcDataChunk.C \ + src/SPELLipcIncoming.C \ + src/SPELLipcMessage.C \ + src/SPELLipcServerInterface.C \ + src/SPELLipcServerInterfaceSingle.C \ + src/SPELLipcChannel.C \ + src/SPELLsocket.C \ + src/SPELLipcClientInterface.C \ + src/SPELLipcHelper.C \ + src/SPELLipcInput.C \ + src/SPELLipcMessageMailbox.C \ + src/SPELLipcOutput.C \ + src/SPELLipcTrash.C + \ No newline at end of file diff --git a/lib/SPELL_IPC/src/SPELLipcChannel.C b/lib/SPELL_IPC/src/SPELLipcChannel.C index 29efc98..2e72709 100644 --- a/lib/SPELL_IPC/src/SPELLipcChannel.C +++ b/lib/SPELL_IPC/src/SPELLipcChannel.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of a peer ipc channel // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -27,11 +27,13 @@ // FILES TO INCLUDE //////////////////////////////////////////////////////// // Local includes ---------------------------------------------------------- #include "SPELL_IPC/SPELLipcChannel.H" +#include "SPELL_IPC/SPELLipcError.H" // Project includes -------------------------------------------------------- #include "SPELL_UTIL/SPELLlog.H" #include "SPELL_UTIL/SPELLutils.H" #include "SPELL_SYN/SPELLmonitor.H" #include "SPELL_SYN/SPELLsyncError.H" +#include "SPELL_IPC/SPELLipcError.H" // System includes --------------------------------------------------------- @@ -60,23 +62,25 @@ SPELLipcChannel::SPELLipcChannel( const std::string& name, SPELLsocket* socket, SPELLipcChannel::~SPELLipcChannel() { DEBUG( NAME + "Destroying channel"); - if (m_socket) - { - delete m_socket; - m_socket = NULL; - } if (m_output) { + m_output->disconnect(false); m_output->join(); delete m_output; m_output = NULL; } if (m_input) { + m_input->disconnect(); m_input->join(); delete m_input; m_input = NULL; } + if (m_socket) + { + delete m_socket; + m_socket = NULL; + } DEBUG( NAME + "Channel destroyed"); } @@ -89,6 +93,7 @@ void SPELLipcChannel::connect() m_output = createOutput(); m_input = createInput(); m_input->start(); + m_output->start(); setConnected(true); DEBUG( NAME + "Connect done"); } @@ -138,8 +143,17 @@ void SPELLipcChannel::disconnect() { DEBUG( NAME + "Disconnect"); m_connected = false; - m_output->disconnect(true); + try + { + m_output->disconnect(true); + } + catch (SPELLipcError& ex) + { + + } + m_input->setHandleEOC(false); m_input->disconnect(); + m_input->join(); m_socket->close(); DEBUG( NAME + "Disconnect finished"); } @@ -217,11 +231,18 @@ void SPELLipcChannel::requestedEOC() { if (isConnected()) { - setConnected(false); - DEBUG( NAME + "Peer requested end of conversation"); - m_output->disconnect(false); - m_socket->shutdown(); - DEBUG( NAME + "Disconnected, reporting interface"); - m_ifc.connectionClosed(m_key); + try + { + setConnected(false); + DEBUG( NAME + "Peer requested end of conversation"); + m_output->disconnect(false); + m_socket->shutdown(); + DEBUG( NAME + "Disconnected, reporting interface"); + m_ifc.connectionClosed(m_key); + } + catch (SPELLipcError& ex) + { + // Ignore the IPC error if it happens when requeting EOC + } } } diff --git a/lib/SPELL_IPC/src/SPELLipcClientInterface.C b/lib/SPELL_IPC/src/SPELLipcClientInterface.C index e732e9e..8ac7e76 100644 --- a/lib/SPELL_IPC/src/SPELLipcClientInterface.C +++ b/lib/SPELL_IPC/src/SPELLipcClientInterface.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the interface for clients // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -59,6 +59,7 @@ SPELLipcClientInterface::SPELLipcClientInterface( const std::string& name, const { m_channel = NULL; m_listener = NULL; + m_socket = NULL; m_trash.start(); m_timeoutIpcRetry = SPELLconfiguration::instance().commonOrDefault("RetryTimeout", IPC_REQUEST_RETRY_DEFAULT_DELAY_MSEC ); @@ -339,15 +340,16 @@ void SPELLipcClientInterface::incomingRequest( const SPELLipcMessage& msg ) SPELLmonitor m(m_lock); - DEBUG(NAME + "Incoming request (" + msg.getSequenceStr() + ")"); + DEBUG(NAME + "Incoming request (" + msg.getSequenceStr() + ") for ("+msg.get("User")+")"); try { DEBUG(NAME + "Creating request processor (" + msg.getSequenceStr() + ")"); - SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, m_channel->getWriter(), *m_listener ); + SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, m_lock, &m_channel, *m_listener ); ireq->start(); - DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")"); - ireq->waitStarted(); + //DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")"); + // TODO: No reason to wait here. Remove once validated. + //ireq->waitStarted(); DEBUG(NAME + "Place in trash"); m_trash.place(ireq); DEBUG(NAME + "Creating request processor DONE (" + msg.getSequenceStr() + ")"); @@ -365,7 +367,7 @@ void SPELLipcClientInterface::incomingRequest( const SPELLipcMessage& msg ) //============================================================================= void SPELLipcClientInterface::incomingMessage( const SPELLipcMessage& msg ) { - DEBUG(NAME + "IPC interface incoming message " + msg.getId()); + DEBUG(NAME + "IPC interface incoming message " + msg.getId() + " for ("+msg.get("User")+")"); if (!m_connected) return; if (m_listener == NULL) return; @@ -374,11 +376,12 @@ void SPELLipcClientInterface::incomingMessage( const SPELLipcMessage& msg ) SPELLipcIncomingMessage* imsg = new SPELLipcIncomingMessage( msgId, m_ifcName, msg, *m_listener); imsg->start(); - DEBUG(NAME + "Wait processor to start"); - imsg->waitStarted(); - DEBUG(NAME + "Place in trash"); + //DEBUG(NAME + "Wait processor to start"); + // TODO: No reason to wait here. Remove once validated. + //imsg->waitStarted(); + //DEBUG(NAME + "Place in trash"); m_trash.place(imsg); - DEBUG(NAME + "IPC interface incoming message OUT"); + //DEBUG(NAME + "IPC interface incoming message OUT"); } //============================================================================= @@ -567,3 +570,10 @@ void SPELLipcClientInterface::removeListener() m_listener = NULL; } +SPELLipcMessage SPELLipcClientInterface::getPingMessage() +{ + if (m_listener != NULL) + return m_listener->getPingMessage(); + static SPELLipcMessage empty = SPELLipcMessage(); + return empty; +}; diff --git a/lib/SPELL_IPC/src/SPELLipcDataChunk.C b/lib/SPELL_IPC/src/SPELLipcDataChunk.C index ee78224..1307e43 100644 --- a/lib/SPELL_IPC/src/SPELLipcDataChunk.C +++ b/lib/SPELL_IPC/src/SPELLipcDataChunk.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the IPC data chunker // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_IPC/src/SPELLipcHelper.C b/lib/SPELL_IPC/src/SPELLipcHelper.C index efc196d..fffd854 100644 --- a/lib/SPELL_IPC/src/SPELLipcHelper.C +++ b/lib/SPELL_IPC/src/SPELLipcHelper.C @@ -5,7 +5,7 @@ // DESCRIPTION: IPC utilities // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_IPC/src/SPELLipcIncoming.C b/lib/SPELL_IPC/src/SPELLipcIncoming.C index d1fca4c..7cbfcf3 100644 --- a/lib/SPELL_IPC/src/SPELLipcIncoming.C +++ b/lib/SPELL_IPC/src/SPELLipcIncoming.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the incoming message handler // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -49,10 +49,11 @@ SPELLipcIncomingBase::SPELLipcIncomingBase( const std::string& id, const std::st m_processingFinishEvent(false), m_processingStartEvent(false), m_key(msg.getKey()), - m_finished(false), - m_started(false) + m_started(false), + m_finished(false) + { - DEBUG( NAME + "Created"); + //DEBUG( NAME + "Created"); DEBUG( NAME + "Using message " + m_message.getId()); m_processingFinishEvent.clear(); m_processingStartEvent.clear(); @@ -63,7 +64,7 @@ SPELLipcIncomingBase::SPELLipcIncomingBase( const std::string& id, const std::st //============================================================================= SPELLipcIncomingBase::~SPELLipcIncomingBase() { - DEBUG("Destroyed"); + //DEBUG("Destroyed"); m_finished = true; } @@ -128,7 +129,6 @@ void SPELLipcIncomingBase::setFinished() //============================================================================= bool SPELLipcIncomingBase::isFinished() { - SPELLmonitor m(m_dataLock); return m_finished; } @@ -164,16 +164,16 @@ int SPELLipcIncomingBase::getKey() //============================================================================= bool SPELLipcIncomingBase::wait( long timeoutMsec ) { - DEBUG( NAME + "Wait finish " + getMessage().getSequenceStr()); + //DEBUG( NAME + "Wait finish " + getMessage().getSequenceStr()); bool timedout = m_processingFinishEvent.wait( timeoutMsec ); if (timedout) { - DEBUG( NAME + "Finish timeout (" + ISTR(timeoutMsec) + ") " + getMessage().getSequenceStr()); - DEBUG( "MESSAGE " + getMessage().dataStr()); + //DEBUG( NAME + "Finish timeout (" + ISTR(timeoutMsec) + ") " + getMessage().getSequenceStr()); + //DEBUG( "MESSAGE " + getMessage().dataStr()); } else { - DEBUG( NAME + "Wait finish done " + getMessage().getSequenceStr()); + //DEBUG( NAME + "Wait finish done " + getMessage().getSequenceStr()); } return timedout; } @@ -187,6 +187,7 @@ void SPELLipcIncomingBase::finish() if (m_finished) return; m_processingFinishEvent.set(); m_finished = true; + m_message.clear(); } //============================================================================= @@ -222,11 +223,11 @@ SPELLipcIncomingMessage::~SPELLipcIncomingMessage() //============================================================================= void SPELLipcIncomingMessage::run() { - DEBUG( NAME + "Incoming message starting"); + //DEBUG( NAME + "Incoming message starting"); setStarted(); getListener().processMessage(getMessage()); finish(); - DEBUG( NAME + "Incoming message finished"); + //DEBUG( NAME + "Incoming message finished"); } //============================================================================= @@ -235,11 +236,12 @@ void SPELLipcIncomingMessage::run() SPELLipcIncomingRequest::SPELLipcIncomingRequest( const std::string& requestId, const std::string& ifcName, SPELLipcMessage msg, - SPELLipcOutput& writer, + SPELLmutex& mutex, + SPELLipcChannel** channel, SPELLipcInterfaceListener& listener) : SPELLipcIncomingBase(requestId,ifcName,msg,listener), - m_writer(writer) + m_channel(channel),m_mutex(mutex) { } @@ -248,7 +250,7 @@ SPELLipcIncomingRequest::SPELLipcIncomingRequest( const std::string& requestId, //============================================================================= SPELLipcIncomingRequest::~SPELLipcIncomingRequest() { - DEBUG( NAME + "Incoming request destroyed"); + //DEBUG( NAME + "Incoming request destroyed"); } //============================================================================= @@ -282,7 +284,12 @@ void SPELLipcIncomingRequest::run() try { DEBUG( NAME + "Sending response (" + copy.getSequenceStr() + ")"); - m_writer.send(response); + { + SPELLmonitor m(m_mutex); + if (*m_channel != NULL){ + (*m_channel)->getWriter().send(response); + } + } DEBUG( NAME + "Response sent (" + copy.getSequenceStr() + ")"); } catch(...) diff --git a/lib/SPELL_IPC/src/SPELLipcInput.C b/lib/SPELL_IPC/src/SPELLipcInput.C index 1018f00..8eacff9 100644 --- a/lib/SPELL_IPC/src/SPELLipcInput.C +++ b/lib/SPELL_IPC/src/SPELLipcInput.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data reader // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -38,7 +38,7 @@ // DEFINES ///////////////////////////////////////////////////////////////// #define NAME std::string("[ INPUT-KEY(") + ISTR(m_key) + ")-" + m_ifcName + " ] " -#define SIZE sizeof(unsigned int) +#define SIZE sizeof(uint32_t) // store the diagnostics config #pragma GCC diagnostic push @@ -58,6 +58,9 @@ SPELLipcInput::SPELLipcInput( const std::string& name, SPELLsocket& skt, int pee m_ifcName = name; m_key = peerKey; m_connected = true; + m_totalPacketLength = 0; + m_requestedEOC = false; + m_lastByte = 0; DEBUG( NAME + "Created"); } @@ -89,7 +92,10 @@ int SPELLipcInput::readPacketLength( int numRead ) m_totalPacketLength = length; //DEBUG( NAME + " readPacketLength length: " + ISTR(m_totalPacketLength) + " " + SPELLutils::dumpString(tmp)); - assert(m_totalPacketLength < 9999000); + // Kill connection in case a client sends more then 1000MB in a single packet + if (m_totalPacketLength > 1000000000){ + throw SPELLipcError( NAME + "Peer has sent bad data disconnecting!", 0); + } // Remove the length bytes from buffer for( unsigned int byte=0; byte<(numRead-SIZE); byte++) @@ -126,6 +132,7 @@ int SPELLipcInput::readMoreBytes() { LOG_WARN( NAME + "WARNING: retrying read..."); retries++; + usleep(50000); if (retries ==3) throw SPELLipcError(NAME + "Peer has disconnected (errno " + ISTR(errNo) + ")", errNo ); } else break; @@ -147,8 +154,8 @@ int SPELLipcInput::completeLength( int numRead ) { int more = m_socket.receive( m_buffer+numRead, IPC_BUFFER_SIZE-numRead ); int errNo = errno; - assert( more >= 0 ); - if (more == 0 && m_connected) + //assert( more >= 0 ); + if (more <= 0 && m_connected) { DEBUG( NAME + "Read 0, peer has disconnected"); // When we receive zero it means that the peer has invoked @@ -156,6 +163,7 @@ int SPELLipcInput::completeLength( int numRead ) // interface is in charge of that, we shall not touch the // socket file descriptor here in SPELLipcInput. Just finish the // loop. + // If more < 0 there was an during the receive call => disconect the client throw SPELLipcError( NAME + "Peer has disconnected (errno " + ISTR(errNo) + ")", errNo); } return more; @@ -344,7 +352,7 @@ void SPELLipcInput::run() { case IPC_ERROR_UNKNOWN_MSG_TYPE: { - LOG_ERROR( NAME + "Unable to process packet. " + ex.getError()) + LOG_ERROR( NAME + "Unable to process packet. " + ex.getError()); DEBUG("Packet size: " + ISTR(m_packet.size())); DEBUG("Packet expected length: " + ISTR(m_totalPacketLength)); DEBUG(SPELLutils::dumpString(m_packet)); @@ -407,7 +415,7 @@ void SPELLipcInput::disconnect() //============================================================================= void SPELLipcInput::dispatch() { - DEBUG( NAME + " Dispatch TRY IN"); + //DEBUG( NAME + " Dispatch TRY IN"); if (!m_connected) return; //DEBUG( NAME + "Dispatching: '" + m_packet + "'"); assert( m_packet.size() == m_totalPacketLength ); @@ -436,8 +444,9 @@ void SPELLipcInput::dispatch() msg.fromData( dataForMsg ); msg.setCompressed(compression); msg.setKey(m_key); - - DEBUG( NAME + "DISPATCH: " + msg.dataStr()); + msg.setSender(msg.getSender()); + msg.set("User",m_socket.getUser()); + //DEBUG( NAME + "DISPATCH: " + msg.dataStr()); switch(msg.getType()) { @@ -478,7 +487,7 @@ void SPELLipcInput::dispatch() m_packet = ""; m_lastByte = NULL; m_totalPacketLength = 0; - DEBUG( NAME + "DISPATCH OUT"); + //DEBUG( NAME + "DISPATCH OUT"); } #pragma GCC diagnostic pop // restore diagnostics mode diff --git a/lib/SPELL_IPC/src/SPELLipcMessage.C b/lib/SPELL_IPC/src/SPELLipcMessage.C index 96a583d..a784232 100644 --- a/lib/SPELL_IPC/src/SPELLipcMessage.C +++ b/lib/SPELL_IPC/src/SPELLipcMessage.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the IPC message // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -104,6 +104,7 @@ SPELLipcMessage::SPELLipcMessage( SPELLipcMessage* msg ) m_key = msg->m_key; m_compressed = msg->m_compressed; m_properties = msg->m_properties; + set("User", msg->get("User")); } //============================================================================= @@ -195,7 +196,13 @@ std::string SPELLipcMessage::get( std::string key ) const } return it->second; } - +void SPELLipcMessage::clear( ) +{ + m_properties.clear(); + m_id = ""; + m_senderId = ""; + m_receiverId = ""; +} //============================================================================= // METHOD: SPELLipcMessage:getRef //============================================================================= diff --git a/lib/SPELL_IPC/src/SPELLipcMessageMailbox.C b/lib/SPELL_IPC/src/SPELLipcMessageMailbox.C index 6ae3c8b..955752e 100644 --- a/lib/SPELL_IPC/src/SPELLipcMessageMailbox.C +++ b/lib/SPELL_IPC/src/SPELLipcMessageMailbox.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the message mailbox // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -108,22 +108,6 @@ void SPELLipcMessageMailbox::shutdown() DEBUG(NAME + "Shutdown") m_working = false; } - cancelAll(); -} - -//============================================================================= -// METHOD: SPELLipcMessageMailbox::cancelAll() -//============================================================================= -void SPELLipcMessageMailbox::cancelAll() -{ - SPELLipcMessageQueueMap::iterator mit; - for( mit = m_queueMap.begin(); mit != m_queueMap.end(); mit++) - { - SPELLipcMessage* dummyResponse = new SPELLipcMessage("dummy"); - dummyResponse->setType( MSG_TYPE_RESPONSE ); - SPELLipcMessageQueue* queue = (*mit).second; - queue->push(dummyResponse); - } } //============================================================================= diff --git a/lib/SPELL_IPC/src/SPELLipcOutput.C b/lib/SPELL_IPC/src/SPELLipcOutput.C index 7b06f0d..5fb960e 100644 --- a/lib/SPELL_IPC/src/SPELLipcOutput.C +++ b/lib/SPELL_IPC/src/SPELLipcOutput.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data writer // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -33,15 +33,16 @@ #include "SPELL_SYN/SPELLmonitor.H" #include "SPELL_UTIL/SPELLlog.H" #include "SPELL_UTIL/SPELLcompression.H" +#include "SPELL_EXC/SPELLexecutor.H" // System includes --------------------------------------------------------- // DEFINES ///////////////////////////////////////////////////////////////// #define NAME std::string("[ OUTPUT-KEY(") + ISTR(m_key) + ")-" + m_ifcName + " ] " -#define SIZE sizeof(unsigned int) +#define SIZE sizeof(uint32_t) #define MINIMUM_SIZE_FOR_COMPRESSION 512 -#define PING_PERIOD_SEC 250 +#define PING_PERIOD_SEC 10 //============================================================================= // FUNCTION: encodeLength @@ -70,7 +71,7 @@ SPELLipcOutput::SPELLipcOutput( const std::string& name, SPELLsocket& skt, int m m_channel(chan), m_connected(true) { - DEBUG( NAME + "Created"); + //DEBUG( NAME + "Created"); m_ping.setId("ping"); m_ping.setType(MSG_TYPE_PING); } @@ -80,7 +81,9 @@ SPELLipcOutput::SPELLipcOutput( const std::string& name, SPELLsocket& skt, int m //============================================================================= SPELLipcOutput::~SPELLipcOutput() { - DEBUG( NAME + "Destroyed"); + //DEBUG( NAME + "Destroyed"); + m_connected = false; + this->join(); } //============================================================================= @@ -88,20 +91,21 @@ SPELLipcOutput::~SPELLipcOutput() //============================================================================= void SPELLipcOutput::send( SPELLipcMessage& msg ) { - msg.setKey( m_key ); - DEBUG( NAME + "SEND " + msg.dataStr() ); try { - std::string data = msg.data(); - bool doCompression = (msg.getCompressed() && (data.size()>= MINIMUM_SIZE_FOR_COMPRESSION)); + SPELLmonitor m(m_lock); + msg.setKey(m_key); + //DEBUG(NAME + "SEND " + msg.dataStr()); + std::string data = msg.data(); + bool doCompression = (msg.getCompressed() && (data.size()>= MINIMUM_SIZE_FOR_COMPRESSION)); if (doCompression) { int origSize = data.size(); std::cerr << "Compressing message of length " << data.size() << " bytes (" << msg.getId() << ")" << std::endl; - DEBUG("Raw data: " + SPELLutils::dumpString(data) + " size " + ISTR(data.length()) ); + //DEBUG("Raw data: " + SPELLutils::dumpString(data) + " size " + ISTR(data.length()) ); SPELLcompression compressor(data); data = compressor.compress(); - DEBUG("Compressed data: " + SPELLutils::dumpString(data) + " size " + ISTR(data.length()) ); + //DEBUG("Compressed data: " + SPELLutils::dumpString(data) + " size " + ISTR(data.length()) ); double ratio = ((double) origSize - (double) data.size())/((double)origSize) * 100.0; std::cerr << "Compressed to " << data.size() << " bytes (ratio " << std::setprecision(2) << ratio << "%)" << std::endl; } @@ -109,6 +113,8 @@ void SPELLipcOutput::send( SPELLipcMessage& msg ) data = (doCompression ? COMPRESSION_FLAG_TRUE_STR : COMPRESSION_FLAG_FALSE_STR) + data; writeData( data ); + + //DEBUG( NAME + "SEND DONE" ); } catch(SPELLipcError& err) { @@ -118,10 +124,11 @@ void SPELLipcOutput::send( SPELLipcMessage& msg ) LOG_ERROR( NAME + " Connection lost at output " + std::string(err.what()) ); LOG_ERROR( NAME + " Data being sent: " + msg.dataStr()); m_channel.outputFailed(errNo, err.getError()); + throw; } else { - DEBUG( NAME + "Send failed, not connected: " + err.what() + ", errno=" + ISTR(errNo) ); + //DEBUG( NAME + "Send failed, not connected: " + err.what() + ", errno=" + ISTR(errNo) ); } } catch(...) @@ -135,10 +142,10 @@ void SPELLipcOutput::send( SPELLipcMessage& msg ) } else { - DEBUG( NAME + "Send failed, not connected, errno=" + ISTR(errNo) ); + //DEBUG( NAME + "Send failed, not connected, errno=" + ISTR(errNo) ); } } - DEBUG( NAME + "SEND DONE" ); + } //============================================================================= @@ -147,8 +154,8 @@ void SPELLipcOutput::send( SPELLipcMessage& msg ) void SPELLipcOutput::disconnect( bool send_eoc ) { if (!m_connected) return; - - DEBUG( NAME + "SPELLipcOutput disconnect"); + SPELLmonitor m(m_lock); + //DEBUG( NAME + "SPELLipcOutput disconnect"); if (send_eoc) { @@ -157,9 +164,10 @@ void SPELLipcOutput::disconnect( bool send_eoc ) eoc.setType( MSG_TYPE_EOC ); eoc.setKey(m_key); send(eoc); - DEBUG( NAME + "EOC sent"); + //DEBUG( NAME + "EOC sent"); } m_connected = false; + } //============================================================================= @@ -167,13 +175,13 @@ void SPELLipcOutput::disconnect( bool send_eoc ) //============================================================================= void SPELLipcOutput::writeData( std::string data ) { - DEBUG( NAME + "Write data TRY-IN"); - SPELLmonitor m(m_lock); - DEBUG( NAME + "Write data IN"); + ////DEBUG( NAME + "Write data TRY-IN"); + + ////DEBUG( NAME + "Write data IN"); if (m_connected) { unsigned int sizeData = data.size(); - //DEBUG( NAME + "Packet length " + ISTR(sizeData)); + ////DEBUG( NAME + "Packet length " + ISTR(sizeData)); int success = 0; @@ -198,11 +206,11 @@ void SPELLipcOutput::writeData( std::string data ) numBytes = sizeData; success = 0; offset = 0; - //DEBUG("writeData sending message: " + SPELLutils::dumpString(data)); + ////DEBUG("writeData sending message: " + SPELLutils::dumpString(data)); while( numBytes > 0 ) { success = m_socket.send(&data[offset],numBytes); - if (success == -1 || errno != 0) + if (success == -1) { throw SPELLipcError( NAME + "Error while sending data, errno " + ISTR(errno) ); } @@ -214,7 +222,7 @@ void SPELLipcOutput::writeData( std::string data ) m_lastSentTime.setCurrent(); } - DEBUG( NAME + "Write data OUT"); + ////DEBUG( NAME + "Write data OUT"); } //============================================================================= @@ -234,21 +242,22 @@ void SPELLipcOutput::run() delta = currentTime - lastTime; if (delta.getSeconds() > PING_PERIOD_SEC) { - std::cerr << "ping [" << NAME << "] " << currentTime.toString() << std::endl; try { - send(m_ping); + SPELLipcMessage ping = this->m_channel.m_ifc.getPingMessage(); + if (ping.isVoid()) { + send(m_ping); + } else { + send(ping); + } } catch(...) { - DEBUG( NAME + "Abort ping loop"); return; } } - DEBUG( NAME + "1"); usleep(2000000); // 2 seconds - DEBUG( NAME + "2"); } - DEBUG( NAME + "Finish ping loop"); + //DEBUG( NAME + "Finish ping loop"); } diff --git a/lib/SPELL_IPC/src/SPELLipcServerInterface.C b/lib/SPELL_IPC/src/SPELLipcServerInterface.C index 5c0d407..3a29092 100644 --- a/lib/SPELL_IPC/src/SPELLipcServerInterface.C +++ b/lib/SPELL_IPC/src/SPELLipcServerInterface.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the interface for servers // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -27,6 +27,7 @@ // FILES TO INCLUDE //////////////////////////////////////////////////////// // Local includes ---------------------------------------------------------- #include "SPELL_IPC/SPELLipcError.H" +#include "SPELL_SYN/SPELLsyncError.H" #include "SPELL_IPC/SPELLipcServerInterface.H" #include "SPELL_IPC/SPELLipcHelper.H" #include "SPELL_IPC/SPELLtimeoutValues.H" @@ -56,7 +57,7 @@ SPELLipcServerInterface::SPELLipcServerInterface( const std::string& name, int k m_serverPort = port; m_clients.clear(); - + m_clientKeysToRemove.clear(); m_serverSocket = NULL; m_ifcName = name; @@ -125,6 +126,19 @@ void SPELLipcServerInterface::run() bool disconnected = false; SPELLsocket* clientSocket = m_serverSocket->acceptClient( &disconnected ); + if (clientSocket == NULL && !m_clientKeysToRemove.empty()) + { + SPELLmonitor m(m_clientCleanupLock); + SPELLmonitor m2(m_clientLock); + + std::vector::const_iterator it = m_clientKeysToRemove.begin(); + while(it != m_clientKeysToRemove.end()) + { + removeClientInternal(*it); + ++it; + } + m_clientKeysToRemove.clear(); + } if ((!disconnected)&&clientSocket != NULL) { LOG_INFO(NAME + "Accepted new client connection"); @@ -159,6 +173,10 @@ void SPELLipcServerInterface::run() { LOG_ERROR("Failed to accept client: " + err.what()); } + catch(SPELLsyncError& err) + { + LOG_ERROR("Failed to accept client: " + err.what()); + } } if (disconnected) return; @@ -213,7 +231,8 @@ bool SPELLipcServerInterface::hasClient( int key ) DEBUG(NAME + "Has client TRY-IN"); SPELLmonitor m(m_clientLock); DEBUG(NAME + "Has client OUT"); - return ( m_clients.find(key) != m_clients.end() ); + SPELLipcChannelMap::iterator client = m_clients.find(key); + return ( client != m_clients.end() && client->second != NULL ); } //============================================================================= @@ -223,12 +242,11 @@ void SPELLipcServerInterface::addClient( int key, SPELLsocket* skt ) { DEBUG( NAME + "add Client TRY-IN"); - SPELLmonitor m(m_clientLock); - SPELLipcChannel* channel = new SPELLipcChannel( std::string(m_ifcName), skt, key, *this ); channel->connect(); - m_clients.insert( std::make_pair( key, channel )); + SPELLmonitor m(m_clientLock); + m_clients[key] = channel; LOG_INFO(NAME + "Added client " + ISTR(key)); m_clientConnectionEvent.set(); } @@ -237,6 +255,13 @@ void SPELLipcServerInterface::addClient( int key, SPELLsocket* skt ) // METHOD: SPELLipcServerInterface:removeClient //============================================================================= void SPELLipcServerInterface::removeClient( int key ) +{ + SPELLmonitor m(m_clientCleanupLock); + m_clientKeysToRemove.push_back(key); +} + + +void SPELLipcServerInterface::removeClientInternal( int key ) { if (!hasClient(key)) { @@ -244,12 +269,22 @@ void SPELLipcServerInterface::removeClient( int key ) } DEBUG( NAME + "Remove client TRY-IN" ); - SPELLmonitor m(m_clientLock); - SPELLipcChannelMap::iterator cit = m_clients.find(key); - cit->second->disconnect(); - delete cit->second; - m_clients.erase(cit); + if (cit->second != NULL) + { + cit->second->disconnect(); + + m_clientLock.unlock(); + m_clientCleanupLock.unlock(); + delete cit->second; + m_clientCleanupLock.lock(); + m_clientLock.lock(); + + // FIXME: Clearing clients may invalidate references in other threads + // resulting in a crash. This ought to be fixed with the new IPC layer. + //m_clients.erase(cit); + m_clients[cit->first] = NULL; + } std::vector::iterator kit = std::find(m_usedClientKeys.begin(), m_usedClientKeys.end(), key); if (kit != m_usedClientKeys.end()) { @@ -270,12 +305,20 @@ void SPELLipcServerInterface::removeAllClients() for( cit = m_clients.begin(); cit != m_clients.end(); cit++) { DEBUG(NAME + "Removing client " + ISTR(cit->first)); - cit->second->disconnect(); - delete cit->second; + if (cit->second != NULL) + { + cit->second->disconnect(); + delete cit->second; + m_clients[cit->first] = NULL; + } + DEBUG(NAME + "Removing client " + ISTR(cit->first) + " done" ); } m_usedClientKeys.clear(); - m_clients.clear(); + m_clientKeysToRemove.clear(); + // FIXME: Clearing clients may invalidate references in other threads + // resulting in a crash. This ought to be fixed with the new IPC layer. + //m_clients.clear(); DEBUG( NAME + "Remove all clients OUT"); } @@ -339,7 +382,7 @@ void SPELLipcServerInterface::connectionLost( int peerKey, int errNo, const std: cit = m_clients.find(peerKey); } } - if (cit != m_clients.end()) + if (cit != m_clients.end() && cit->second != NULL) { LOG_INFO(NAME + "#### Peer " + ISTR(peerKey) + " reconnected!"); } @@ -376,8 +419,9 @@ void SPELLipcServerInterface::sendMessage( int peerKey, SPELLipcMessage& msg ) { // Must set the appropriate key to the message beforehand. The key info is used // to identify requests and their responses + SPELLmonitor m(m_clientLock); msg.setKey(peerKey); - getChannel(peerKey).getWriter().send(msg); + (*getChannel(peerKey))->getWriter().send(msg); } catch(SPELLipcError& err) { @@ -397,9 +441,10 @@ SPELLipcMessage SPELLipcServerInterface::sendRequest( int peerKey, SPELLipcMessa DEBUG(NAME + "Get writer for peer " + ISTR(peerKey)); // Must set the appropriate key to the message beforehand. The key info is used // to identify requests and their responses + SPELLmonitor m(m_clientLock); msg.setKey(peerKey); DEBUG(NAME + "Sending now request to peer " + ISTR(peerKey)); - resp = performRequest( getChannel(peerKey), msg, timeoutMsec ); + resp = performRequest( **getChannel(peerKey), msg, timeoutMsec ); } catch( SPELLipcError& err ) { @@ -418,16 +463,16 @@ SPELLipcMessage SPELLipcServerInterface::sendRequest( int peerKey, SPELLipcMessa //============================================================================= // METHOD: SPELLipcServerInterface:getChannel //============================================================================= -SPELLipcChannel& SPELLipcServerInterface::getChannel( int peerKey ) +SPELLipcChannel** SPELLipcServerInterface::getChannel( int peerKey ) { - DEBUG( NAME + "Get channel TRY-IN" ); + //DEBUG( NAME + "Get channel TRY-IN" ); SPELLmonitor m(m_clientLock); SPELLipcChannelMap::iterator cit = m_clients.find(peerKey); - if (cit != m_clients.end()) + if (cit != m_clients.end() && cit->second != NULL) { - DEBUG( NAME + "Get channel OUT" ); - return *cit->second; + //DEBUG( NAME + "Get channel OUT" ); + return &m_clients[peerKey]; } DEBUG( NAME + "Get channel FAIL" ); throw SPELLipcError("Cannot get writer, no such key: " + ISTR(peerKey)); @@ -514,11 +559,11 @@ void SPELLipcServerInterface::cancelOutgoingRequests( int peerKey ) DEBUG(NAME + "Cancel outgoing requests for peer " + ISTR(peerKey)); // Obtain the channel corresponding to the client - SPELLipcChannel& channel = getChannel(peerKey); + SPELLipcChannel* channel = *getChannel(peerKey); // Iterate over the list of ongoing requests, and cancel the requests in the mailbox std::vector::iterator it; - std::vector requestList = channel.getOngoingRequests(); + std::vector requestList = channel->getOngoingRequests(); for( it = requestList.begin(); it != requestList.end(); it++) { DEBUG(NAME + " - cancel " + *it); @@ -543,7 +588,7 @@ void SPELLipcServerInterface::cancelIncomingRequests( int peerKey ) //============================================================================= void SPELLipcServerInterface::incomingRequest( const SPELLipcMessage& msg ) { - DEBUG(NAME + "IPC interface incoming request TRY IN (" + msg.getSequenceStr() + ")"); + //DEBUG(NAME + "IPC interface incoming request TRY IN (" + msg.getSequenceStr() + ")"); { SPELLmonitor m(m_ipcLock); @@ -559,23 +604,24 @@ void SPELLipcServerInterface::incomingRequest( const SPELLipcMessage& msg ) } } - DEBUG(NAME + "IPC interface incoming request IN (" + msg.getSequenceStr() + ")"); + //DEBUG(NAME + "IPC interface incoming request IN (" + msg.getSequenceStr() + ")"); try { - DEBUG(NAME + "Creating request processor (" + msg.getSequenceStr() + ")"); - SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, getChannel(msg.getKey()).getWriter(), *m_listener ); + //DEBUG(NAME + "Creating request processor (" + msg.getSequenceStr() + ")"); + SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg,m_clientLock, getChannel(msg.getKey()), *m_listener ); ireq->start(); - DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")"); - ireq->waitStarted(); + //DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")"); + // TODO: No reason to wait here. Remove once validated. + //ireq->waitStarted(); { - DEBUG(NAME + "Place in trash"); + //DEBUG(NAME + "Place in trash"); SPELLmonitor m(m_ipcLock); m_trash.place(ireq); - DEBUG(NAME + "Place in trash DONE"); + //DEBUG(NAME + "Place in trash DONE"); } - DEBUG(NAME + "Creating request processor DONE (" + msg.getSequenceStr() + ")"); + //DEBUG(NAME + "Creating request processor DONE (" + msg.getSequenceStr() + ")"); } catch(SPELLipcError& err) { @@ -597,19 +643,20 @@ void SPELLipcServerInterface::incomingMessage( const SPELLipcMessage& msg ) if (m_listener == NULL) return; } - DEBUG(NAME + "Creating message processor"); + //DEBUG(NAME + "Creating message processor"); SPELLipcIncomingMessage* imsg = new SPELLipcIncomingMessage( msg.requestId(), m_ifcName, msg, *m_listener); imsg->start(); - DEBUG(NAME + "Wait processor to start"); - imsg->waitStarted(); + //DEBUG(NAME + "Wait processor to start"); + // TODO: No reason to wait here. Remove once validated. + //imsg->waitStarted(); { - DEBUG(NAME + "Place in trash"); + //DEBUG(NAME + "Place in trash"); SPELLmonitor m(m_ipcLock); m_trash.place(imsg); - DEBUG(NAME + "Place in trash DONE"); + //DEBUG(NAME + "Place in trash DONE"); } - DEBUG(NAME + "IPC interface incoming message OUT"); + //DEBUG(NAME + "IPC interface incoming message OUT"); } //============================================================================= diff --git a/lib/SPELL_IPC/src/SPELLipcServerInterfaceSingle.C b/lib/SPELL_IPC/src/SPELLipcServerInterfaceSingle.C index 980740c..a8e12c0 100644 --- a/lib/SPELL_IPC/src/SPELLipcServerInterfaceSingle.C +++ b/lib/SPELL_IPC/src/SPELLipcServerInterfaceSingle.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the interface for single client servers // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -49,7 +49,8 @@ SPELLipcServerInterfaceSingle::SPELLipcServerInterfaceSingle( const std::string& m_connected(false), m_trash(name), m_ipcSequence(0), - m_mailbox(name) + m_mailbox(name), + m_removeClient(false) { m_serverKey = key; m_serverPort = port; @@ -73,6 +74,7 @@ SPELLipcServerInterfaceSingle::~SPELLipcServerInterfaceSingle() { DEBUG(NAME + "Destroying server interface"); DEBUG(NAME + "Server interface destroyed"); + removeClientInternal(); } //============================================================================= @@ -116,12 +118,14 @@ void SPELLipcServerInterfaceSingle::run() DEBUG(" - Entering select loop"); DEBUG(NAME + "Accepting connections"); - while(isConnected()) { bool disconnected = false; SPELLsocket* clientSocket = m_serverSocket->acceptClient( &disconnected ); - + if (clientSocket == NULL && m_removeClient) + { + removeClientInternal(); + } if ( (!disconnected) && (clientSocket != NULL) && (isConnected()) ) { LOG_INFO(NAME + "Accepted new client connection"); @@ -172,7 +176,7 @@ void SPELLipcServerInterfaceSingle::addClient( SPELLsocket* skt ) DEBUG( NAME + "add Client TRY-IN"); SPELLmonitor m(m_clientLock); - + m_removeClient = false; m_channel = new SPELLipcChannel( std::string(m_ifcName), skt, 1, *this ); m_channel->connect(); @@ -185,22 +189,27 @@ void SPELLipcServerInterfaceSingle::addClient( SPELLsocket* skt ) //============================================================================= void SPELLipcServerInterfaceSingle::removeClient() { - DEBUG( NAME + "Remove client TRY-IN" ); - SPELLmonitor m(m_clientLock); + m_removeClient = true; +} + +void SPELLipcServerInterfaceSingle::removeClientInternal() +{ + SPELLmonitor m(m_cleanupLock); if (m_channel) { - m_channel->disconnect(); - delete m_channel; - m_channel = NULL; + m_channel->disconnect(); + delete m_channel; + m_channel = NULL; + m_removeClient = false; } - DEBUG( NAME + "Remove client OUT" ); -} +} //============================================================================= // METHOD: SPELLipcServerInterfaceSingle:disconnect //============================================================================= void SPELLipcServerInterfaceSingle::disconnect() { + DEBUG(NAME + "Server interface disconnect TRY-IN"); if (!isConnected()) return; DEBUG(NAME + "Server interface disconnect ALL IN"); @@ -220,7 +229,7 @@ void SPELLipcServerInterfaceSingle::disconnect() //DEBUG(NAME + "Shutdown thread pool"); //m_msgPool.shutdown(); DEBUG(NAME + "Removing clients"); - removeClient(); + removeClientInternal(); LOG_INFO(NAME + "Wait to end..."); join(); LOG_INFO(NAME + "Server interface disconnected"); @@ -272,11 +281,14 @@ void SPELLipcServerInterfaceSingle::sendMessage( SPELLipcMessage& msg ) DEBUG(NAME + "Send message to peer"); try { - SPELLipcOutput& writer = m_channel->getWriter(); - // Must set the appropriate key to the message beforehand. The key info is used - // to identify requests and their responses - msg.setKey(1); - writer.send(msg); + if (m_channel != NULL) + { + SPELLipcOutput& writer = m_channel->getWriter(); + // Must set the appropriate key to the message beforehand. The key info is used + // to identify requests and their responses + msg.setKey(1); + writer.send(msg); + } } catch(SPELLipcError& err) { @@ -428,15 +440,16 @@ void SPELLipcServerInterfaceSingle::incomingRequest( const SPELLipcMessage& msg } } - DEBUG(NAME + "IPC interface incoming request IN (" + msg.getSequenceStr() + ")"); + DEBUG(NAME + "IPC interface incoming request IN (" + msg.getSequenceStr() + ") for ("+msg.get("User")+")"); try { DEBUG(NAME + "Creating request processor (" + msg.getSequenceStr() + ")"); - SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, m_channel->getWriter(), *m_listener ); + SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, m_clientLock,&m_channel, *m_listener ); ireq->start(); DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")"); - ireq->waitStarted(); + // TODO: No reason to wait here. Remove once validated. + //ireq->waitStarted(); DEBUG(NAME + "Place in trash"); m_trash.place(ireq); DEBUG(NAME + "Place in trash DONE"); @@ -456,9 +469,9 @@ void SPELLipcServerInterfaceSingle::incomingRequest( const SPELLipcMessage& msg //============================================================================= void SPELLipcServerInterfaceSingle::incomingMessage( const SPELLipcMessage& msg ) { - DEBUG(NAME + "IPC interface incoming message TRY IN"); + // DEBUG(NAME + "IPC interface incoming message TRY IN"); SPELLmonitor m(m_incomingLock); - DEBUG(NAME + "IPC interface incoming message IN " + msg.getId()); + // DEBUG(NAME + "IPC interface incoming message IN " + msg.getId()); { SPELLmonitor m(m_ipcLock); if (!isConnected()) return; @@ -468,18 +481,29 @@ void SPELLipcServerInterfaceSingle::incomingMessage( const SPELLipcMessage& msg DEBUG(NAME + "Creating message processor"); while(m_trash.size()>50) { - //LOG_WARN(NAME + "Waiting for free space in queue"); - usleep(2000); + m_trash.clearData(); + if (m_trash.size()>50) + { + LOG_WARN(NAME + "Waiting for free space in queue"); + usleep(50000); + } + } + SPELLipcInterfaceListener* listener = m_listener; + if (listener != NULL){ + SPELLipcIncomingMessage* imsg = new SPELLipcIncomingMessage( msg.requestId(), m_ifcName, msg, *listener); + imsg->start(); + //DEBUG(NAME + "Wait processor to start"); + // TODO: No reason to wait here. Remove once validated. + //imsg->waitStarted(); + // DEBUG(NAME + "Place in trash"); + m_trash.place(imsg); + } else { + LOG_WARN("!! Request discarded: no listener: " + msg.getId()); } - SPELLipcIncomingMessage* imsg = new SPELLipcIncomingMessage( msg.requestId(), m_ifcName, msg, *m_listener); - imsg->start(); - DEBUG(NAME + "Wait processor to start"); - imsg->waitStarted(); - DEBUG(NAME + "Place in trash"); - m_trash.place(imsg); - DEBUG(NAME + "Place in trash DONE"); - - DEBUG(NAME + "IPC interface incoming message OUT"); + + // DEBUG(NAME + "Place in trash DONE"); + + // DEBUG(NAME + "IPC interface incoming message OUT"); } //============================================================================= diff --git a/lib/SPELL_IPC/src/SPELLipcTrash.C b/lib/SPELL_IPC/src/SPELLipcTrash.C index 3b7ce91..8789ebf 100644 --- a/lib/SPELL_IPC/src/SPELLipcTrash.C +++ b/lib/SPELL_IPC/src/SPELLipcTrash.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the request cleaner // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -137,7 +137,7 @@ void SPELLipcTrash::run() while(isWorking()) { if (haveData()) clearData(); - usleep(350000); + usleep(50000); } if (haveData()) clearData(); m_trashFinishEvent.set(); @@ -167,7 +167,7 @@ bool SPELLipcTrash::haveData() //============================================================================= unsigned int SPELLipcTrash::size() { - SPELLmonitor m(m_dataLock); + SPELLmonitor m(m_dataLock); return m_messages.size(); } @@ -181,22 +181,26 @@ void SPELLipcTrash::clearData() for( it = m_messages.begin(); it != m_messages.end(); it++) { - DEBUG( NAME + "Waiting for " + (*it)->getSequence() ); + //DEBUG( NAME + "Waiting for " + (*it)->getSequence() ); if ((*it)->isStarted()) { - bool timedout = (*it)->wait(500); // milliseconds + bool timedout = (*it)->wait(25); // milliseconds if (!timedout) { - DEBUG( NAME + "Joining " + (*it)->getSequence() ); - (*it)->join(); - DEBUG( NAME + "************ Deleting " + (*it)->getSequence() ); - delete (*it); - it = m_messages.erase(it); - DEBUG( NAME + "Deleted"); + if (!*it) { + it = m_messages.erase(it); + } else { + //DEBUG( NAME + "Joining " + (*it)->getSequence() ); + (*it)->join(); + //DEBUG( NAME + "************ Deleting " + (*it)->getSequence() ); + delete (*it); + it = m_messages.erase(it); + //DEBUG( NAME + "Deleted"); + } } else { - DEBUG( NAME + "Did not delete " + (*it)->getSequence() ); + //DEBUG( NAME + "Did not delete " + (*it)->getSequence() ); } } } diff --git a/lib/SPELL_IPC/src/SPELLsocket.C b/lib/SPELL_IPC/src/SPELLsocket.C index 29a651e..83f0f65 100644 --- a/lib/SPELL_IPC/src/SPELLsocket.C +++ b/lib/SPELL_IPC/src/SPELLsocket.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the socket wrapper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -38,14 +38,16 @@ #include #include #include - +#include +#include +#include // DEFINES ///////////////////////////////////////////////////////////////// //============================================================================= // CONSTRUCTOR: SPELLsocket::SPELLsocket //============================================================================= -SPELLsocket::SPELLsocket( int fd ) +SPELLsocket::SPELLsocket( int fd , std::string user, std::vector groups) : user(user), groups(groups) { m_socketFd = fd; m_connected = true; @@ -90,9 +92,13 @@ int SPELLsocket::send( const void* buffer, int size ) { //DEBUGX(std::string tmp); if (!m_connected) return 0; - int numWritten = write(m_socketFd,buffer,size); + int numWritten = ::send(m_socketFd,buffer,size,MSG_NOSIGNAL); //DEBUGX(tmp.assign((char*) buffer, ((char*)buffer) + numWritten)); - //DEBUG("SPELL SOCKET WROTE (" + ISTR(numWritten) + "):" + SPELLutils::dumpString(tmp)); + + if (errno > 0) { + //perror("send"); + LOG_ERROR("[SKT] Socket " + ISTR(m_socketFd) + " encountered error: " + ISTR(errno) + " bytes written: " + ISTR(numWritten) + "/" + ISTR(size)); + } return numWritten; } @@ -139,6 +145,63 @@ void SPELLsocket::close() ::close(m_socketFd); } +std::string _exec(std::string cmd) { + char buffer[128]; + std::string result = ""; + FILE* pipe = popen(cmd.c_str(), "r"); + if (!pipe) + return ""; + try { + while (fgets(buffer, sizeof buffer, pipe) != NULL) { + result += buffer; + } + } catch (...) { + pclose(pipe); + throw; + } + pclose(pipe); + std::string::size_type i = 0; + while (i < result.length()) { + i = result.find('\n', i); + if (i == std::string::npos) { + break; + } + result.erase(i); + } + return result; + +} + +std::vector split(std::string& s, const std::string& delimiter) { + std::vector tokens; + size_t pos = 0; + std::string token; + while ((pos = s.find(delimiter)) != std::string::npos) { + token = s.substr(0, pos); + tokens.push_back(token); + s.erase(0, pos + delimiter.length()); + } + tokens.push_back(s); + + return tokens; +} +template +std::string str(T begin, T end) +{ + std::stringstream ss; + bool first = true; + ss << "["; + for (; begin != end; begin++) + { + if (!first) + ss << ", "; + ss << *begin; + first = false; + } + ss << "]"; + return ss.str(); +} + //============================================================================= // METHOD: SPELLsocket::isConnected //============================================================================= @@ -169,10 +232,11 @@ SPELLsocket* SPELLsocket::acceptClient( bool* disconnected ) timeout.tv_usec = 0; // Wait on the file descriptors - int numfds = select( m_socketFd+1, &read_fds, NULL, NULL, &timeout); + int numfds = select( FD_SETSIZE, &read_fds, NULL, NULL, &timeout); if( numfds == -1) { + perror("select"); if (m_connected) { LOG_ERROR("Error on socket select: " + ISTR(errno)); @@ -196,8 +260,32 @@ SPELLsocket* SPELLsocket::acceptClient( bool* disconnected ) } else { + + in_port_t port = ntohs(client_addr.sin_port); +#ifdef WITH_KUBERNETES + DEBUG("Incoming Client from port: " + ISTR(port)); + std::string user = _exec("cat ~spell/procs/users | grep "+ISTR(port)+" | awk -F= '{print $2}'"); + int tries = 10; + while (user == "" && tries-- > 0){ + user = _exec("cat ~spell/procs/users | grep "+ISTR(port)+" | awk -F= '{print $2}'"); + if (user == "") { + usleep(500000); + } + } + std::string groupsStr = _exec("cat ~spell/procs/groups/" + user); + tries = 10; + while (groupsStr == "" && tries-- > 0){ + groupsStr = _exec("cat ~spell/procs/groups/" + user); + if (groupsStr == "") { + usleep(500000); + } + } + groups = split(groupsStr, " "); + + DEBUG("Incoming Client for user: " + user + " groups:" + str(groups.begin(), groups.end())); +#endif *disconnected = false; - return new SPELLsocket( newfd ); + return new SPELLsocket( newfd, user, groups); } } @@ -236,9 +324,10 @@ SPELLsocket* SPELLsocket::connect( const std::string& server, const int& port ) DEBUG(" - Connecting to server at port " + ISTR(port)); if (::connect(socketFd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) { + // perror("connect"); throw SPELLipcError("Error on socket connect: errno " + ISTR(errno)); } - return new SPELLsocket(socketFd); + return new SPELLsocket(socketFd, "spell",{}); } //============================================================================= @@ -246,64 +335,78 @@ SPELLsocket* SPELLsocket::connect( const std::string& server, const int& port ) //============================================================================= SPELLsocket* SPELLsocket::listen( int* port ) { + int retries = 0; + while (retries < 3) + { + if (retries) + usleep(250); + ++retries; - struct sockaddr_in serv_addr; - bzero( (char*) &serv_addr, sizeof(serv_addr)); + struct sockaddr_in serv_addr; + bzero( (char*) &serv_addr, sizeof(serv_addr)); - int socketFd; - // Get the listener socket - if((socketFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) - { - throw SPELLipcError("Error on socket creation, errno " +ISTR(errno) ); - } + int socketFd; + // Get the listener socket + if((socketFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + if (retries < 3) continue; + throw SPELLipcError("Error on socket creation, errno " +ISTR(errno) ); + } - // Set reuse address - int yes = 1; - if(setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) - { - throw SPELLipcError("Error on socket configuration (reuse addr), errno " + ISTR(errno)); - } + // Set reuse address + int32_t yes = 1; + if(setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int32_t)) == -1) + { + if (retries < 3) continue; + throw SPELLipcError("Error on socket configuration (reuse addr), errno " + ISTR(errno)); + } - // Set no linger - struct linger linger; - linger.l_onoff = 1; /*0 = off (l_linger ignored), nonzero = on */ - linger.l_linger =0; /*0 = discard data, nonzero = wait for data sent */ - if(setsockopt(socketFd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1) - { - throw SPELLipcError("Error on socket configuration (linger), errno " + ISTR(errno)); - } + // Set no linger + struct linger linger; + linger.l_onoff = 1; /*0 = off (l_linger ignored), nonzero = on */ + linger.l_linger =0; /*0 = discard data, nonzero = wait for data sent */ + if(setsockopt(socketFd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1) + { + if (retries < 3) continue; + throw SPELLipcError("Error on socket configuration (linger), errno " + ISTR(errno)); + } - // Set keep alive - if(setsockopt(socketFd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(int)) == -1) - { - throw SPELLipcError("Error on socket configuration (keep alive), errno " + ISTR(errno)); - } + // Set keep alive + if(setsockopt(socketFd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(int32_t)) == -1) + { + if (retries < 3) continue; + throw SPELLipcError("Error on socket configuration (keep alive), errno " + ISTR(errno)); + } - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - serv_addr.sin_port = htons(*port); - memset(&(serv_addr.sin_zero), '\0', 8); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + serv_addr.sin_port = htons(*port); + memset(&(serv_addr.sin_zero), '\0', 8); - if (bind(socketFd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) - { - throw SPELLipcError("Error on socket bind, errno " + ISTR(errno)); - } + if (bind(socketFd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) + { + if (retries < 3) continue; + throw SPELLipcError("Error on socket bind, errno " + ISTR(errno)); + } - socklen_t address_len = sizeof serv_addr; - // Get the actual port (chosen by OS if m_serverPort was zero for bind) - if (getsockname( socketFd, (struct sockaddr*) &serv_addr, &address_len )<0) - { - std::cerr << errno << std::endl; - throw SPELLipcError("Error getting socket address, errno " + ISTR(errno) ); - } - *port = ntohs(serv_addr.sin_port); - DEBUG("Listening on port " + ISTR(*port)); + socklen_t address_len = sizeof serv_addr; + // Get the actual port (chosen by OS if m_serverPort was zero for bind) + if (getsockname( socketFd, (struct sockaddr*) &serv_addr, &address_len )<0) + { + if (retries < 3) continue; + throw SPELLipcError("Error getting socket address, errno " + ISTR(errno) ); + } + *port = ntohs(serv_addr.sin_port); + DEBUG("Listening on port " + ISTR(*port)); - if (::listen(socketFd,5) == -1) - { - throw SPELLipcError("Error on listen, errno " + ISTR(errno)); + if (::listen(socketFd,5) == -1) + { + if (retries < 3) continue; + throw SPELLipcError("Error on listen, errno " + ISTR(errno)); + } + return new SPELLsocket( socketFd , "spell",{}); } - return new SPELLsocket( socketFd ); + throw SPELLipcError("Error on listen, errno " + ISTR(errno)); } //============================================================================= diff --git a/lib/SPELL_LST/Makefile.am b/lib/SPELL_LST/Makefile.am index abab52e..09beeaf 100644 --- a/lib/SPELL_LST/Makefile.am +++ b/lib/SPELL_LST/Makefile.am @@ -1,34 +1,41 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_LST.la -libSPELL_LST_la_LDFLAGS = -version-info 3:0:0 -libSPELL_LST_la_SOURCES = \ - src/SPELLlistenerContext.C \ - src/SPELLlistenerGui.C \ - src/SPELLlistener.C - + +lib_LTLIBRARIES = libSPELL_LST_v2.la libSPELL_LST_v3.la + +libSPELL_LST_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_LST_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_LST_v2_la_SOURCES = src/SPELLlistenerContext.C \ + src/SPELLlistenerGui.C \ + src/SPELLlistener.C + +libSPELL_LST_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_LST_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_LST_v3_la_SOURCES = src/SPELLlistenerContext.C \ + src/SPELLlistenerGui.C \ + src/SPELLlistener.C + \ No newline at end of file diff --git a/lib/SPELL_LST/src/SPELLlistener.C b/lib/SPELL_LST/src/SPELLlistener.C index dc78b7c..697784a 100644 --- a/lib/SPELL_LST/src/SPELLlistener.C +++ b/lib/SPELL_LST/src/SPELLlistener.C @@ -5,7 +5,7 @@ // DESCRIPTION: // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -70,7 +70,16 @@ void SPELLlistener::start( const std::string& configFile ) m_contextListener = new SPELLlistenerContext( configFile ); m_guiListener->startup(m_contextListener, NULL); - m_contextListener->startup(m_guiListener, NULL); + m_contextListener->startup(m_guiListener, NULL); + + std::vector ctxList = + SPELLconfiguration::instance().getAvailableContexts(); + + for (std::vector::iterator it = ctxList.begin(); + it != ctxList.end(); it++) + { + m_contextListener->respawnContext((*it)); + } } void SPELLlistener::stop() diff --git a/lib/SPELL_LST/src/SPELLlistenerContext.C b/lib/SPELL_LST/src/SPELLlistenerContext.C index b799db0..564bd7e 100644 --- a/lib/SPELL_LST/src/SPELLlistenerContext.C +++ b/lib/SPELL_LST/src/SPELLlistenerContext.C @@ -5,7 +5,7 @@ // DESCRIPTION: // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -56,7 +56,7 @@ SPELLlistenerContext::SPELLlistenerContext(const std::string& configFile) m_gui = NULL; m_peer = NULL; - + m_ipc = NULL; m_configFile = configFile; m_port = STRI(SPELLconfiguration::instance().getListenerParameter("ContextListenerPort")); m_contextStartupCmd = SPELLconfiguration::instance().getListenerParameter("ContextScript"); @@ -220,6 +220,7 @@ SPELLipcMessage SPELLlistenerContext::startContext( const SPELLipcMessage& msg ) //============================================================================= SPELLipcMessage SPELLlistenerContext::destroyContext( const SPELLipcMessage& msg ) { + LOG_INFO("Destroying context"); std::string name; name = msg.get(MessageField::FIELD_CTX_NAME); @@ -234,11 +235,12 @@ SPELLipcMessage SPELLlistenerContext::destroyContext( const SPELLipcMessage& msg SPELLprocessManager::instance().killProcess("CTX_" + name); SPELLprocessManager::instance().waitProcess("CTX_" + name); SPELLprocessManager::instance().clearProcess("CTX_" + name); + usleep(10000000); + respawnContext(name); } catch(SPELLcoreException& ex) {}; LOG_INFO("Destroyed context"); - return SPELLipcHelper::createResponse(ContextMessages::RSP_DESTROY_CTX, msg); } @@ -312,7 +314,7 @@ SPELLipcMessage SPELLlistenerContext::stopContext( const SPELLipcMessage& msg ) notify.setSender("LST"); notify.setReceiver("GUI"); m_gui->displace(¬ify); - + //respawnContext(ctxInfo->m_name); } catch(SPELLcoreException& ex) {}; } @@ -412,14 +414,26 @@ void SPELLlistenerContext::fillContextInfo(const std::string ctxName, SPELLipcMe std::string driverName; SPELLcontextConfig* ctxConfig; SPELLdriverConfig* drvConfig; - ContextInfo* ctxInfo; + std::map::iterator ctxInfo; - ctxInfo = &m_openContexts[ctxName]; - ctxConfig = ctxInfo->m_ctxConfig; - drvConfig = ctxInfo->m_drvConfig; + ctxInfo = m_openContexts.find(ctxName); + if (ctxInfo == m_openContexts.end()){ + msg.set(MessageField::FIELD_CTX_NAME, "Unknown"); + msg.set(MessageField::FIELD_CTX_PORT, ISTR(0) ); + msg.set(MessageField::FIELD_CTX_DRV, "Unknown"); + msg.set(MessageField::FIELD_CTX_SC, "Unknown"); + msg.set(MessageField::FIELD_CTX_FAM, "Unknown"); + msg.set(MessageField::FIELD_CTX_GCS, "Unknown"); + msg.set(MessageField::FIELD_CTX_DESC, "Unknown"); + msg.set(MessageField::FIELD_CTX_STATUS, "ERROR"); + msg.set(MessageField::FIELD_CTX_MAXPROC, "0" ); + return; + } + ctxConfig = ctxInfo->second.m_ctxConfig; + drvConfig = ctxInfo->second.m_drvConfig; msg.set(MessageField::FIELD_CTX_NAME, ctxName); - msg.set( MessageField::FIELD_CTX_PORT, ISTR(ctxInfo->m_port) ); + msg.set( MessageField::FIELD_CTX_PORT, ISTR(ctxInfo->second.m_port) ); if (ctxConfig != NULL) { @@ -428,7 +442,7 @@ void SPELLlistenerContext::fillContextInfo(const std::string ctxName, SPELLipcMe msg.set(MessageField::FIELD_CTX_FAM, ctxConfig->getFamily()); msg.set(MessageField::FIELD_CTX_GCS, ctxConfig->getGCS()); msg.set(MessageField::FIELD_CTX_DESC, ctxConfig->getDescription()); - msg.set(MessageField::FIELD_CTX_STATUS, ctxInfo->m_status); + msg.set(MessageField::FIELD_CTX_STATUS, ctxInfo->second.m_status); } else { @@ -507,7 +521,7 @@ SPELLipcMessage SPELLlistenerContext::displace( const SPELLipcMessage& msg ) else if (msg.getId() == ContextMessages::REQ_DESTROY_CTX) res = this->destroyContext(msg); else - LOG_ERROR("Unprocessed message: " + msg.getId()) + LOG_ERROR("Unprocessed message: " + msg.getId()); DEBUG("Response IPC object: " + res.dataStr()); @@ -517,7 +531,7 @@ SPELLipcMessage SPELLlistenerContext::displace( const SPELLipcMessage& msg ) //============================================================================= // METHOD: SPELLlistenerContext::processStarted //============================================================================= -void SPELLlistenerContext::processStarted( const std::string& identifier ) +void SPELLlistenerContext::processStarted( const std::string identifier ) { LOG_INFO("Context process started: " + identifier); } @@ -525,7 +539,7 @@ void SPELLlistenerContext::processStarted( const std::string& identifier ) //============================================================================= // METHOD: SPELLlistenerContext::processFinished //============================================================================= -void SPELLlistenerContext::processFinished( const std::string& identifier, const int& retValue ) +void SPELLlistenerContext::processFinished( const std::string identifier, const int& retValue ) { LOG_INFO("Context process finished: " + identifier); } @@ -533,7 +547,7 @@ void SPELLlistenerContext::processFinished( const std::string& identifier, const //============================================================================= // METHOD: SPELLlistenerContext::processKilled //============================================================================= -void SPELLlistenerContext::processKilled( const std::string& identifier ) +void SPELLlistenerContext::processKilled( const std::string identifier ) { ContextInfo* ctxInfo; std::string ctxName = identifier.substr(4); @@ -551,18 +565,25 @@ void SPELLlistenerContext::processKilled( const std::string& identifier ) notify.setReceiver("GUI"); m_gui->displace(¬ify); DEBUG("Process killed processing done"); + usleep(10000000); + respawnContext(ctxName); } //============================================================================= // METHOD: SPELLlistenerContext::processFailed //============================================================================= -void SPELLlistenerContext::processFailed( const std::string& identifier ) +void SPELLlistenerContext::processFailed( const std::string identifier ) { ContextInfo* ctxInfo; LOG_ERROR("Context " + identifier + " failed"); ctxInfo = &m_openContexts[identifier.substr(4)]; ctxInfo->m_status = MessageValue::DATA_CTX_ERROR; - m_ipc->disconnect(); + try { + m_ipc->disconnectClient(ctxInfo->m_key); + } catch(SPELLcoreException& ex) + { + + } // Notify to other clients SPELLipcMessage notify( ListenerMessages::MSG_CONTEXT_OP ); @@ -572,8 +593,11 @@ void SPELLlistenerContext::processFailed( const std::string& identifier ) notify.setSender("LST"); notify.setReceiver("GUI"); m_gui->displace(¬ify); + usleep(10000000); + respawnContext(ctxInfo->m_name); } + //============================================================================= // METHOD: SPELLlistenerContext::notifyClients //============================================================================= diff --git a/lib/SPELL_LST/src/SPELLlistenerGui.C b/lib/SPELL_LST/src/SPELLlistenerGui.C index 44f5774..56b2ed2 100644 --- a/lib/SPELL_LST/src/SPELLlistenerGui.C +++ b/lib/SPELL_LST/src/SPELLlistenerGui.C @@ -5,7 +5,7 @@ // DESCRIPTION: // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -46,6 +46,9 @@ SPELLlistenerGui::SPELLlistenerGui(const std::string& configFile) m_configFile = configFile; m_port = STRI(SPELLconfiguration::instance().getListenerParameter("ListenerPort")); m_peer = NULL; + m_ctx = NULL; + m_peer = NULL; + m_ipc = NULL; } //============================================================================= diff --git a/lib/SPELL_PRC/Makefile.am b/lib/SPELL_PRC/Makefile.am index a29aed2..3836e60 100644 --- a/lib/SPELL_PRC/Makefile.am +++ b/lib/SPELL_PRC/Makefile.am @@ -1,33 +1,38 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_PRC.la -libSPELL_PRC_la_LDFLAGS = -version-info 3:0:0 -libSPELL_PRC_la_SOURCES = \ - src/SPELLprocess.C \ - src/SPELLprocessManager.C - + +lib_LTLIBRARIES = libSPELL_PRC_v2.la libSPELL_PRC_v3.la + +libSPELL_PRC_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_PRC_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_PRC_v2_la_SOURCES = src/SPELLprocess.C \ + src/SPELLprocessManager.C + +libSPELL_PRC_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_PRC_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_PRC_v3_la_SOURCES = src/SPELLprocess.C \ + src/SPELLprocessManager.C \ No newline at end of file diff --git a/lib/SPELL_PRC/src/SPELLprocess.C b/lib/SPELL_PRC/src/SPELLprocess.C index 042ade7..674f4c1 100644 --- a/lib/SPELL_PRC/src/SPELLprocess.C +++ b/lib/SPELL_PRC/src/SPELLprocess.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of process model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -103,6 +103,7 @@ SPELLprocess::SPELLprocess( std::string identifier, int pid, SPELLprocessManager SPELLprocess::~SPELLprocess() { DEBUG("[PRC] PROCESS " + m_identifier + " DESTROYED"); + this->join(); } //============================================================================= @@ -117,6 +118,7 @@ void SPELLprocess::run() m_statusCode = PSTATUS_INITIAL; try { + LOG_INFO("Starting process with command '" + m_command + "'"); m_processPID = popen( m_command ); } catch(SPELLcoreException& ex) @@ -223,7 +225,7 @@ void SPELLprocess::run() m_statusCode = PSTATUS_RUNNING; m_pManager->fireProcessStarted( m_identifier ); - bool repeat = false; + bool repeat = true; do { if ( !SPELLutils::pathExists( "/proc/" + ISTR(m_processPID) + "/stat" ) ) @@ -243,7 +245,7 @@ void SPELLprocess::run() } else { - usleep(1000); + usleep(100000); } } while(repeat); @@ -303,7 +305,7 @@ pid_t SPELLprocess::popen( std::string command ) } else if (pid == 0) { - if (execl("/bin/sh", "sh", "-c", command.c_str(), NULL) != 0) + if (execl("/bin/bash", "bash", "-c", command.c_str(), NULL) != 0) { std::cerr << "####################################################################" << std::endl; std::cerr << "####################################################################" << std::endl; diff --git a/lib/SPELL_PRC/src/SPELLprocessManager.C b/lib/SPELL_PRC/src/SPELLprocessManager.C index 8a5e911..c68daa9 100644 --- a/lib/SPELL_PRC/src/SPELLprocessManager.C +++ b/lib/SPELL_PRC/src/SPELLprocessManager.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of process manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -34,7 +34,7 @@ #include "SPELL_UTIL/SPELLbase.H" #include "SPELL_UTIL/SPELLerror.H" #include "SPELL_UTIL/SPELLlog.H" - +#include "SPELL_UTIL/SPELLutils.H" // GLOBALS ///////////////////////////////////////////////////////////////// @@ -56,6 +56,7 @@ SPELLprocessManager::SPELLprocessManager() //============================================================================= SPELLprocessManager::~SPELLprocessManager() { + m_processes.clear(); m_listeners.clear(); } @@ -81,6 +82,9 @@ void SPELLprocessManager::startProcess( const std::string& identifier, const std DEBUG("[PRCMGR] Starting process " + identifier); SPELLprocess* process = new SPELLprocess(identifier,command,this); process->start(); + if (m_processes.count(identifier) > 0) + LOG_ERROR("[PRCMGR] ProcessId " + identifier + " already exists!!!"); + m_processes.insert( std::make_pair( identifier, process )); DEBUG("[PRCMGR] Starting process " + identifier + " done"); } @@ -143,15 +147,32 @@ void SPELLprocessManager::killProcess( const std::string& identifier ) DEBUG("[PRCMGR] Kill process " + identifier + " done"); } +bool SPELLprocessManager::checkProcessExist( const std::string& identifier ) +{ + SPELLmonitor m(m_lock); + DEBUG("[PRCMGR] Checking process " + identifier); + SPELLprocessMap::iterator it = m_processes.find(identifier); + if (it == m_processes.end() ) + { + return false; + } + return true; + +} + //============================================================================= // METHOD : SPELLprocessManager::waitProcess() //============================================================================= int SPELLprocessManager::waitProcess( const std::string& identifier ) { - SPELLprocessMap::iterator it = m_processes.find(identifier); - if (it == m_processes.end() ) + SPELLprocessMap::iterator it; { - THROW_EXCEPTION("Cannot wait process " + identifier, "Not found", SPELL_ERROR_PROCESS); + SPELLmonitor m(m_lock); + it = m_processes.find(identifier); + if (it == m_processes.end() ) + { + THROW_EXCEPTION("Cannot wait process " + identifier, "Not found", SPELL_ERROR_PROCESS); + } } return it->second->wait(); } @@ -161,6 +182,7 @@ int SPELLprocessManager::waitProcess( const std::string& identifier ) //============================================================================= SPELLprocessStatus SPELLprocessManager::getProcessStatus( const std::string& identifier ) { + SPELLmonitor m(m_lock); SPELLprocessMap::iterator it = m_processes.find(identifier); if (it == m_processes.end() ) { @@ -174,11 +196,14 @@ SPELLprocessStatus SPELLprocessManager::getProcessStatus( const std::string& ide //============================================================================= void SPELLprocessManager::clearProcess( const std::string& identifier ) { + SPELLmonitor m(m_lock); DEBUG("[PRCMGR] Clear process " + identifier); SPELLprocessMap::iterator pit = m_processes.find(identifier); if (pit != m_processes.end()) { + m_lock.unlock(); pit->second->join(); + m_lock.lock(); delete pit->second; m_processes.erase(pit); DEBUG("[PRCMGR] Clear process " + identifier + " done"); @@ -230,14 +255,14 @@ void SPELLprocessManager::removeListener( const std::string& identifier, SPELLpr //============================================================================= // METHOD : SPELLprocessManager::fireProcessStarted() //============================================================================= -void SPELLprocessManager::fireProcessStarted( const std::string& identifier ) +void SPELLprocessManager::fireProcessStarted( const std::string identifier ) { - SPELLmonitor m(m_lock); DEBUG("[PRCMGR] Firing process started: " + identifier); - SPELLprocessListenersMap::iterator mit = m_listeners.find(identifier); + SPELLprocessListenersMap listeners = m_listeners; + SPELLprocessListenersMap::iterator mit = listeners.find(identifier); if (mit != m_listeners.end()) { - SPELLprocessListeners& list = mit->second; + SPELLprocessListeners list = mit->second; SPELLprocessListeners::iterator it; for( it = list.begin(); it != list.end(); it++) { @@ -253,14 +278,14 @@ void SPELLprocessManager::fireProcessStarted( const std::string& identifier ) //============================================================================= // METHOD : SPELLprocessManager::fireProcessFinished() //============================================================================= -void SPELLprocessManager::fireProcessFinished( const std::string& identifier, int retValue ) +void SPELLprocessManager::fireProcessFinished( std::string identifier, int retValue ) { - SPELLmonitor m(m_lock); DEBUG("[PRCMGR] Firing process finished: " + identifier); - SPELLprocessListenersMap::iterator mit = m_listeners.find(identifier); + SPELLprocessListenersMap listeners = m_listeners; + SPELLprocessListenersMap::iterator mit = listeners.find(identifier); if (mit != m_listeners.end()) { - SPELLprocessListeners& list = mit->second; + SPELLprocessListeners list = mit->second; SPELLprocessListeners::iterator it; for( it = list.begin(); it != list.end(); it++) { @@ -276,14 +301,14 @@ void SPELLprocessManager::fireProcessFinished( const std::string& identifier, in //============================================================================= // METHOD : SPELLprocessManager::fireProcessKilled() //============================================================================= -void SPELLprocessManager::fireProcessKilled( const std::string& identifier ) +void SPELLprocessManager::fireProcessKilled( std::string identifier ) { - SPELLmonitor m(m_lock); DEBUG("[PRCMGR] Firing process killed: " + identifier); - SPELLprocessListenersMap::iterator mit = m_listeners.find(identifier); + SPELLprocessListenersMap listeners = m_listeners; + SPELLprocessListenersMap::iterator mit = listeners.find(identifier); if (mit != m_listeners.end()) { - SPELLprocessListeners& list = mit->second; + SPELLprocessListeners list = mit->second; SPELLprocessListeners::iterator it; for( it = list.begin(); it != list.end(); it++) { @@ -294,20 +319,19 @@ void SPELLprocessManager::fireProcessKilled( const std::string& identifier ) } } } - DEBUG("[PRCMGR] Firing process killed done: " + identifier); } //============================================================================= // METHOD : SPELLprocessManager::fireProcessFailed() //============================================================================= -void SPELLprocessManager::fireProcessFailed( const std::string& identifier ) +void SPELLprocessManager::fireProcessFailed( std::string identifier ) { - SPELLmonitor m(m_lock); DEBUG("[PRCMGR] Firing process failed: " + identifier); - SPELLprocessListenersMap::iterator mit = m_listeners.find(identifier); + SPELLprocessListenersMap listeners = m_listeners; + SPELLprocessListenersMap::iterator mit = listeners.find(identifier); if (mit != m_listeners.end()) { - SPELLprocessListeners& list = mit->second; + SPELLprocessListeners list = mit->second; SPELLprocessListeners::iterator it; for( it = list.begin(); it != list.end(); it++) { diff --git a/lib/SPELL_PRD/Makefile.am b/lib/SPELL_PRD/Makefile.am index cb47a17..66ee734 100644 --- a/lib/SPELL_PRD/Makefile.am +++ b/lib/SPELL_PRD/Makefile.am @@ -1,34 +1,47 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_PRD.la -libSPELL_PRD_la_LDFLAGS = -version-info 2:1:0 -libSPELL_PRD_la_SOURCES = \ - src/SPELLprocedureManager.C \ - src/SPELLprocedure.C \ - src/SPELLlibrary.C - + +lib_LTLIBRARIES = libSPELL_PRD_v2.la libSPELL_PRD_v3.la + +libSPELL_PRD_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_PRD_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_PRD_v2_la_SOURCES = src/SPELLprocedureManager.C \ + src/SPELLprocedure.C \ + src/SPELLlibrary.C \ + src/SPELLpyService.C \ + src/SPELLserviceRegisterPython.C \ + src/SPELLserviceWatchdogPython.C + +libSPELL_PRD_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_PRD_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_PRD_v3_la_SOURCES = src/SPELLprocedureManager.C \ + src/SPELLprocedure.C \ + src/SPELLlibrary.C \ + src/SPELLpyService.C \ + src/SPELLserviceRegisterPython.C \ + src/SPELLserviceWatchdogPython.C + \ No newline at end of file diff --git a/lib/SPELL_PRD/src/SPELLlibrary.C b/lib/SPELL_PRD/src/SPELLlibrary.C index 3283c71..dd7cdaf 100644 --- a/lib/SPELL_PRD/src/SPELLlibrary.C +++ b/lib/SPELL_PRD/src/SPELLlibrary.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of library model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -48,9 +48,6 @@ SPELLlibrary::SPELLlibrary( const std::string& libPath, const std::string& filen // The remove the lib base path, not the subfolders m_libId = m_libId.substr( libPath.size()+1, m_libId.size()-libPath.size()-1 ); - - // Parse the file to get properties and source code - parseFile(filename); } //============================================================================= @@ -59,28 +56,3 @@ SPELLlibrary::SPELLlibrary( const std::string& libPath, const std::string& filen SPELLlibrary::~SPELLlibrary() { } - -//============================================================================= -// METHOD : SPELLlibrary::parseFile -//============================================================================= -void SPELLlibrary::parseFile( const std::string& path ) -{ - // Will be composed during parsing - m_source.clear(); - - std::ifstream file; - file.open( path.c_str() ); - if (!file.is_open()) - { - THROW_EXCEPTION("Cannot parse file " + path, "Unable to open", SPELL_ERROR_FILESYSTEM); - } - // Stores the last key found - std::string lastKey; - while(!file.eof()) - { - std::string line = ""; - std::getline(file,line); - m_source.addSourceCodeLine(line); - } - file.close(); -} diff --git a/lib/SPELL_PRD/src/SPELLprocedure.C b/lib/SPELL_PRD/src/SPELLprocedure.C index 376e73d..81f87f1 100644 --- a/lib/SPELL_PRD/src/SPELLprocedure.C +++ b/lib/SPELL_PRD/src/SPELLprocedure.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of procedure model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -36,15 +36,16 @@ #include #include #include -#include #define KEY_NAME "NAME" +#define KEY_PYTHON_VERSION "PYTHON VERSION" #define KEY_FILE "FILE" #define KEY_HISTORY "REVISION HISTORY" #define KEY_SC1 "SPACECRAFT" #define KEY_SC2 "SPACECRAFTS" const std::string CHECK_SPACECRAFT = "CheckSpacecraft"; +const std::string OVERRIDE_SC = "OverrideContextSpacecraftName"; //============================================================================= // CONSTRUCTOR : SPELLprocedure::SPELLprocedure() @@ -69,9 +70,6 @@ SPELLprocedure::SPELLprocedure( const std::string& procPath, const std::string& m_file = filename; m_header = ""; - // Obtain the file checksum - m_md5 = obtainChecksum(filename); - // Parse the file to get properties and source code parseFile(filename); } @@ -89,6 +87,55 @@ SPELLprocedure::~SPELLprocedure() //============================================================================= std::string SPELLprocedure::getHeader() { + if (!m_header.empty()) + return m_header; + + std::ifstream file; + file.open( m_file.c_str() ); + if (!file.is_open()) + { + THROW_EXCEPTION("Cannot parse file " + m_file, "Unable to open", SPELL_ERROR_FILESYSTEM); + } + // Will be true while in comment lines + bool isComment = false; + // Will be true while inside the header + bool inHeader = false; + // Will be true when finished parsing the header + bool headerDone = false; + // Will be true if parsing the history of changes + bool inHistory = false; + m_header = ""; + // Stores the last key found + std::string lastKey; + while(!file.eof()) + { + std::string line = ""; + std::getline(file,line); + + if ((line.size()>0)&&(!headerDone)) + { + isComment = (line[0] == '#'); + if (isComment && (!inHeader)) + { + // If it is a header delimiter line we are entering the header + if (isLimitLine(line)) + { + inHeader = true; + } + } + else if (isComment && inHeader) + { + m_header += line + "\n"; + // If we are in header and another limit line comes, we have finished + if (isLimitLine(line)) + { + headerDone = true; + break; + } + } + } + } + file.close(); return m_header; } @@ -129,7 +176,6 @@ void SPELLprocedure::parseFile( const std::string& path ) { std::string line = ""; std::getline(file,line); - m_source.addSourceCodeLine(line); if ((line.size()>0)&&(!headerDone)) { isComment = (line[0] == '#'); @@ -143,7 +189,6 @@ void SPELLprocedure::parseFile( const std::string& path ) } else if (isComment && inHeader) { - m_header += line + "\n"; // If we are in header and another limit line comes, we have finished if (isLimitLine(line)) { @@ -224,43 +269,6 @@ void SPELLprocedure::parseFile( const std::string& path ) m_properties[KEY_FILE] = m_file; } -//============================================================================= -// METHOD : SPELLprocedure::obtainChecksum() -//============================================================================= -std::string SPELLprocedure::obtainChecksum( const std::string& filename ) -{ - int fd = open(filename.c_str(), O_RDONLY); - if (fd<0) - { - THROW_EXCEPTION("Cannot calculate MD5 for file " + filename, "Unable to open", SPELL_ERROR_FILESYSTEM); - } - struct stat statbuf; - if(fstat(fd, &statbuf) < 0) - { - THROW_EXCEPTION("Cannot calculate MD5 for file " + filename, "Unable to stat file", SPELL_ERROR_FILESYSTEM); - } - int fileSize = statbuf.st_size; - char* fileBuffer; - unsigned char result[MD5_DIGEST_LENGTH]; - - fileBuffer = (char*) mmap(0, fileSize, PROT_READ, MAP_SHARED, fd, 0); - MD5((unsigned char*) fileBuffer, fileSize, result); - - // Print the MD5 sum as hex-digits. - int i; - char* hex = new char[2]; - std::string checksum = ""; - for(i=0; i SPELLprocedureSourceCode::getSourceCodeLines() { + if (!m_sourceLines.empty()) + return m_sourceLines; + + std::ifstream file; + file.open( m_filename.c_str() ); + if (!file.is_open()) + { + THROW_EXCEPTION("Cannot parse file " + m_filename, "Unable to open", SPELL_ERROR_FILESYSTEM); + } + // Stores the last key found + std::string lastKey; + std::string line = ""; + while(!file.eof()) + { + std::getline(file,line); + m_sourceLines.push_back(line); + } + + return m_sourceLines; +}; diff --git a/lib/SPELL_PRD/src/SPELLprocedureManager.C b/lib/SPELL_PRD/src/SPELLprocedureManager.C index 326deb9..137ac73 100644 --- a/lib/SPELL_PRD/src/SPELLprocedureManager.C +++ b/lib/SPELL_PRD/src/SPELLprocedureManager.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of procedure manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -33,7 +33,7 @@ #include "SPELL_UTIL/SPELLlog.H" #include "SPELL_UTIL/SPELLpythonHelper.H" #include "SPELL_SYN/SPELLmonitor.H" - +#include "SPELL_WRP/SPELLpyHandle.H" static SPELLprocedureManager* s_instance = 0; @@ -94,11 +94,16 @@ void SPELLprocedureManager::resolvePaths() SPELLcontextConfig& ctx = SPELLconfiguration::instance().getContext(m_ctxName); m_procPath = ctx.getProcPath(); m_libPath = ctx.getLibPath(); + m_servicePath = ctx.getServicePath(); // Resolve the path m_procPath = SPELLutils::resolvePath(m_procPath); m_libPath = SPELLutils::resolvePath(m_libPath); + m_servicePath = SPELLutils::resolvePath(m_servicePath); + SPELLutils::trim(m_procPath, "\r\n"); SPELLutils::trim(m_libPath, "\r\n"); + SPELLutils::trim(m_servicePath, "\r\n"); + if (!SPELLutils::isDirectory(m_procPath)) { LOG_ERROR("Procedure path not found or not a directory: '" + m_procPath + "'"); @@ -125,6 +130,24 @@ void SPELLprocedureManager::resolvePaths() { LOG_INFO("[PRCM] No user libraries defined"); } + + if (m_servicePath != "" && m_servicePath != "None") + { + if (!SPELLutils::isDirectory(m_servicePath)) + { + LOG_ERROR("Spell Service path not found or not a directory: '" + m_servicePath + "'"); + m_servicePath = ""; + } + else + { + LOG_INFO("[PRCM] Spell Service path: " + m_servicePath); + } + } + else + { + LOG_INFO("[PRCM] No Spell Services defined"); + } + } //============================================================================= @@ -158,6 +181,17 @@ void SPELLprocedureManager::refresh() LOG_INFO("Loading library files"); findLibraries( m_libPath ); } + if (m_servicePath != "" && m_servicePath != "None") + { + SPELLpythonHelper::instance().addToPath(m_libPath); + LOG_INFO("Loading Spell Services"); + findServices( m_servicePath, sc ); + + ServiceModelMap::iterator serviceIt = m_serviceModels.begin(); + for(;serviceIt != m_serviceModels.end();serviceIt++){ + std::cout << "Service " << serviceIt->second->getName() << " was found" << std::endl; + } + } } //============================================================================= @@ -223,7 +257,20 @@ const SPELLprocedureManager::ProcList SPELLprocedureManager::getProcList() } return list; } +//============================================================================= +// METHOD : SPELLprocedureManager::getServiceList +//============================================================================= +const SPELLprocedureManager::ProcList SPELLprocedureManager::getServiceList() +{ + ProcList list; + ServiceModelMap::iterator it; + for( it = m_serviceModels.begin(); it != m_serviceModels.end(); it++) + { + list.push_back( it->first ); + } + return list; +} //============================================================================= // METHOD : SPELLprocedureManager::getProcName //============================================================================= @@ -235,6 +282,10 @@ const std::string SPELLprocedureManager::getProcName( const std::string& procId ProcMap::iterator it = m_idToName.find(theProcId); if (it == m_idToName.end()) { + if (m_serviceModels.find(theProcId) != m_serviceModels.end()){ + return theProcId; + } + DEBUG("[PRCM] Did not find any name for: " + theProcId ); THROW_EXCEPTION("Cannot get name for procedure '" + theProcId + "'", "No such identifier", SPELL_ERROR_PROCEDURES); } @@ -242,6 +293,82 @@ const std::string SPELLprocedureManager::getProcName( const std::string& procId return it->second; } +//============================================================================= +// METHOD : SPELLprocedureManager::findProcedures +//============================================================================= +void SPELLprocedureManager::registerServiceHandler( PyObject* serviceImpl ) +{ + SPELLpyService* serviceModel = new SPELLpyService(serviceImpl); + + m_serviceModels[serviceModel->getName()] = serviceModel; +} + + +//============================================================================= +// METHOD : SPELLprocedureManager::findProcedures +//============================================================================= +void SPELLprocedureManager::findServices( const std::string& basePath, const std::string& sc ) +{ + if (!SPELLutils::isDirectory(basePath)) + { + return; + } + + std::list files = SPELLutils::getFilesInDir( basePath ); + std::list::iterator it; + std::list::iterator end = files.end(); + + std::string procPath = m_servicePath; + + // Add the current path to python path + if (SPELLpythonHelper::instance().isInitialized()) + { + SPELLpythonHelper::instance().addToPath( basePath ); + } + + PyObject* result = SPELLpythonHelper::instance().callFunction("spell.utils.spell_service","SupportServices",NULL); + Py_IncRef(result); + SPELLpythonHelper::instance().checkError(); + if (result == Py_False) + return; + + for( it = files.begin(); it != end; it++ ) + { + if ((*it) == "__init__.py") continue; + + std::size_t idx = (*it).find_last_of(".py"); + std::size_t idxb = (*it).find(".py~"); // Filter out backup files + std::size_t idxc = (*it).find(".pyc"); // Filter out compiled py files + if ((idx != std::string::npos && idx == ((*it).length() - 1)) + && (idxb == std::string::npos) && (idxc == std::string::npos)) + { + std::string serviceFile = basePath + PATH_SEPARATOR + (*it); + std::string serviceModuleName = it->substr(0, idx-2); + try + { + std::cout << "Loading Service " << serviceModuleName << std::endl; + + SPELLpyHandle serviceModule = PyImport_ImportModule(serviceModuleName.c_str()); + SPELLpythonHelper::instance().checkError(); + } + catch (SPELLcoreException& e) + { + + } + + } + } + + std::list subdirs = SPELLutils::getSubdirs( basePath ); + // Procedure folder order will be ['Bus', 'Ground', 'Mission', 'Payload', 'Prod_SES', 'Regression', 'SAE', 'Validation'] + subdirs.sort(SPELLutils::compareNocase); + end = subdirs.end(); + for( it = subdirs.begin(); it != end; it++ ) + { + findServices( basePath + PATH_SEPARATOR + (*it), sc ); + } +} + //============================================================================= // METHOD : SPELLprocedureManager::findProcedures //============================================================================= @@ -265,7 +392,8 @@ void SPELLprocedureManager::findProcedures( const std::string& basePath, const s std::size_t idx = (*it).find_last_of(".py"); std::size_t idxb = (*it).find(".py~"); // Filter out backup files - if ((idx != std::string::npos && idx == ((*it).length() - 1) ) && ( idxb == std::string::npos )) + std::size_t idxc = (*it).find(".pyc"); // Filter out compiled py files + if ((idx != std::string::npos && idx == ((*it).length() - 1) ) && ( idxb == std::string::npos ) && ( idxc == std::string::npos )) { std::string procFile = basePath + PATH_SEPARATOR + (*it); SPELLprocedure* proc = NULL; @@ -301,6 +429,8 @@ void SPELLprocedureManager::findProcedures( const std::string& basePath, const s } std::list subdirs = SPELLutils::getSubdirs( basePath ); + // Procedure folder order will be ['Bus', 'Ground', 'Mission', 'Payload', 'Prod_SES', 'Regression', 'SAE', 'Validation'] + subdirs.sort(SPELLutils::compareNocase); end = subdirs.end(); for( it = subdirs.begin(); it != end; it++ ) { @@ -366,7 +496,14 @@ SPELLprocedureSourceCode SPELLprocedureManager::getSourceCode( const std::string LibModels::iterator libit = m_libModels.find(procId); if (libit == m_libModels.end()) { - THROW_EXCEPTION("Cannot get source code for " + procId, "Procedure or library not found", SPELL_ERROR_PROCEDURES); + ServiceModelMap::iterator mit = m_serviceModels.find(theProcId); + if (mit == m_serviceModels.end()) + { + THROW_EXCEPTION("Cannot get source code for " + procId, "Procedure or library not found", SPELL_ERROR_PROCEDURES); + + } + SPELLpyService* service = mit->second; + return service->getSourceCode(); } SPELLlibrary* lib = libit->second; lib->refresh(); @@ -391,7 +528,16 @@ SPELLprocedure::PropertyKeys SPELLprocedureManager::getPropertyKeys( const std:: it = m_procModels.find(theProcId); if (it == m_procModels.end()) { - THROW_EXCEPTION("Cannot get properties for " + theProcId, "Procedure not found", SPELL_ERROR_PROCEDURES); + ServiceModelMap::iterator mit; + mit = m_serviceModels.find(theProcId); + if (mit == m_serviceModels.end()) + { + THROW_EXCEPTION("Cannot get properties for " + theProcId, "Procedure not found", SPELL_ERROR_PROCEDURES); + } + // Services don't have properties for now + SPELLprocedure::PropertyKeys empty = SPELLprocedure::PropertyKeys(); + empty.clear(); + return empty; } SPELLprocedure* proc = (*it).second; proc->refresh(); @@ -418,7 +564,7 @@ const std::string SPELLprocedureManager::getProperty( const std::string& procId, //============================================================================= // METHOD : SPELLprocedureManager::noInstanceId //============================================================================= -const std::string SPELLprocedureManager::noInstanceId( const std::string& procId ) +const std::string noInstanceId( const std::string& procId ) { std::string noIId = procId; std::size_t pos = procId.find_first_of("#"); @@ -429,6 +575,22 @@ const std::string SPELLprocedureManager::noInstanceId( const std::string& procId return noIId; } +//============================================================================= +// METHOD : SPELLprocedureManager::getProcedure +//============================================================================= +SPELLpyService& SPELLprocedureManager::getService( const std::string& serviceId ) +{ + SPELLmonitor lock(m_lock); + std::string noIId = noInstanceId(serviceId); + ServiceModelMap::iterator it; + it = m_serviceModels.find(noIId); + if (it != m_serviceModels.end()) + { + return *it->second; + } + THROW_EXCEPTION("Cannot obtain service model", "No such id: " + serviceId, SPELL_ERROR_PROCEDURES); +} + //============================================================================= // METHOD : SPELLprocedureManager::getProcedure //============================================================================= diff --git a/lib/SPELL_PRD/src/SPELLpyService.C b/lib/SPELL_PRD/src/SPELLpyService.C new file mode 100644 index 0000000..1521e88 --- /dev/null +++ b/lib/SPELL_PRD/src/SPELLpyService.C @@ -0,0 +1,115 @@ +// ################################################################################ +// FILE : SPELLservice.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of spell service model +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// Local includes ---------------------------------------------------------- +#include "SPELL_CFG/SPELLconfiguration.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLerror.H" +#include "SPELL_WRP/SPELLpyHandle.H" +#include "SPELL_UTIL/SPELLpythonHelper.H" +#include "SPELL_UTIL/SPELLpythonMonitors.H" + +// System includes --------------------------------------------------------- +#include +#include +#include +#include +#include "SPELL_PRD/SPELLpyService.H" +#include "SPELL_PRD/SPELLserviceWatchdogPython.H" + +//============================================================================= +// CONSTRUCTOR : SPELLpyService::SPELLpyService() +//============================================================================= +SPELLpyService::SPELLpyService(PyObject* serviceImpl) : +m_source("") +{ + SPELLsafePythonOperations ops("SPELLpyService::SPELLpyService"); + SPELLpyHandle pyServiceName = SPELLpythonHelper::instance().callMethod( + serviceImpl, "getName", NULL); + m_name = PyString_AsString(pyServiceName.get()); + SPELLpyHandle basePath = SPELLpythonHelper::instance().callMethod(serviceImpl, "getBasePath", NULL); + m_basePath = PyString_AsString(basePath.get()); + basePath = SPELLpythonHelper::instance().callMethod(serviceImpl, "getMainFile", NULL); + m_mainServiceFile = PyString_AsString(basePath.get()); + + m_service = serviceImpl; + Py_IncRef(serviceImpl); + std::cout << "Found Spell Service " << m_name << std::endl; + m_source = SPELLprocedureSourceCode(this->getMainServiceFile()); +} + +//============================================================================= +// DESTRUCTOR : SPELLpyService::~SPELLpyService +//============================================================================= +SPELLpyService::~SPELLpyService() +{ + Py_DecRef(m_service); +} + +bool SPELLpyService::useCommandOverride() const { + SPELLsafePythonOperations ops("useCommandOverride"); + SPELLpyHandle userOverride = SPELLpythonHelper::instance().callMethod(m_service,"useCommandOverride",NULL); + + SPELLpythonHelper::instance().checkError(); + + return userOverride.get() == Py_True; +} + +std::string SPELLpyService::getCommandOverride(int startTimeout, int loginTimeout, std::string config, std::string contextName, int ipcPort, std::string instanceId, + std::string warmstartFile) const { + SPELLsafePythonOperations ops("getCommandOverride"); + + SPELLpyHandle newCommand = PyObject_CallMethod(m_service,(char*)"getCommandOverride", (char*)"(iississ)", startTimeout, loginTimeout, config.c_str(), contextName.c_str(), ipcPort, instanceId.c_str(), warmstartFile.c_str(),NULL); + SPELLpythonHelper::instance().checkError(); + return PyString_AsString(newCommand.get()); +} + +void SPELLpyService::startWatchDog(void (*callback)(std::string&)) +{ + SPELLsafePythonOperations ops("startWatchDog"); + PyObject* callbackObj = SpellServiceWatchdog_Create(callback); + SPELLpyHandle newCommand = PyObject_CallMethod(m_service,(char*)"_startWatchDog", (char*)"(O)", callbackObj,NULL); + SPELLpythonHelper::instance().checkError(); +} + +void SPELLpyService::start() +{ + SPELLsafePythonOperations ops("start"); + + SPELLpyHandle newCommand = PyObject_CallMethod(m_service,(char*)"_start", (char*)"()",NULL); + SPELLpythonHelper::instance().checkError(); +} + +PyObject* SPELLpyService::getStartFunction() const +{ + SPELLsafePythonOperations ops("_getStartCode"); + + PyObject* funcCode = PyObject_CallMethod(m_service,(char*)"_getStartCode", (char*)"()",NULL); + SPELLpythonHelper::instance().checkError(); + + return PyMethod_Function(funcCode); +} diff --git a/lib/SPELL_PRD/src/SPELLserviceRegisterPython.C b/lib/SPELL_PRD/src/SPELLserviceRegisterPython.C new file mode 100644 index 0000000..9d6345e --- /dev/null +++ b/lib/SPELL_PRD/src/SPELLserviceRegisterPython.C @@ -0,0 +1,181 @@ +// ################################################################################ +// FILE : SPELLSpellServicePython.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the goto Python bindings +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// Local includes ---------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" +#include "SPELL_PRD/SPELLservicePython.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLpythonHelper.H" +#include "SPELL_PRD/SPELLprocedureManager.H" +// System includes --------------------------------------------------------- +#include "structmember.h" + + + +//============================================================================ +// FUNCTION : SpellService_Init +// DESCRIPTION : Initialized of the SpellService python object +//============================================================================ +static int SpellService_Init( PySpellServiceObject* self, PyObject* args, PyObject* kwds ); +//============================================================================ +// FUNCTION : SpellService_Dealloc +// DESCRIPTION : Cleanup of the SpellService python object +//============================================================================ +static void SpellService_Dealloc( PySpellServiceObject* self ); +//============================================================================ +// FUNCTION : SpellService_New +// DESCRIPTION : Constructor of the SpellService python object +//============================================================================ +static PyObject* SpellService_New( PyTypeObject* type, PyObject* args, PyObject* kwds ); +//============================================================================ +// FUNCTION : SpellService_Call +// DESCRIPTION : Call a SpellService statement +//============================================================================ +static PyObject* SpellService_Call( PyObject* self, PyObject* args, PyObject* kargs ); + + + +//============================================================================ +// SpellService object member specification +//============================================================================ +static PyMemberDef SpellService_Members[] = +{ + {NULL} /* Sentinel */ +}; + +//============================================================================ +// SpellService object method specification +//============================================================================ +static PyMethodDef SpellService_Methods[] = +{ + {NULL} /* Sentinel */ +}; + +//============================================================================ +// Python representation of the SPELL SpellService object type +//============================================================================ +static PyTypeObject SpellService_Type = +{ + PyVarObject_HEAD_INIT(NULL,0) + "context.RegisterSpellService", //tp_name + sizeof(PySpellServiceObject), //tp_basicsize + 0, //tp_itemsize + (destructor)SpellService_Dealloc, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + SpellService_Call, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + "RegisterSpellService mechanism", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + SpellService_Methods, // tp_methods + SpellService_Members, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + (initproc)SpellService_Init, // tp_init + 0, // tp_alloc + SpellService_New, // tp_new +}; + + +//============================================================================ +// FUNCTION : SpellService_Init +//============================================================================ +static int SpellService_Init( PySpellServiceObject* self, PyObject* args, PyObject* kwds ) +{ + return 0; +} + +//============================================================================ +// FUNCTION : SpellService_Dealloc +//============================================================================ +static void SpellService_Dealloc( PySpellServiceObject* self ) +{ + Py_TYPE(self)->tp_free( (PyObject*) self ); +} + +//============================================================================ +// FUNCTION : SpellService_New +//============================================================================ +static PyObject* SpellService_New( PyTypeObject* type, PyObject* args, PyObject* kwds ) +{ + //NOTE: Py_INCREF is already called! + PySpellServiceObject* self; + self = (PySpellServiceObject*) type->tp_alloc(type,0); + return (PyObject*)self; +} + +//============================================================================ +// FUNCTION : SpellService_Call +//============================================================================ +static PyObject* SpellService_Call( PyObject* self, PyObject* args, PyObject* kargs ) +{ + PyObject* target = PyTuple_GetItem(args,0); + Py_IncRef(target); + + SPELLprocedureManager::instance().registerServiceHandler(target); + + return target; +} + +//============================================================================ +// FUNCTION : SpellService_Install +//============================================================================ +void SpellService_Install() +{ + LOG_INFO("Installing SpellService object"); + + if (PyType_Ready(&SpellService_Type) < 0 ) + { + THROW_EXCEPTION("Cannot install SpellService", "Unable to register object type", SPELL_ERROR_PYTHON_API); + } + + PyObject* SpellService = SpellService_New( &SpellService_Type, NULL, NULL ); + Py_INCREF(SpellService); + + SPELLpythonHelper::instance().install(SpellService,"RegisterSpellService"); +} + diff --git a/lib/SPELL_PRD/src/SPELLserviceWatchdogPython.C b/lib/SPELL_PRD/src/SPELLserviceWatchdogPython.C new file mode 100644 index 0000000..7018933 --- /dev/null +++ b/lib/SPELL_PRD/src/SPELLserviceWatchdogPython.C @@ -0,0 +1,192 @@ +// ################################################################################ +// FILE : SPELLSpellServicePython.C +// DATE : Mar 17, 2011 +// PROJECT : SPELL +// DESCRIPTION: Implementation of the goto Python bindings +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE //////////////////////////////////////////////////////// +// Local includes ---------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" +#include "SPELL_PRD/SPELLserviceWatchdogPython.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLpythonHelper.H" +#include "SPELL_PRD/SPELLprocedureManager.H" +// System includes --------------------------------------------------------- +#include "structmember.h" + + + +//============================================================================ +// FUNCTION : SpellService_Init +// DESCRIPTION : Initialized of the SpellService python object +//============================================================================ +static int SpellServiceWatchdog_Init( PySpellServiceWatchdogObject* self, PyObject* args, PyObject* kwds ); +//============================================================================ +// FUNCTION : SpellService_Dealloc +// DESCRIPTION : Cleanup of the SpellService python object +//============================================================================ +static void SpellServiceWatchdog_Dealloc( PySpellServiceWatchdogObject* self ); +//============================================================================ +// FUNCTION : SpellService_New +// DESCRIPTION : Constructor of the SpellService python object +//============================================================================ +static PyObject* SpellServiceWatchdog_New( PyTypeObject* type, PyObject* args, PyObject* kwds ); +//============================================================================ +// FUNCTION : SpellService_Call +// DESCRIPTION : Call a SpellService statement +//============================================================================ +static PyObject* SpellServiceWatchdog_Call( PyObject* self, PyObject* args, PyObject* kargs ); + + + +//============================================================================ +// SpellService object member specification +//============================================================================ +static PyMemberDef SpellServiceWatchdog_Members[] = +{ + {"callback",T_OBJECT_EX,offsetof(PySpellServiceWatchdogObject,callback),0,"callback to C code"}, + {NULL} /* Sentinel */ +}; + +//============================================================================ +// SpellService object method specification +//============================================================================ +static PyMethodDef SpellServiceWatchdog_Methods[] = +{ + {NULL} /* Sentinel */ +}; + +//============================================================================ +// Python representation of the SPELL SpellService object type +//============================================================================ +static PyTypeObject SpellServiceWatchdog_Type = +{ + PyVarObject_HEAD_INIT(NULL,0) + "context.WatchdogCallback", //tp_name + sizeof(PySpellServiceWatchdogObject), //tp_basicsize + 0, //tp_itemsize + (destructor)SpellServiceWatchdog_Dealloc, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + SpellServiceWatchdog_Call, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + "WatchdogCallback mechanism", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + SpellServiceWatchdog_Methods, // tp_methods + SpellServiceWatchdog_Members, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + (initproc)SpellServiceWatchdog_Init, // tp_init + 0, // tp_alloc + SpellServiceWatchdog_New, // tp_new +}; + + +//============================================================================ +// FUNCTION : SpellService_Init +//============================================================================ +static int SpellServiceWatchdog_Init( PySpellServiceWatchdogObject* self, PyObject* args, PyObject* kwds ) +{ + return 0; +} + +//============================================================================ +// FUNCTION : SpellService_Dealloc +//============================================================================ +static void SpellServiceWatchdog_Dealloc( PySpellServiceWatchdogObject* self ) +{ + Py_TYPE(self)->tp_free( (PyObject*) self ); +} + +//============================================================================ +// FUNCTION : SpellService_New +//============================================================================ +static PyObject* SpellServiceWatchdog_New( PyTypeObject* type, PyObject* args, PyObject* kwds ) +{ + //NOTE: Py_INCREF is already called! + PySpellServiceWatchdogObject* self; + self = (PySpellServiceWatchdogObject*) type->tp_alloc(type,0); + PyObject* callback = PyTuple_GetItem(args,0); + Py_INCREF(callback); + PyObject_SetAttrString((PyObject*)self, "callback",callback); + + return (PyObject*)self; +} + +//============================================================================ +// FUNCTION : SpellService_Call +//============================================================================ +static PyObject* SpellServiceWatchdog_Call( PyObject* self, PyObject* args, PyObject* kargs ) +{ + PyObject* target = PyTuple_GetItem(args,0); + Py_IncRef(target); + + void (*callback)(std::string&); + PyObject* obj = PyObject_GetAttrString(self,"callback"); + callback = (void (*)(std::string&))PyCapsule_GetPointer(obj, NULL); + + std::string targetStr= PyString_AsString(target); + callback(targetStr); + Py_INCREF(Py_None); + return Py_None; +} + +//============================================================================ +// FUNCTION : SpellService_Install +//============================================================================ +PyObject* SpellServiceWatchdog_Create(void (*callback)(std::string&) ) +{ + LOG_INFO("Installing SpellService object"); + + if (PyType_Ready(&SpellServiceWatchdog_Type) < 0 ) + { + THROW_EXCEPTION("Cannot install SpellService", "Unable to register object type", SPELL_ERROR_PYTHON_API); + } + PyObject* callbackObj = PyCapsule_New((void*) callback,NULL,NULL); + PyObject* args = PyTuple_Pack(1,callbackObj,NULL); + PyObject* watchdog = SpellServiceWatchdog_New( &SpellServiceWatchdog_Type, args, NULL ); + Py_INCREF(watchdog); + + return watchdog; +} + diff --git a/lib/SPELL_SDB/Makefile.am b/lib/SPELL_SDB/Makefile.am index 1d58057..bdbd0a6 100644 --- a/lib/SPELL_SDB/Makefile.am +++ b/lib/SPELL_SDB/Makefile.am @@ -1,41 +1,46 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_SDB.la +lib_LTLIBRARIES = libSPELL_SDB_v2.la libSPELL_SDB_v3.la -libSPELL_SDB_la_CPPFLAGS = ${AM_CPPFLAGS} -DWITH_DEBUG -libSPELL_SDB_la_LDFLAGS = -version-info 1:0:0 +libSPELL_SDB_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} -libSPELL_SDB_la_SOURCES = \ - src/SPELLpyDatabaseMethods.C \ - src/SPELLpyDatabaseModule.C \ - src/SPELLdatabase.C \ - src/SPELLdatabaseFile.C \ - src/SPELLdatabaseFileSPB.C \ - src/SPELLdatabaseFactory.C - +libSPELL_SDB_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_SDB_v2_la_SOURCES = src/SPELLpyDatabaseMethods.C \ + src/SPELLpyDatabaseModule.C \ + src/SPELLdatabase.C \ + src/SPELLdatabaseFile.C \ + src/SPELLdatabaseFileSPB.C \ + src/SPELLdatabaseFactory.C + +libSPELL_SDB_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_SDB_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_SDB_v3_la_SOURCES = src/SPELLpyDatabaseMethods.C \ + src/SPELLpyDatabaseModule.C \ + src/SPELLdatabase.C \ + src/SPELLdatabaseFile.C \ + src/SPELLdatabaseFileSPB.C \ + src/SPELLdatabaseFactory.C diff --git a/lib/SPELL_SDB/src/SPELLdatabase.C b/lib/SPELL_SDB/src/SPELLdatabase.C index 28ca202..641784d 100644 --- a/lib/SPELL_SDB/src/SPELLdatabase.C +++ b/lib/SPELL_SDB/src/SPELLdatabase.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of SPELL database // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_SDB/src/SPELLdatabaseFactory.C b/lib/SPELL_SDB/src/SPELLdatabaseFactory.C index e7f1f61..f2118df 100644 --- a/lib/SPELL_SDB/src/SPELLdatabaseFactory.C +++ b/lib/SPELL_SDB/src/SPELLdatabaseFactory.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of SPELL database factory // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_SDB/src/SPELLdatabaseFile.C b/lib/SPELL_SDB/src/SPELLdatabaseFile.C index 072f6a7..5dda807 100644 --- a/lib/SPELL_SDB/src/SPELLdatabaseFile.C +++ b/lib/SPELL_SDB/src/SPELLdatabaseFile.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of database based on local files // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_SDB/src/SPELLdatabaseFileSPB.C b/lib/SPELL_SDB/src/SPELLdatabaseFileSPB.C index 8f7494c..243cc5d 100644 --- a/lib/SPELL_SDB/src/SPELLdatabaseFileSPB.C +++ b/lib/SPELL_SDB/src/SPELLdatabaseFileSPB.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation based on local SPB files // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_SDB/src/SPELLpyDatabaseMethods.C b/lib/SPELL_SDB/src/SPELLpyDatabaseMethods.C index f0844fe..2be34d0 100644 --- a/lib/SPELL_SDB/src/SPELLpyDatabaseMethods.C +++ b/lib/SPELL_SDB/src/SPELLpyDatabaseMethods.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of database Python bindings // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -46,7 +46,7 @@ int SPELLpyDatabase_Init( PyDatabaseObject* self, PyObject* args, PyObject* kwds std::string name = ""; std::string file = ""; std::string ext = ""; - std::string type = self->ob_type->tp_name; + std::string type = Py_TYPE(self)->tp_name; if (PyTuple_Size(args)!=3) { THROW_SYNTAX_EXCEPTION_NR("Cannot initialize database", "Expected database name, file and default extension"); @@ -93,7 +93,7 @@ void SPELLpyDatabase_Dealloc( PyDatabaseObject* self ) { delete self->__pdb; self->__pdb = NULL; - self->ob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ @@ -614,8 +614,7 @@ static PyMethodDef dictiter_methods[] = { PyTypeObject PyDatabaseIterator_Type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ + PyVarObject_HEAD_INIT(&PyType_Type,0) "database-keyiterator", /* tp_name */ sizeof(PyDatabaseIteratorObject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -668,7 +667,7 @@ PyObject* SPELLpyDatabase_NewIterator( PyDatabaseObject* container ) //============================================================================ void SPELLpyDatabase_DeallocIterator( PyDatabaseIteratorObject* di ) { - di->ob_type->tp_free( (PyObject*)di ); + Py_TYPE(di)->tp_free( (PyObject*)di ); } //============================================================================ @@ -676,34 +675,26 @@ void SPELLpyDatabase_DeallocIterator( PyDatabaseIteratorObject* di ) //============================================================================ PyObject* SPELLpyDatabase_NextKey( PyDatabaseIteratorObject* di ) { - PyObject *key; - register Py_ssize_t i, mask; - register PyDictEntry *ep; - PyDictObject* d = di->di_dict; + PyObject *key,*value; + Py_ssize_t i; + int result; + PyObject* d = (PyObject*)di->di_dict; if (d == NULL) return NULL; assert (PyDict_Check(d)); - if (di->di_used != d->ma_used) - { - PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); - di->di_used = -1; /* Make this state sticky */ - return NULL; - } - i = di->di_pos; if (i < 0) goto fail; - ep = d->ma_table; - mask = d->ma_mask; - while (i <= mask && ep[i].me_value == NULL) i++; - di->di_pos = i+1; - if (i > mask) goto fail; + + result = PyDict_Next(d, &di->di_pos, &key, &value); + + if (!result) goto fail; + di->len--; - key = ep[i].me_key; + Py_INCREF(key); return key; fail: - Py_DECREF(d); di->di_dict = NULL; return NULL; } diff --git a/lib/SPELL_SDB/src/SPELLpyDatabaseModule.C b/lib/SPELL_SDB/src/SPELLpyDatabaseModule.C index 37c8ee9..dd40883 100644 --- a/lib/SPELL_SDB/src/SPELLpyDatabaseModule.C +++ b/lib/SPELL_SDB/src/SPELLpyDatabaseModule.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of Python database module // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -78,8 +78,8 @@ DATABASE_DEFINITION( SPELLpyDatabaseFileSPB_Type, "spell.adapter.databases.Datab ////////////////////////////////////////////////////////////////////////////// // PYTHON MODULE INITIALIZATION ////////////////////////////////////////////////////////////////////////////// -PyMODINIT_FUNC -initlibSPELL_SDB(void) + +MOD_INIT(libSPELL_SDB) { // Will hold the Python module PyObject* module; @@ -90,10 +90,12 @@ initlibSPELL_SDB(void) DATABASE_TYPE_READY(SPELLpyDatabaseFileSPB_Type); // Initialize the module - module = Py_InitModule3("libSPELL_SDB", NULL, "Module for SPELL databases"); + MOD_DEF(module,MOD_NAME(libSPELL_SDB),"Module for SPELL databases",NULL) // Add the classes to the module dictionary DATABASE_TYPE_LOAD(module, SPELLpyDatabase_Type, "Database" ); DATABASE_TYPE_LOAD(module, SPELLpyDatabaseFile_Type, "DatabaseFile" ); DATABASE_TYPE_LOAD(module, SPELLpyDatabaseFileSPB_Type, "DatabaseFileSPB" ); + + return MOD_SUCCESS_VAL(module); } diff --git a/lib/SPELL_SYN/Makefile.am b/lib/SPELL_SYN/Makefile.am index 8416b6c..0759e83 100644 --- a/lib/SPELL_SYN/Makefile.am +++ b/lib/SPELL_SYN/Makefile.am @@ -1,49 +1,53 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_SYN.la - -libSPELL_SYN_la_LDFLAGS = -version-info 1:0:0 - -if PLATFORM_LINUX - ADDITIONAL_SRC= src/SPELLmutexPOSIX.C \ - src/SPELLmutexFactoryPOSIX.C \ - src/SPELLconditionPOSIX.C \ - src/SPELLconditionFactoryPOSIX.C -else - ADDITIONAL_SRC= -endif - -libSPELL_SYN_la_SOURCES = $(ADDITIONAL_SRC) \ - src/SPELLtimer.C \ - src/SPELLevent.C \ - src/SPELLthread.C \ - src/SPELLthreadWorker.C \ - src/SPELLthreadPool.C - - +lib_LTLIBRARIES = libSPELL_SYN_v2.la libSPELL_SYN_v3.la + +libSPELL_SYN_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_SYN_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_SYN_v2_la_SOURCES = src/SPELLmutexPOSIX.C \ + src/SPELLmutexFactoryPOSIX.C \ + src/SPELLconditionPOSIX.C \ + src/SPELLconditionFactoryPOSIX.C \ + src/SPELLtimer.C \ + src/SPELLevent.C \ + src/SPELLthread.C \ + src/SPELLthreadWorker.C \ + src/SPELLthreadPool.C + +libSPELL_SYN_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_SYN_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_SYN_v3_la_SOURCES = src/SPELLmutexPOSIX.C \ + src/SPELLmutexFactoryPOSIX.C \ + src/SPELLconditionPOSIX.C \ + src/SPELLconditionFactoryPOSIX.C \ + src/SPELLtimer.C \ + src/SPELLevent.C \ + src/SPELLthread.C \ + src/SPELLthreadWorker.C \ + src/SPELLthreadPool.C + \ No newline at end of file diff --git a/lib/SPELL_SYN/src/SPELLconditionFactoryPOSIX.C b/lib/SPELL_SYN/src/SPELLconditionFactoryPOSIX.C index fbdad75..a689e98 100644 --- a/lib/SPELL_SYN/src/SPELLconditionFactoryPOSIX.C +++ b/lib/SPELL_SYN/src/SPELLconditionFactoryPOSIX.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of condition factory for POSIX // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_SYN/src/SPELLconditionPOSIX.C b/lib/SPELL_SYN/src/SPELLconditionPOSIX.C index 34757f5..7fe518b 100644 --- a/lib/SPELL_SYN/src/SPELLconditionPOSIX.C +++ b/lib/SPELL_SYN/src/SPELLconditionPOSIX.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of condition mechanism for POSIX // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -36,7 +36,21 @@ //============================================================================= SPELLconditionPOSIX::SPELLconditionPOSIX() { - pthread_cond_init(&m_condition, NULL); + int result = pthread_cond_init(&m_condition, NULL); + if (result == EAGAIN){ + LOG_ERROR("[SPELLconditionPOSIX.create] Error creating condition! The system lacked the necessary resources (other than memory) to initialise another condition variable."); + } else if (result == ENOMEM) { + LOG_ERROR("[SPELLconditionPOSIX.create] Error creating condition! Insufficient memory exists to initialise the condition variable."); + } else if (result == EBUSY) { + LOG_ERROR("[SPELLconditionPOSIX.create] Error creating condition! The implementation has detected an attempt to re-initialise the object referenced by cond, a previously initialised, but not yet destroyed, condition variable."); + } else if (result == EINVAL) { + LOG_ERROR("[SPELLconditionPOSIX.create] Error creating condition! The value specified by attr is invalid."); + } +//#ifdef WITH_DEBUG +// std::stringstream buf; +// buf << "SPELLconditionPOSIX create " << &m_condition; +// DEBUG( buf.str()); +//#endif } //============================================================================= @@ -44,7 +58,12 @@ SPELLconditionPOSIX::SPELLconditionPOSIX() //============================================================================= SPELLconditionPOSIX::~SPELLconditionPOSIX() { - pthread_cond_destroy(&m_condition); +//#ifdef WITH_DEBUG +// std::stringstream buf; +// buf << "SPELLconditionPOSIX destroy " << &m_condition; +// DEBUG( buf.str()); +//#endif + pthread_cond_destroy(&m_condition); } //============================================================================= @@ -73,8 +92,23 @@ bool SPELLconditionPOSIX::wait( SPELLmutex* m, unsigned long timeoutMsec ) clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += timeoutMsec / 1000; abstime.tv_nsec += ( timeoutMsec - (timeoutMsec / 1000)*1000 ) * 1000; + if (abstime.tv_nsec >= 1000000000){ + DEBUG("[SPELLconditionPOSIX.wait] abstime.tv_nsec is >= 1000000000. This may cause Condition error EINVAL. Value will be corrected."); + abstime.tv_sec += abstime.tv_nsec / 1000000000; + abstime.tv_nsec = abstime.tv_nsec % 1000000000; + } + if (abstime.tv_nsec < 0) { + DEBUG("[SPELLconditionPOSIX.wait] abstime.tv_nsec is < 0. This may cause Condition error EINVAL. Value will be corrected."); + abstime.tv_sec -= 1; + abstime.tv_nsec = (abstime.tv_nsec + 1000000000) % 1000000000; + } SPELLmutexPOSIX* pmutex = dynamic_cast(m->getImpl()); assert(pmutex->get() != 0); +//#ifdef WITH_DEBUG +// std::stringstream buf; +// buf << "SPELLconditionPOSIX pthread_cond_timedwait " << &m_condition; +// DEBUG( buf.str()); +//#endif int ret = pthread_cond_timedwait(&m_condition, pmutex->get(), &abstime); if (ret == ETIMEDOUT) { diff --git a/lib/SPELL_SYN/src/SPELLevent.C b/lib/SPELL_SYN/src/SPELLevent.C index 644d4e3..8ded4c3 100644 --- a/lib/SPELL_SYN/src/SPELLevent.C +++ b/lib/SPELL_SYN/src/SPELLevent.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the event mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -42,7 +42,7 @@ SPELLevent::SPELLevent( bool log ) { m_log = log; m_isClear = false; - DEBUG("[EVE] Event " + PSTR(this) + " created with mutex " + PSTR(&m_mutex)) + //DEBUG("[EVE] Event " + PSTR(this) + " created with mutex " + PSTR(&m_mutex)) if (m_log) std::cerr << " CREATE EVENT " << (void*) this << std::endl; } @@ -51,7 +51,7 @@ SPELLevent::SPELLevent( bool log ) //============================================================================= SPELLevent::~SPELLevent() { - DEBUG("[EVE] Event " + PSTR(this) + " destroyed") + //DEBUG("[EVE] Event " + PSTR(this) + " destroyed") if (m_log) std::cerr << " DESTROY EVENT " << (void*) this << std::endl; } @@ -61,7 +61,7 @@ SPELLevent::~SPELLevent() void SPELLevent::set() { if (m_log) std::cerr << "SET EVENT TRY IN " << (void*) this << std::endl; - DEBUG("[EVE] Event " + PSTR(this) + " set") + //DEBUG("[EVE] Event " + PSTR(this) + " set") m_mutex.lock(); if (m_isClear) { @@ -80,7 +80,7 @@ void SPELLevent::set() void SPELLevent::clear() { if (m_log) std::cerr << "CHECK CLEAR EVENT IN " << (void*) this << std::endl; - DEBUG("[EVE] Event " + PSTR(this) + " clear") + //DEBUG("[EVE] Event " + PSTR(this) + " clear") m_mutex.lock(); m_isClear = true; m_mutex.unlock(); @@ -93,14 +93,14 @@ void SPELLevent::clear() void SPELLevent::wait() { if (m_log) std::cerr << "WAIT EVENT TRY IN " << (void*) this << std::endl; - DEBUG("[EVE] Event " + PSTR(this) + " wait in with mutex " + PSTR(&m_mutex)) + //DEBUG("[EVE] Event " + PSTR(this) + " wait in with mutex " + PSTR(&m_mutex)) m_mutex.lock(); while (m_isClear) { m_condition.wait(&m_mutex); } m_mutex.unlock(); - DEBUG("[EVE] Event " + PSTR(this) + " wait out") + //DEBUG("[EVE] Event " + PSTR(this) + " wait out") if (m_log) std::cerr << "WAIT EVENT FINISH " << (void*) this << std::endl; } @@ -110,7 +110,7 @@ void SPELLevent::wait() bool SPELLevent::wait( unsigned long timeoutMsec ) { bool timedout = false; - DEBUG("[EVE] Event " + PSTR(this) + " wait in with mutex " + PSTR(&m_mutex)) + //DEBUG("[EVE] Event " + PSTR(this) + " wait in with mutex " + PSTR(&m_mutex)) if (m_log) std::cerr << " WAIT EVENT T.O. TRY IN " << (void*) this << std::endl; m_mutex.lock(); while (m_isClear && !timedout) @@ -121,7 +121,7 @@ bool SPELLevent::wait( unsigned long timeoutMsec ) } m_mutex.unlock(); if (m_log) std::cerr << " WAIT EVENT T.O. FINISH" << (void*) this << std::endl; - DEBUG("[EVE] Event " + PSTR(this) + " wait out") + //DEBUG("[EVE] Event " + PSTR(this) + " wait out") return timedout; } @@ -131,7 +131,7 @@ bool SPELLevent::wait( unsigned long timeoutMsec ) bool SPELLevent::isClear() { if (m_log) std::cerr << " IS CLEAR EVENT IN " << (void*) this << std::endl; - DEBUG("[EVE] Event " + PSTR(this) + " isclear with mutex " + PSTR(&m_mutex)) + //DEBUG("[EVE] Event " + PSTR(this) + " isclear with mutex " + PSTR(&m_mutex)) bool isClear = false; m_mutex.lock(); isClear = m_isClear; diff --git a/lib/SPELL_SYN/src/SPELLmutexFactoryPOSIX.C b/lib/SPELL_SYN/src/SPELLmutexFactoryPOSIX.C index c9c759e..e81712c 100644 --- a/lib/SPELL_SYN/src/SPELLmutexFactoryPOSIX.C +++ b/lib/SPELL_SYN/src/SPELLmutexFactoryPOSIX.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the mutex factory for POSIX // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_SYN/src/SPELLmutexPOSIX.C b/lib/SPELL_SYN/src/SPELLmutexPOSIX.C index f3fe595..e98e9fb 100644 --- a/lib/SPELL_SYN/src/SPELLmutexPOSIX.C +++ b/lib/SPELL_SYN/src/SPELLmutexPOSIX.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the mutex mechanism for POSIX // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -36,6 +36,7 @@ SPELLmutexPOSIX::SPELLmutexPOSIX() : SPELLmutexIF() { + m_threadId = 0; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); diff --git a/lib/SPELL_SYN/src/SPELLthread.C b/lib/SPELL_SYN/src/SPELLthread.C index 5746b09..cbaa733 100644 --- a/lib/SPELL_SYN/src/SPELLthread.C +++ b/lib/SPELL_SYN/src/SPELLthread.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the thread mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -55,7 +55,7 @@ SPELLthread::SPELLthread( std::string id ) pthread_attr_init(&m_threadAttr); pthread_attr_setdetachstate(&m_threadAttr, PTHREAD_CREATE_JOINABLE); m_threadRunning = false; - DEBUG("[THR] Thread " + m_threadId + " created") + // DEBUG("[THR] Thread " + m_threadId + " created") } //============================================================================= @@ -63,7 +63,7 @@ SPELLthread::SPELLthread( std::string id ) //============================================================================= SPELLthread::~SPELLthread() { - DEBUG("[THR] Thread " + m_threadId + " do destroy"); + //DEBUG("[THR] Thread " + m_threadId + " do destroy"); m_threadRunning = false; pthread_attr_destroy(&m_threadAttr); } @@ -74,12 +74,24 @@ SPELLthread::~SPELLthread() void SPELLthread::start() { SPELLmonitor m(m_threadLock); - int result = pthread_create(&m_thread, (const pthread_attr_t*) &m_threadAttr, do_run, this ); - //std::cerr << "==== create thread " << m_thread << " " << m_threadId << std::endl; - if( result != 0) - { - throw SPELLsyncError("Unable to start thread", "Cannot create thread: " + ISTR(result)); - } + int result; + int tries = 0; + do { + result = pthread_create(&m_thread, (const pthread_attr_t*) &m_threadAttr, do_run, this ); + tries++; + if (result != 0) + { + if (tries > 10) + { + perror("pthread_create"); + throw SPELLsyncError("Unable to start thread", "Cannot create thread: " + ISTR(result)); + } + else + { + usleep(500000); + } + } + } while (result != 0); } //============================================================================= @@ -116,10 +128,10 @@ void SPELLthread::doRun() void SPELLthread::join() { //std::cerr << "==== before join " << m_thread << " " << m_threadId << std::endl; - SPELLmonitor m(m_threadLock); - if (m_thread != 0) + pthread_t thread = m_thread; + if (thread != 0) { - pthread_join(m_thread, NULL); + pthread_join(thread, NULL); //std::cerr << "==== after join " << m_thread << " " << m_threadId << std::endl; m_thread = 0; m_threadRunning = false; diff --git a/lib/SPELL_SYN/src/SPELLthreadPool.C b/lib/SPELL_SYN/src/SPELLthreadPool.C index a1447d8..be732e9 100644 --- a/lib/SPELL_SYN/src/SPELLthreadPool.C +++ b/lib/SPELL_SYN/src/SPELLthreadPool.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the thread pool mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_SYN/src/SPELLthreadWorker.C b/lib/SPELL_SYN/src/SPELLthreadWorker.C index e11d396..a3de9a2 100644 --- a/lib/SPELL_SYN/src/SPELLthreadWorker.C +++ b/lib/SPELL_SYN/src/SPELLthreadWorker.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the thread worker mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -44,6 +44,7 @@ SPELLthreadWorker::SPELLthreadWorker( const std::string& id ) m_work = NULL; m_shutdown = false; m_newWork.clear(); + m_busy = false; } //============================================================================= diff --git a/lib/SPELL_SYN/src/SPELLtimer.C b/lib/SPELL_SYN/src/SPELLtimer.C index 18290b8..4f2400b 100644 --- a/lib/SPELL_SYN/src/SPELLtimer.C +++ b/lib/SPELL_SYN/src/SPELLtimer.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the timer mechanism // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -46,7 +46,7 @@ SPELLtimer::SPELLtimer( unsigned long period, SPELLtimerListener& listener ) m_period = period; m_elapsed = 0; m_timeout = 0; - DEBUG("[TMR] Timer created (1) " + PSTR(this)) + //DEBUG("[TMR] Timer created (1) " + PSTR(this)) } //============================================================================= @@ -61,7 +61,7 @@ SPELLtimer::SPELLtimer( unsigned long period, SPELLtimerListener& listener, unsi m_period = period; m_elapsed = 0; m_timeout = timeout; - DEBUG("[TMR] Timer created (2) " + PSTR(this)) + //DEBUG("[TMR] Timer created (2) " + PSTR(this)) } //============================================================================= @@ -79,26 +79,26 @@ SPELLtimer::~SPELLtimer() //============================================================================= void SPELLtimer::run() { - DEBUG("[TMR] Timer thread started: " + PSTR(this)) + //DEBUG("[TMR] Timer thread started: " + PSTR(this)) setCounting(true); while(isCounting()) { usleep(m_period*1000);// Period is given in msec if (callTimerCallback()) { - DEBUG("[TMR] Ending timer thread (callback) for " + PSTR(this)) + //DEBUG("[TMR] Ending timer thread (callback) for " + PSTR(this)) return; } if (checkTimeout()) { - DEBUG("[TMR] Ending timer thread (timeout) for " + PSTR(this)) + //DEBUG("[TMR] Ending timer thread (timeout) for " + PSTR(this)) return; } - DEBUG("[TMR] Stop event wait in " + PSTR(this)) + //DEBUG("[TMR] Stop event wait in " + PSTR(this)) wait(); - DEBUG("[TMR] Stop event wait out " + PSTR(this)) + //DEBUG("[TMR] Stop event wait out " + PSTR(this)) } - DEBUG("[TMR] Ending timer thread for " + PSTR(this)) + //DEBUG("[TMR] Ending timer thread for " + PSTR(this)) } //============================================================================= @@ -137,10 +137,10 @@ bool SPELLtimer::checkTimeout() //============================================================================= void SPELLtimer::cancel() { - DEBUG("[TMR] Cancelling timer thread IN" + PSTR(this)) + //DEBUG("[TMR] Cancelling timer thread IN" + PSTR(this)) setCounting(false); cont(); - DEBUG("[TMR] Cancelling timer thread " + PSTR(this) + " OUT ") + //DEBUG("[TMR] Cancelling timer thread " + PSTR(this) + " OUT ") } //============================================================================= @@ -166,7 +166,7 @@ void SPELLtimer::setCounting( bool counting ) //============================================================================= void SPELLtimer::stop() { - DEBUG("[TMR] Stopping timer IN" + PSTR(this)) + //DEBUG("[TMR] Stopping timer IN" + PSTR(this)) SPELLmonitor monitor(m_mutex); m_stopEvent.clear(); } @@ -176,7 +176,7 @@ void SPELLtimer::stop() //============================================================================= void SPELLtimer::cont() { - DEBUG("[TMR] Continue timer IN" + PSTR(this)) + //DEBUG("[TMR] Continue timer IN" + PSTR(this)) SPELLmonitor monitor(m_mutex); m_stopEvent.set(); } @@ -186,6 +186,6 @@ void SPELLtimer::cont() //============================================================================= void SPELLtimer::wait() { - DEBUG("[TMR] Wait timer IN" + PSTR(this)) + //DEBUG("[TMR] Wait timer IN" + PSTR(this)) m_stopEvent.wait(); } diff --git a/lib/SPELL_UTIL/Makefile.am b/lib/SPELL_UTIL/Makefile.am index fbfa0e5..a2d346e 100644 --- a/lib/SPELL_UTIL/Makefile.am +++ b/lib/SPELL_UTIL/Makefile.am @@ -1,41 +1,51 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_UTIL.la +lib_LTLIBRARIES = libSPELL_UTIL_v2.la libSPELL_UTIL_v3.la -libSPELL_UTIL_la_LDFLAGS = -version-info 3:0:0 -libSPELL_UTIL_la_SOURCES = \ - src/SPELLtime.C \ - src/SPELLutils.C \ - src/SPELLlog.C \ - src/SPELLpythonHelper.C \ - src/SPELLlogPython.C \ - src/SPELLpyArgs.C \ - src/SPELLcompression.C \ - src/SPELLerror.C - +libSPELL_UTIL_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_UTIL_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_UTIL_v2_la_SOURCES = src/SPELLtime.C \ + src/SPELLutils.C \ + src/SPELLlog.C \ + src/SPELLpythonHelper.C \ + src/SPELLlogPython.C \ + src/SPELLpyArgs.C \ + src/SPELLcompression.C \ + src/SPELLerror.C + + +libSPELL_UTIL_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_UTIL_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_UTIL_v3_la_SOURCES = src/SPELLtime.C \ + src/SPELLutils.C \ + src/SPELLlog.C \ + src/SPELLpythonHelper.C \ + src/SPELLlogPython.C \ + src/SPELLpyArgs.C \ + src/SPELLcompression.C \ + src/SPELLerror.C diff --git a/lib/SPELL_UTIL/src/SPELLcompression.C b/lib/SPELL_UTIL/src/SPELLcompression.C index 6e4dd38..4d35184 100644 --- a/lib/SPELL_UTIL/src/SPELLcompression.C +++ b/lib/SPELL_UTIL/src/SPELLcompression.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the compression utility // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_UTIL/src/SPELLerror.C b/lib/SPELL_UTIL/src/SPELLerror.C index b431062..49939d0 100644 --- a/lib/SPELL_UTIL/src/SPELLerror.C +++ b/lib/SPELL_UTIL/src/SPELLerror.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the Python error bindings // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -101,8 +101,7 @@ static PyMethodDef ExecutionAborted_Methods[] = //============================================================================ static PyTypeObject ExecutionAborted_Type = { - PyObject_HEAD_INIT(NULL) - 0, //ob_size + PyVarObject_HEAD_INIT(NULL,0) "executor.ExecutionAborted", //tp_name sizeof(PyExecutionAbortedObject), //tp_basicsize 0, //tp_itemsize @@ -163,8 +162,7 @@ static PyMethodDef ExecutionTerminated_Methods[] = //============================================================================ static PyTypeObject ExecutionTerminated_Type = { - PyObject_HEAD_INIT(NULL) - 0, //ob_size + PyVarObject_HEAD_INIT(NULL,0) "executor.ExecutionTerminated", //tp_name sizeof(PyExecutionTerminatedObject), //tp_basicsize 0, //tp_itemsize @@ -232,7 +230,7 @@ static int ExecutionAborted_Init( PyExecutionAbortedObject* self, PyObject* args static void ExecutionAborted_Dealloc( PyExecutionAbortedObject* self ) { Py_XDECREF(self->message); - self->ob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ @@ -269,7 +267,7 @@ static int ExecutionTerminated_Init( PyExecutionTerminatedObject* self, PyObject //============================================================================ static void ExecutionTerminated_Dealloc( PyExecutionTerminatedObject* self ) { - self->ob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ @@ -499,7 +497,7 @@ SPELLcoreException* SPELLerror::errorToException( PyObject* err, PyObject* ptype } else { - message = " (no back trace information)\n"; + message = ""; } LOG_ERROR("**************************************"); @@ -513,7 +511,7 @@ SPELLcoreException* SPELLerror::errorToException( PyObject* err, PyObject* ptype else { PyObject* data = PyTuple_GetItem(pvalue, 1); - if (PyTuple_Size(data)==4) + if (data && PyTuple_Size(data)==4) { PyObject* filename = PyTuple_GetItem( data, 0); PyObject* lineno = PyTuple_GetItem( data, 1); @@ -555,7 +553,7 @@ SPELLcoreException* SPELLerror::errorToException( PyObject* err, PyObject* ptype else if (PyErr_GivenExceptionMatches(err, PyExc_SyntaxError)) { // It is a tuple like ('invalid syntax', ('file.py', lineno, offset, 'text')) - message = "Unknown syntax error (could not gather information)\n" + message; + message = "Syntax error\n" + message; if (PyTuple_Size(pvalue)==2) { PyObject* data = PyTuple_GetItem(pvalue, 1); diff --git a/lib/SPELL_UTIL/src/SPELLlog.C b/lib/SPELL_UTIL/src/SPELLlog.C index dea7c12..5a8139e 100644 --- a/lib/SPELL_UTIL/src/SPELLlog.C +++ b/lib/SPELL_UTIL/src/SPELLlog.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the logger // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -109,7 +109,7 @@ void SPELLlog::setLogFile( const std::string& filename, const std::string timest logfilename = logbase + "/" + logfilename; m_logFileName = logfilename; - log4cplus::SharedFileAppenderPtr appender( new log4cplus::RollingFileAppender(LOG4CPLUS_TEXT(logfilename), 10*1024*1024, 5, false, true)); + log4cplus::SharedFileAppenderPtr appender( new log4cplus::RollingFileAppender(LOG4CPLUS_TEXT(logfilename), 10*1024*1024, 5, true, true)); appender->setLayout( std::auto_ptr(new log4cplus::PatternLayout(LOG_PATTERN)) ); appender->getloc(); log4cplus::Logger::getRoot().addAppender( log4cplus::SharedAppenderPtr(appender.get()) ); diff --git a/lib/SPELL_UTIL/src/SPELLlogPython.C b/lib/SPELL_UTIL/src/SPELLlogPython.C index 72465d6..5c87bc6 100644 --- a/lib/SPELL_UTIL/src/SPELLlogPython.C +++ b/lib/SPELL_UTIL/src/SPELLlogPython.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the logger bindings // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -88,8 +88,7 @@ static PyMethodDef Log_Methods[] = //============================================================================ static PyTypeObject Log_Type = { - PyObject_HEAD_INIT(NULL) - 0, //ob_size + PyVarObject_HEAD_INIT(NULL, 0) "executor.LOG", //tp_name sizeof(PyLogObject), //tp_basicsize 0, //tp_itemsize @@ -143,7 +142,7 @@ static int Log_Init( PyLogObject* self, PyObject* args, PyObject* kwds ) //============================================================================ static void Log_Dealloc( PyLogObject* self ) { - self->ob_type->tp_free( (PyObject*) self ); + Py_TYPE(self)->tp_free( (PyObject*) self ); } //============================================================================ @@ -232,6 +231,8 @@ static PyObject* Log_Call( PyObject* self, PyObject* args, PyObject* kargs ) case LOG_ERROR: LOG_ERROR_PY(message); break; + default: + break; } Py_RETURN_NONE; diff --git a/lib/SPELL_UTIL/src/SPELLpyArgs.C b/lib/SPELL_UTIL/src/SPELLpyArgs.C index 13cd96c..3fe504a 100644 --- a/lib/SPELL_UTIL/src/SPELLpyArgs.C +++ b/lib/SPELL_UTIL/src/SPELLpyArgs.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the argument helper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -220,7 +220,7 @@ SPELLtime SPELLpyArgs::getModifier_AsTime( const std::string& modifier ) const bool SPELLpyArgs::getModifier_AsBoolean( const std::string& modifier ) const { PyObject* valueObj = (*this)[modifier]; - DEBUG("[CFGHLP] Configured modifier: " + PYREPR(valueObj)) + DEBUG("[CFGHLP] Configured modifier: " + PYREPR(valueObj)); bool value = false; if (valueObj != NULL) { @@ -282,7 +282,7 @@ SPELLtime SPELLpyArgs::getModifier_Delay() const std::string SPELLpyArgs::getModifier_ValueFormat() const { PyObject* formatObj = (*this)[LanguageModifiers::ValueFormat]; - DEBUG("[CFGHLP] Configured ValueFormat: " + PYREPR(formatObj)) + DEBUG("[CFGHLP] Configured ValueFormat: " + PYREPR(formatObj)); std::string format = LanguageConstants::ENG; @@ -310,7 +310,7 @@ std::string SPELLpyArgs::getModifier_ValueFormat() const std::string SPELLpyArgs::getModifier_Expected() const { PyObject* expectedObj = (*this)[LanguageModifiers::Expected]; - DEBUG("[CFGHLP] Configured Expected: " + PYREPR(expectedObj)) + DEBUG("[CFGHLP] Configured Expected: " + PYREPR(expectedObj)); std::string expected = ""; if ( expectedObj != NULL ) @@ -333,7 +333,7 @@ std::string SPELLpyArgs::getModifier_Expected() const std::string SPELLpyArgs::getModifier_LoRed() const { PyObject* valueObj = (*this)[LanguageModifiers::LoRed]; - DEBUG("[CFGHLP] Configured LoRed: " + PYREPR(valueObj)) + DEBUG("[CFGHLP] Configured LoRed: " + PYREPR(valueObj)); std::string value = ""; if ( valueObj != NULL ) @@ -349,7 +349,7 @@ std::string SPELLpyArgs::getModifier_LoRed() const std::string SPELLpyArgs::getModifier_LoYel() const { PyObject* valueObj = (*this)[LanguageModifiers::LoYel]; - DEBUG("[CFGHLP] Configured LoYel: " + PYREPR(valueObj)) + DEBUG("[CFGHLP] Configured LoYel: " + PYREPR(valueObj)); std::string value = ""; if ( valueObj != NULL ) @@ -365,7 +365,7 @@ std::string SPELLpyArgs::getModifier_LoYel() const std::string SPELLpyArgs::getModifier_HiRed() const { PyObject* valueObj = (*this)[LanguageModifiers::HiRed]; - DEBUG("[CFGHLP] Configured HiRed: " + PYREPR(valueObj)) + DEBUG("[CFGHLP] Configured HiRed: " + PYREPR(valueObj)); std::string value = ""; if ( valueObj != NULL ) @@ -381,7 +381,39 @@ std::string SPELLpyArgs::getModifier_HiRed() const std::string SPELLpyArgs::getModifier_HiYel() const { PyObject* valueObj = (*this)[LanguageModifiers::HiYel]; - DEBUG("[CFGHLP] Configured HiYel: " + PYREPR(valueObj)) + DEBUG("[CFGHLP] Configured HiYel: " + PYREPR(valueObj)); + + std::string value = ""; + if ( valueObj != NULL ) + { + value = PYSSTR(valueObj); + } + return value; +} + +//============================================================================= +// METHOD: SPELLpyArgs::getModifier_Select() +//============================================================================= +std::string SPELLpyArgs::getModifier_Select() const +{ + PyObject* valueObj = (*this)[LanguageModifiers::Select]; + DEBUG("[CFGHLP] Configured Select: " + PYREPR(valueObj)); + + std::string value = ""; + if ( valueObj != NULL ) + { + value = PYSSTR(valueObj); + } + return value; +} + +//============================================================================= +// METHOD: SPELLpyArgs::getModifier_LimitType() +//============================================================================= +std::string SPELLpyArgs::getModifier_LimitType() const +{ + PyObject* valueObj = (*this)[LanguageModifiers::Type]; + DEBUG("[CFGHLP] Configured Limit Type: " + PYREPR(valueObj)); std::string value = ""; if ( valueObj != NULL ) @@ -546,10 +578,16 @@ std::string SPELLpyArgs::getModifier_Default() const } else if (PyFloat_Check( valueObj )) { +#if PY_MAJOR_VERSION >= 3 + PyObject* obj = PyObject_Str(valueObj); + value = PyUnicode_AsUTF8(obj); + Py_DECREF(obj); +#else char* buffer = new char[512]; - PyFloat_AsString(buffer, (PyFloatObject*) (valueObj) ); - value = std::string(buffer); - delete buffer; + PyFloat_AsString(buffer, (PyFloatObject*) (valueObj) ); + value = std::string(buffer); + delete buffer; +#endif } else if (PyBool_Check( valueObj )) { @@ -573,3 +611,4 @@ std::string SPELLpyArgs::getModifier_Default() const } return value; } + diff --git a/lib/SPELL_UTIL/src/SPELLpythonHelper.C b/lib/SPELL_UTIL/src/SPELLpythonHelper.C index 1cc035d..5357c39 100644 --- a/lib/SPELL_UTIL/src/SPELLpythonHelper.C +++ b/lib/SPELL_UTIL/src/SPELLpythonHelper.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the Python helper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -39,7 +39,12 @@ #include "Python-ast.h" #include "opcode.h" #include "traceback.h" - +#include "pystate.h" +#if PY_MAJOR_VERSION >= 3 +# include "code.h" +# include "frameobject.h" +# include "structmember.h" +#endif // See setNewLine method #undef MIN #undef MAX @@ -63,7 +68,7 @@ static PyObject * objargs_mktuple(va_list va) int i, n = 0; va_list countva; PyObject *result, *tmp; - countva = va; + va_copy(countva, va); while ( ( (PyObject *) va_arg(countva, PyObject *)) != NULL) { ++n; @@ -139,7 +144,7 @@ void SPELLpythonHelper::importAllFrom( const std::string& package ) moduleDict = PyModule_GetDict( module ); } - PyObject* mainModule = PyImport_AddModule("__main__"); + PyObject* mainModule = PyImport_ImportModule(BUILTINS); if (mainModule == NULL) { THROW_EXCEPTION("Cannot import " + package, "Unable to access main module", SPELL_ERROR_PYTHON_API ); @@ -152,18 +157,59 @@ void SPELLpythonHelper::importAllFrom( const std::string& package ) PyDict_Merge(main_dict, moduleDict, 0); DEBUG("[PYH] Imported all from module " + package); } +void SPELLpythonHelper::updateBuiltinsWith( const std::string& package ) +{ + LOG_INFO("Import all from " + package); + PyObject* dict = PyDict_New(); + PyObject* module = PyImport_ImportModuleEx( const_cast(package.c_str()), dict, dict, NULL); + if ( module == NULL ) + { + SPELLcoreException* ex = SPELLerror::instance().errorToException(); + throw *ex; + } + + // Borrowed + PyObject* moduleDict = PyModule_GetDict( module ); + std::vector tokens = SPELLutils::tokenize( package, "." ); + + std::vector::iterator it; + for( it = tokens.begin(); it != tokens.end(); it++ ) + { + // Skip the first token + if (it == tokens.begin()) continue; + // Get the submodule + // Borrowed reference + module = PyDict_GetItemString( moduleDict, (*it).c_str() ); + moduleDict = PyModule_GetDict( module ); + } + + PyObject* mainModule = PyImport_ImportModule(BUILTINS); + if (mainModule == NULL) + { + THROW_EXCEPTION("Cannot import " + package, "Unable to access "BUILTINS" module", SPELL_ERROR_PYTHON_API ); + } + PyObject* main_dict = PyModule_GetDict(mainModule); + if (main_dict== NULL) + { + THROW_EXCEPTION("Cannot import " + package, "Unable to access "BUILTINS" module dictionary", SPELL_ERROR_PYTHON_API ); + } + PyDict_Merge(main_dict, moduleDict, 0); + DEBUG("[PYH] Imported all from module " + package); +} //============================================================================ // METROD : SPELLpythonHelper::importUserLibraries //============================================================================ -void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath ) +bool SPELLpythonHelper::importUserLibraries( const std::string& libraryPath, std::string& errors ) { + bool success = true; + if (libraryPath != "" && libraryPath != "None" ) { if (SPELLutils::isDirectory(libraryPath)) { // Import the main module first - PyObject* mainModule = PyImport_AddModule("__main__"); + PyObject* mainModule = PyImport_ImportModule(BUILTINS); if (mainModule == NULL) { THROW_EXCEPTION("Cannot import user libraries", "Unable to access main module", SPELL_ERROR_PYTHON_API ); @@ -179,7 +225,7 @@ void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath ) if (PyDict_Contains( main_dict, flag.get()) ) { LOG_WARN("[PYH] No need to re-import user libraries"); - return; + return true; } LOG_INFO("Loading user libraries in " + libraryPath); @@ -205,12 +251,12 @@ void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath ) } catch(SPELLcoreException& ex) { - LOG_ERROR("Failed to import user library " + filename + ": " + ex.what()); - PyErr_Clear(); + success = false; + if (errors != "") errors += "\n - "; + errors += "When importing library " + filename + ": " + ex.what(); } } - // Now ensure that all libraries contain all imported names as well for( it = files.begin(); it != end; it++) { @@ -228,8 +274,9 @@ void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath ) } catch(SPELLcoreException& ex) { - LOG_ERROR("Failed to update user library " + filename + ": " + ex.what()); - PyErr_Clear(); + success = false; + if (errors != "") errors += "\n - "; + errors += "When updating library " + filename + ": " + ex.what(); } } @@ -238,9 +285,12 @@ void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath ) } else { - THROW_EXCEPTION("Unable to load USER libraries", "Library path '" + libraryPath + "' is not a directory", SPELL_ERROR_FILESYSTEM); + success = false; + if (errors != "") errors += "\n - "; + errors += "Path '" + libraryPath + "' is not a directory"; } } + return success; } //============================================================================ @@ -320,7 +370,7 @@ void SPELLpythonHelper::importUserLibrary( PyObject* main_dict, const std::strin //============================================================================ PyObject* SPELLpythonHelper::getMainDict() { - PyObject* mainModule = PyImport_AddModule("__main__"); + PyObject* mainModule = PyImport_AddModule(BUILTINS); if (mainModule == NULL) { THROW_EXCEPTION("Cannot access main dictionary", "Unable to access main module", SPELL_ERROR_PYTHON_API ); @@ -335,7 +385,7 @@ PyObject* SPELLpythonHelper::getMainDict() void SPELLpythonHelper::install( PyObject* object, const std::string& name ) { DEBUG("[PYH] Installing object in globals: " + name); - install(object,name,"__main__"); + install(object,name,BUILTINS); } //============================================================================ @@ -343,7 +393,7 @@ void SPELLpythonHelper::install( PyObject* object, const std::string& name ) //============================================================================ void SPELLpythonHelper::install( PyObject* object, const std::string& name, const std::string& module ) { - PyObject* moduleObj = PyImport_AddModule( module.c_str() ); + PyObject* moduleObj = PyImport_ImportModule( module.c_str() ); if (moduleObj == NULL) { THROW_EXCEPTION("Cannot install " + name, "Unable to access module " + module, SPELL_ERROR_PYTHON_API ); @@ -365,9 +415,8 @@ void SPELLpythonHelper::install( PyObject* object, const std::string& name, cons //============================================================================= PyObject* SPELLpythonHelper::callMethod( PyObject* obj, const std::string& method, ... ) { - DEBUG("[PYH] Call method " + method + " on " + PYREPR(obj)); - SPELLsafePythonOperations ops("SPELLpythonHelper::callMethod " + method); + DEBUG("[PYH] Call method " + method + " on " + PYREPR(obj)); // Returns new reference @@ -487,8 +536,10 @@ PyObject* SPELLpythonHelper::getModule( const std::string& module ) moduleObj = PyImport_ImportModule( module.c_str() ); if (moduleObj == NULL || moduleObj == Py_None ) { + checkError(); THROW_EXCEPTION("Unable to get module " + module, "Import failed", SPELL_ERROR_PYTHON_API ); } + Py_INCREF(moduleObj); DEBUG("[PYH] Get module done"); return moduleObj; } @@ -498,7 +549,8 @@ PyObject* SPELLpythonHelper::getModule( const std::string& module ) //============================================================================= void SPELLpythonHelper::initialize() { - m_initialized = false; + if (m_initialized) + return; LOG_INFO("[PYH] Initializing Python"); // Initialize python, builtins, main module, etc. @@ -531,11 +583,16 @@ void SPELLpythonHelper::initialize() } // Initialize the system arguments to empty list (no script is executed) - char** argv = new char*[1]; - argv[0] = (char*) ""; - PySys_SetArgv(1,argv); + + CHAR** argv = new CHAR*[1]; + argv[0] = (CHAR*) L""; + PySys_SetArgv(-1,argv); m_initialized = true; + Py_BEGIN_ALLOW_THREADS}; +// PyEval_ReleaseThread(PyThreadState_Get()); +// PyEval_ReleaseLock(); + } //============================================================================= @@ -543,13 +600,13 @@ void SPELLpythonHelper::initialize() //============================================================================= void SPELLpythonHelper::loadFramework() { - importAllFrom("spell.lang.functions"); - importAllFrom("spell.lang.constants"); - importAllFrom("spell.lang.modifiers"); - importAllFrom("spell.lang.user"); - importAllFrom("spell.lib.adapter.utctime"); - importAllFrom("spell.lib.adapter.file"); - importAllFrom("math"); + updateBuiltinsWith("spell.lang.functions"); + updateBuiltinsWith("spell.lang.constants"); + updateBuiltinsWith("spell.lang.modifiers"); + updateBuiltinsWith("spell.lang.user"); + updateBuiltinsWith("spell.lib.adapter.utctime"); + updateBuiltinsWith("spell.lib.adapter.file"); + updateBuiltinsWith("math"); } //============================================================================= @@ -569,7 +626,7 @@ void SPELLpythonHelper::finalize() void SPELLpythonHelper::addToPath( const std::string& path ) { LOG_INFO("[PYH] Append to python path: " + path); - + SPELLsafePythonOperations ops("SPELLpythonHelper::addToPath"); // Retrieve first the current path std::string libs = ""; PyObject* sys = PySys_GetObject( (char*) "path" ); @@ -582,8 +639,11 @@ void SPELLpythonHelper::addToPath( const std::string& path ) } if (!libs.empty()) libs += ":"; libs += path; - +#if PY_MAJOR_VERSION >= 3 + PySys_SetPath( const_cast(std::wstring(libs.begin(),libs.end()).c_str()) ); +#else PySys_SetPath( const_cast(libs.c_str()) ); +#endif } //============================================================================= @@ -663,36 +723,60 @@ SPELLtime SPELLpythonHelper::evalTime( PyObject* expression ) if (isTime(expression)) { SPELLpyHandle isRel = callMethod(expression,"isRel",NULL); + long secs = 0; + unsigned int msecs = 0; + unsigned int usecs = 0; + SPELLpyHandle h = callMethod(expression,"millisecond",NULL); + msecs = PyLong_AsLong(h.get()); + h = callMethod(expression,"microsecond",NULL); + usecs = PyLong_AsLong(h.get()); if (isRel.get() == Py_True) { SPELLpyHandle pySecs = callMethod(expression,"rel",NULL); - long secs = PyLong_AsLong(pySecs.get()); + if (PyFloat_Check(pySecs.get())) + { + double fsecs = PyFloat_AsDouble(pySecs.get()); + // New reference + SPELLpyHandle pyDoub = PyLong_FromDouble(fsecs); + secs = PyLong_AsLong(pyDoub.get()); + } + else + { + secs = PyLong_AsLong(pySecs.get()); + } DEBUG("[PYH] Evaluate time from python object done"); - return SPELLtime( secs, 0, true ); + //DEBUG("@@@@ Initialized rel values:"); + //DEBUG(" - secs: " + ISTR(secs) ); + //DEBUG(" - msecs: " + ISTR(msecs) ); + //DEBUG(" - usecs: " + ISTR(usecs) ); + return SPELLtime( secs, msecs, usecs, true ); } else { // New reference SPELLpyHandle pySecs = callMethod(expression,"abs",NULL); - int seconds = 0; if (PyFloat_Check(pySecs.get())) { double fsecs = PyFloat_AsDouble(pySecs.get()); // New reference SPELLpyHandle pyDoub = PyLong_FromDouble(fsecs); - seconds = PyLong_AsLong(pyDoub.get()); + secs = PyLong_AsLong(pyDoub.get()); } else { - seconds = PyLong_AsLong(pySecs.get()); + secs = PyLong_AsLong(pySecs.get()); } DEBUG("[PYH] Evaluate time from python object done"); - return SPELLtime( seconds, 0, false ); + //DEBUG("@@@@ Initialized abs values:"); + //DEBUG(" - secs: " + ISTR(secs) ); + //DEBUG(" - msecs: " + ISTR(msecs) ); + //DEBUG(" - usecs: " + ISTR(usecs) ); + return SPELLtime( secs, msecs, usecs, false ); } } else { - THROW_FATAL_EXCEPTION("Unable to evaluate time", "Not a TIME instance", SPELL_ERROR_PYTHON_API ); + return evalTime(PYSSTR(expression)); } // Just to avoid warnings... return SPELLtime(); @@ -764,12 +848,26 @@ PyObject* SPELLpythonHelper::pythonTime( const SPELLtime& time ) //============================================================================= PyThreadState* SPELLpythonHelper::beginSafeAllowThreads() { + // Don't call PyEval_SaveThread if this thread doesn't hold the GIL! This would cause weird CPython crashes. + PyThreadState *hasGIL = PyGILState_GetThisThreadState(); + if (hasGIL == NULL) + return NULL; +#if PY_MAJOR_VERSION >= 3 + // Need to check whether we hold the python lock in py3 as well. + if (!PyGILState_Check()) + return NULL; +#endif PyThreadState *tstate = PyThreadState_GET(); + if (tstate != NULL) { -// std::cerr << "BEGIN ALLOW THREADS ##########################################################" << std::endl; - tstate = PyEval_SaveThread(); -// std::cerr << "FRAME: " << PSTR(tstate->frame) << std::endl; + //std::cerr << "BEGIN ALLOW THREADS ##########################################################" << std::endl; + // Make sure this thread is holding the GIL when trying to call PyEval_SaveThread which requires the GIL + if (hasGIL == tstate) + tstate = PyEval_SaveThread(); + else + return NULL; + //std::cerr << "FRAME: " << PSTR(tstate->frame) << std::endl; } return tstate; } @@ -781,8 +879,8 @@ void SPELLpythonHelper::endSafeAllowThreads( PyThreadState* tstate ) { if (tstate != NULL) { -// std::cerr << "END ALLOW THREADS ############################################################" << std::endl; -// std::cerr << "FRAME: " << PSTR(tstate->frame) << std::endl; + //std::cerr << "END ALLOW THREADS ############################################################" << std::endl; + //std::cerr << "FRAME: " << PSTR(tstate->frame) << std::endl; PyEval_RestoreThread(tstate); } } @@ -792,10 +890,10 @@ void SPELLpythonHelper::endSafeAllowThreads( PyThreadState* tstate ) //============================================================================= PyGILState_STATE SPELLpythonHelper::acquireGIL() { -// std::cerr << "ACQUIRE GIL ##################################################################" << std::endl; + //std::cerr << "ACQUIRE GIL ##################################################################" << std::endl; PyGILState_STATE state = PyGILState_Ensure(); -// std::cerr << "FRAME: " << PSTR(PyEval_GetFrame()) << std::endl; -// std::cerr << "STATE: " << state << std::endl; + //std::cerr << "FRAME: " << PSTR(PyEval_GetFrame()) << std::endl; + //std::cerr << "STATE: " << state << std::endl; return state; } @@ -804,9 +902,9 @@ PyGILState_STATE SPELLpythonHelper::acquireGIL() //============================================================================= void SPELLpythonHelper::releaseGIL( PyGILState_STATE state ) { -// std::cerr << "RELEASE GIL ##################################################################" << std::endl; -// std::cerr << "FRAME: " << PSTR(PyEval_GetFrame()) << std::endl; -// std::cerr << "STATE: " << state << std::endl; + //std::cerr << "RELEASE GIL ##################################################################" << std::endl; + //std::cerr << "FRAME: " << PSTR(PyEval_GetFrame()) << std::endl; + //std::cerr << "STATE: " << state << std::endl; PyGILState_Release(state); } @@ -858,7 +956,7 @@ std::string SPELLpythonHelper::readProcedureFile( const std::string& filename ) //============================================================================= PyCodeObject* SPELLpythonHelper::compile( const std::string& filePath ) { - DEBUG("[PYH] Compiling procedure " + filePath) + DEBUG("[PYH] Compiling procedure " + filePath); // Will hold the AST preprocessed bytecode mod_ty ast; @@ -1001,13 +1099,424 @@ PyCodeObject* SPELLpythonHelper::compileScript( const std::string& source ) return code; } + +#if PY_MAJOR_VERSION >= 3 + +#define OFF(x) offsetof(PyFrameObject, x) + +/* Setter for f_lineno - you can set f_lineno from within a trace function in + * order to jump to a given line of code, subject to some restrictions. Most + * lines are OK to jump to because they don't make any assumptions about the + * state of the stack (obvious because you could remove the line and the code + * would still work without any stack errors), but there are some constructs + * that limit jumping: + * + * o Lines with an 'except' statement on them can't be jumped to, because + * they expect an exception to be on the top of the stack. + * o Lines that live in a 'finally' block can't be jumped from or to, since + * the END_FINALLY expects to clean up the stack after the 'try' block. + * o 'try'/'for'/'while' blocks can't be jumped into because the blockstack + * needs to be set up before their code runs, and for 'for' loops the + * iterator needs to be on the stack. + * o Jumps cannot be made from within a trace function invoked with a + * 'return' or 'exception' event since the eval loop has been exited at + * that time. + */ +static int +frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignored)) +{ + int new_lineno = 0; /* The new value of f_lineno */ + long l_new_lineno; + int overflow; + int new_lasti = 0; /* The new value of f_lasti */ + int new_iblock = 0; /* The new value of f_iblock */ + unsigned char *code = NULL; /* The bytecode for the frame... */ + Py_ssize_t code_len = 0; /* ...and its length */ + unsigned char *lnotab = NULL; /* Iterating over co_lnotab */ + Py_ssize_t lnotab_len = 0; /* (ditto) */ + int offset = 0; /* (ditto) */ + int line = 0; /* (ditto) */ + int addr = 0; /* (ditto) */ + int min_addr = 0; /* Scanning the SETUPs and POPs */ + int max_addr = 0; /* (ditto) */ + int delta_iblock = 0; /* (ditto) */ + int min_delta_iblock = 0; /* (ditto) */ + int min_iblock = 0; /* (ditto) */ + int f_lasti_setup_addr = 0; /* Policing no-jump-into-finally */ + int new_lasti_setup_addr = 0; /* (ditto) */ + int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */ + int in_finally[CO_MAXBLOCKS]; /* (ditto) */ + int blockstack_top = 0; /* (ditto) */ + unsigned char setup_op = 0; /* (ditto) */ + + if (p_new_lineno == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + /* f_lineno must be an integer. */ + if (!PyLong_CheckExact(p_new_lineno)) { + PyErr_SetString(PyExc_ValueError, + "lineno must be an integer"); + return -1; + } + + /* Upon the 'call' trace event of a new frame, f->f_lasti is -1 and + * f->f_trace is NULL, check first on the first condition. + * Forbidding jumps from the 'call' event of a new frame is a side effect + * of allowing to set f_lineno only from trace functions. */ + if (f->f_lasti == -1) { + PyErr_Format(PyExc_ValueError, + "can't jump from the 'call' trace event of a new frame"); + return -1; + } + + /* You can only do this from within a trace function, not via + * _getframe or similar hackery. */ +// if (!f->f_trace) { +// PyErr_Format(PyExc_ValueError, +// "f_lineno can only be set by a trace function"); +// return -1; +// } + + /* Forbid jumps upon a 'return' trace event (except after executing a + * YIELD_VALUE or YIELD_FROM opcode, f_stacktop is not NULL in that case) + * and upon an 'exception' trace event. + * Jumps from 'call' trace events have already been forbidden above for new + * frames, so this check does not change anything for 'call' events. */ + if (f->f_stacktop == NULL) { + PyErr_SetString(PyExc_ValueError, + "can only jump from a 'line' trace event"); + return -1; + } + + /* Fail if the line comes before the start of the code block. */ + l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow); + if (overflow +#if SIZEOF_LONG > SIZEOF_INT + || l_new_lineno > INT_MAX + || l_new_lineno < INT_MIN +#endif + ) { + PyErr_SetString(PyExc_ValueError, + "lineno out of range"); + return -1; + } + new_lineno = (int)l_new_lineno; + + if (new_lineno < f->f_code->co_firstlineno) { + PyErr_Format(PyExc_ValueError, + "line %d comes before the current code block", + new_lineno); + return -1; + } + else if (new_lineno == f->f_code->co_firstlineno) { + new_lasti = 0; + new_lineno = f->f_code->co_firstlineno; + } + else { + /* Find the bytecode offset for the start of the given + * line, or the first code-owning line after it. */ + char *tmp; + PyBytes_AsStringAndSize(f->f_code->co_lnotab, + &tmp, &lnotab_len); + lnotab = (unsigned char *) tmp; + addr = 0; + line = f->f_code->co_firstlineno; + new_lasti = -1; + for (offset = 0; offset < lnotab_len; offset += 2) { + addr += lnotab[offset]; + line += (signed char)lnotab[offset+1]; + if (line >= new_lineno) { + new_lasti = addr; + new_lineno = line; + break; + } + } + } + + /* If we didn't reach the requested line, return an error. */ + if (new_lasti == -1) { + PyErr_Format(PyExc_ValueError, + "line %d comes after the current code block", + new_lineno); + return -1; + } + + /* We're now ready to look at the bytecode. */ + PyBytes_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len); + + /* The trace function is called with a 'return' trace event after the + * execution of a yield statement. */ + assert(f->f_lasti != -1); + if (code[f->f_lasti] == YIELD_VALUE || code[f->f_lasti] == YIELD_FROM) { + PyErr_SetString(PyExc_ValueError, + "can't jump from a yield statement"); + return -1; + } + + min_addr = Py_MIN(new_lasti, f->f_lasti); + max_addr = Py_MAX(new_lasti, f->f_lasti); + + /* You can't jump onto a line with an 'except' statement on it - + * they expect to have an exception on the top of the stack, which + * won't be true if you jump to them. They always start with code + * that either pops the exception using POP_TOP (plain 'except:' + * lines do this) or duplicates the exception on the stack using + * DUP_TOP (if there's an exception type specified). See compile.c, + * 'com_try_except' for the full details. There aren't any other + * cases (AFAIK) where a line's code can start with DUP_TOP or + * POP_TOP, but if any ever appear, they'll be subject to the same + * restriction (but with a different error message). */ + if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) { + PyErr_SetString(PyExc_ValueError, + "can't jump to 'except' line as there's no exception"); + return -1; + } + + /* You can't jump into or out of a 'finally' block because the 'try' + * block leaves something on the stack for the END_FINALLY to clean + * up. So we walk the bytecode, maintaining a simulated blockstack. + * When we reach the old or new address and it's in a 'finally' block + * we note the address of the corresponding SETUP_FINALLY. The jump + * is only legal if neither address is in a 'finally' block or + * they're both in the same one. 'blockstack' is a stack of the + * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks + * whether we're in a 'finally' block at each blockstack level. */ + f_lasti_setup_addr = -1; + new_lasti_setup_addr = -1; + memset(blockstack, '\0', sizeof(blockstack)); + memset(in_finally, '\0', sizeof(in_finally)); + blockstack_top = 0; + for (addr = 0; addr < code_len; addr += sizeof(_Py_CODEUNIT)) { + unsigned char op = code[addr]; + switch (op) { + case SETUP_LOOP: + case SETUP_EXCEPT: + case SETUP_FINALLY: + case SETUP_WITH: + case SETUP_ASYNC_WITH: + blockstack[blockstack_top++] = addr; + in_finally[blockstack_top-1] = 0; + break; + + case POP_BLOCK: + assert(blockstack_top > 0); + setup_op = code[blockstack[blockstack_top-1]]; + if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH + || setup_op == SETUP_ASYNC_WITH) { + in_finally[blockstack_top-1] = 1; + } + else { + blockstack_top--; + } + break; + + case END_FINALLY: + /* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist + * in the bytecode but don't correspond to an actual + * 'finally' block. (If blockstack_top is 0, we must + * be seeing such an END_FINALLY.) */ + if (blockstack_top > 0) { + setup_op = code[blockstack[blockstack_top-1]]; + if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH + || setup_op == SETUP_ASYNC_WITH) { + blockstack_top--; + } + } + break; + } + + /* For the addresses we're interested in, see whether they're + * within a 'finally' block and if so, remember the address + * of the SETUP_FINALLY. */ + if (addr == new_lasti || addr == f->f_lasti) { + int i = 0; + int setup_addr = -1; + for (i = blockstack_top-1; i >= 0; i--) { + if (in_finally[i]) { + setup_addr = blockstack[i]; + break; + } + } + + if (setup_addr != -1) { + if (addr == new_lasti) { + new_lasti_setup_addr = setup_addr; + } + + if (addr == f->f_lasti) { + f_lasti_setup_addr = setup_addr; + } + } + } + } + + /* Verify that the blockstack tracking code didn't get lost. */ + //assert(blockstack_top == 0); + if (blockstack_top != 0) { + PyErr_SetString(PyExc_ValueError, + "can't jump blockstack_top pointer got lost"); + return -1; + } + + /* After all that, are we jumping into / out of a 'finally' block? */ + if (new_lasti_setup_addr != f_lasti_setup_addr) { + PyErr_SetString(PyExc_ValueError, + "can't jump into or out of a 'finally' block"); + return -1; + } + + + /* Police block-jumping (you can't jump into the middle of a block) + * and ensure that the blockstack finishes up in a sensible state (by + * popping any blocks we're jumping out of). We look at all the + * blockstack operations between the current position and the new + * one, and keep track of how many blocks we drop out of on the way. + * By also keeping track of the lowest blockstack position we see, we + * can tell whether the jump goes into any blocks without coming out + * again - in that case we raise an exception below. */ + delta_iblock = 0; + for (addr = min_addr; addr < max_addr; addr += sizeof(_Py_CODEUNIT)) { + unsigned char op = code[addr]; + switch (op) { + case SETUP_LOOP: + case SETUP_EXCEPT: + case SETUP_FINALLY: + case SETUP_WITH: + case SETUP_ASYNC_WITH: + delta_iblock++; + break; + + case POP_BLOCK: + delta_iblock--; + break; + } + + min_delta_iblock = Py_MIN(min_delta_iblock, delta_iblock); + } + + /* Derive the absolute iblock values from the deltas. */ + min_iblock = f->f_iblock + min_delta_iblock; + if (new_lasti > f->f_lasti) { + /* Forwards jump. */ + new_iblock = f->f_iblock + delta_iblock; + } + else { + /* Backwards jump. */ + new_iblock = f->f_iblock - delta_iblock; + } + + /* Are we jumping into a block? */ + if (new_iblock > min_iblock) { + PyErr_SetString(PyExc_ValueError, + "can't jump into the middle of a block"); + return -1; + } + + /* Pop any blocks that we're jumping out of. */ + while (f->f_iblock > new_iblock) { + PyTryBlock *b = &f->f_blockstack[--f->f_iblock]; + while ((f->f_stacktop - f->f_valuestack) > b->b_level) { + PyObject *v = (*--f->f_stacktop); + Py_DECREF(v); + } + if (b->b_type == SETUP_FINALLY && + code[b->b_handler] == WITH_CLEANUP_START) + { + /* Pop the exit function. */ + PyObject *v = (*--f->f_stacktop); + Py_DECREF(v); + } + } + + /* Finally set the new f_lineno and f_lasti and return OK. */ + f->f_lineno = new_lineno; + f->f_lasti = new_lasti; + return 0; +} + + +#endif + //============================================================================= // METHOD : SPELLpythonHelper::setNewLine(); //============================================================================= bool SPELLpythonHelper::setNewLine( PyFrameObject* frame, const int& new_lineno, const int& new_lasti ) { LOG_WARN("[PYH] Changing line number on frame " + PYCREPR(frame)); + LOG_WARN("[PYH] new_lineno = " + ISTR(new_lineno) + " new_lasti = " + ISTR(new_lasti)); + +#if PY_MAJOR_VERSION >= 3 + PyObject* line = PyLong_FromLong(new_lineno); + int success = -1; + // In case frame->f_stacktop is NULL and frame->f_back is not NULL, + // (case when just returned from a function call) + // set current frame to the previous frame + // Otherwise, keep using current frame + // (case of a return into the root frame for example) + if (frame->f_stacktop == NULL && frame->f_back != NULL) + frame = frame->f_back; + success = frame_setlineno(frame, line, NULL); + PyObject* err = PyErr_Occurred(); + if (err != NULL) + { + std::cerr << std::endl << "===============================" << std::endl; + //PyErr_Print(); + PyObject* ptype; + PyObject* pvalue; + PyObject* ptraceback; + PyErr_Fetch( &ptype, &pvalue, &ptraceback ); + std::cerr << "TYPE : " << PYREPR(ptype) << std::endl; + std::cerr << "VALUE: " << PYREPR(pvalue) << std::endl; + if (ptraceback) + { + std::cerr << "Traceback: " << std::endl; + PyTracebackObject* traceback = (PyTracebackObject*) ptraceback; + while(traceback != NULL) + { + std::cerr << "at " << PYREPR(traceback->tb_frame->f_code->co_filename) << ":" << traceback->tb_lineno << std::endl; + traceback = traceback->tb_next; + } + } + + std::cerr << "===============================" << std::endl << std::endl; + // Parse the exception to give better information about the error on python side + PyObject* spellException = SPELLpythonHelper::instance().getObject("spell.lib.exception", "SpellException"); + std::string excType = PYREPR(ptype); + if (PyObject_IsInstance( pvalue, spellException )) + { + PyObject* msg = PyObject_GetAttrString( pvalue, "message" ); + PyObject* rea = PyObject_GetAttrString( pvalue, "reason" ); + std::string message = ""; + std::string reason = ""; + if (msg != NULL) + { + message = PYSSTR(msg); + } + if (rea != NULL ) + { + reason = PYSSTR(rea); + } + /** \todo decide the fatal flag value */ + std::cerr << "RAISING INTERNAL DRIVER EXCEPTION" << std::endl; + PyErr_Clear(); + THROW_EXCEPTION("Cannot set new line", reason, SPELL_DRIVER_ERROR ); + } + else if ( PYREPR(pvalue) == "EXECUTION ABORTED" || PYREPR(pvalue) == "EXECUTION TERMINATED" ) + { + // Do not raise exceptions if the detected exception is an aborted or finished internal exception + PyErr_Clear(); + return false; + } + else + { + std::cerr << "RAISING PYTHON ERROR EXCEPTION" << std::endl; + PyErr_Clear(); + THROW_EXCEPTION("Cannot set new line", PYSSTR(pvalue), SPELL_ERROR_PYTHON_API ); + } + } +#else ///////////////////////////////////////////////////////// // THIS IS NASTY: copied from Python 2.5 implementation ///////////////////////////////////////////////////////// @@ -1051,10 +1560,10 @@ bool SPELLpythonHelper::setNewLine( PyFrameObject* frame, const int& new_lineno, * cases (AFAIK) where a line's code can start with DUP_TOP or * POP_TOP, but if any ever appear, they'll be subject to the same * restriction (but with a different error message). */ - if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) - { - THROW_EXCEPTION("Cannot set new line", "Cannot go inside a try/except block", SPELL_ERROR_PYTHON_API); - } + //if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) + //{ + // THROW_EXCEPTION("Cannot set new line", "Cannot go inside a try/except block", SPELL_ERROR_PYTHON_API); + //} /* You can't jump into or out of a 'finally' block because the 'try' * block leaves something on the stack for the END_FINALLY to clean @@ -1215,6 +1724,7 @@ bool SPELLpythonHelper::setNewLine( PyFrameObject* frame, const int& new_lineno, /* Finally set the new f_lineno and f_lasti and return OK. */ frame->f_lineno = new_lineno; frame->f_lasti = new_lasti; +#endif LOG_WARN("[PYH] Set frame lineno " + ISTR(new_lineno) + ":" + ISTR(new_lasti)); return true; } @@ -1230,6 +1740,7 @@ PyFrameObject* SPELLpythonHelper::createFrame( const std::string& filename, PyCo PyObject* mainModule = PyImport_AddModule("__main__"); + if (mainModule == NULL) { THROW_EXCEPTION("Unable to create frame", "Cannot access main module", SPELL_ERROR_PYTHON_API ); @@ -1256,11 +1767,32 @@ PyFrameObject* SPELLpythonHelper::createFrame( const std::string& filename, PyCo return NULL; } } + DEBUG("[PYH] Frame creation"); - frame = PyFrame_New( PyThreadState_Get(), code, mainDict, mainDict ); + + frame = PyFrame_New( PyThreadState_Get(), code,mainDict , NULL ); Py_INCREF(frame); return frame; } +//============================================================================= +// METHOD : SPELLpythonHelper::createFrame(); +//============================================================================= +PyFrameObject* SPELLpythonHelper::createFrameFromFunction( const std::string& filename, PyObject* func ) +{ + DEBUG("[PYH] Creating frame for code " + PYCREPR(func)); + + PyFrameObject* frame = NULL; + + PyCodeObject* code = (PyCodeObject*)PyFunction_GetCode(func); + PyObject* globals = PyFunction_GetGlobals(func); + Py_INCREF(globals); + Py_INCREF(code); + frame = PyFrame_New( PyThreadState_Get(), code,globals , NULL); + + Py_INCREF(frame); + checkError(); + return frame; +} //============================================================================= // METHOD : SPELLpythonHelper::checkError @@ -1290,6 +1822,7 @@ void SPELLpythonHelper::checkError() traceback = traceback->tb_next; } } + std::cerr << "===============================" << std::endl << std::endl; // Parse the exception to give better information about the error on python side PyObject* spellException = SPELLpythonHelper::instance().getObject("spell.lib.exception", "SpellException"); diff --git a/lib/SPELL_UTIL/src/SPELLtime.C b/lib/SPELL_UTIL/src/SPELLtime.C index 71015be..3c9a666 100644 --- a/lib/SPELL_UTIL/src/SPELLtime.C +++ b/lib/SPELL_UTIL/src/SPELLtime.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the time object // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -47,7 +47,7 @@ SPELLtime::SPELLtime() //============================================================================= SPELLtime::SPELLtime( unsigned long secs, bool delta ) { - set(secs,0,delta); + set(secs,0,0,delta); } //============================================================================= @@ -55,7 +55,15 @@ SPELLtime::SPELLtime( unsigned long secs, bool delta ) //============================================================================= SPELLtime::SPELLtime( unsigned long secs, unsigned int msecs, bool delta ) { - set(secs,msecs,delta); + set(secs,msecs,0,delta); +} + +//============================================================================= +// CONSTRUCTOR: SPELLtime::SPELLtime +//============================================================================= +SPELLtime::SPELLtime( unsigned long secs, unsigned int msecs, unsigned int usecs, bool delta ) +{ + set(secs,msecs,usecs,delta); } //============================================================================= @@ -63,7 +71,7 @@ SPELLtime::SPELLtime( unsigned long secs, unsigned int msecs, bool delta ) //============================================================================= SPELLtime::SPELLtime( const SPELLtime& other ) { - set(other.m_secs,other.m_msecs,other.m_delta); + set(other.m_secs,other.m_msecs,other.m_usecs,other.m_delta); } //============================================================================= @@ -83,6 +91,7 @@ SPELLtime& SPELLtime::operator=( const SPELLtime& other ) { m_secs = other.m_secs; m_msecs = other.m_msecs; + m_usecs = other.m_usecs; m_delta = other.m_delta; } // by convention, always return this @@ -95,7 +104,12 @@ SPELLtime& SPELLtime::operator=( const SPELLtime& other ) SPELLtime SPELLtime::operator+(const SPELLtime& other) { SPELLtime result(0,true); - result.set( m_secs + other.m_secs, m_msecs + other.m_msecs, m_delta && other.m_delta ); + // Check for overflow + unsigned long secs = m_secs + other.m_secs; + unsigned int usecs = m_usecs + other.m_usecs; + secs += usecs / (1000*1000); + usecs %= (1000*1000); + result.set( secs, usecs/1000, usecs, m_delta && other.m_delta ); return result; } @@ -104,7 +118,12 @@ SPELLtime SPELLtime::operator+(const SPELLtime& other) //============================================================================= SPELLtime& SPELLtime::operator+=(SPELLtime& other) { - set( m_secs + other.m_secs, m_msecs + other.m_msecs, m_delta && other.m_delta ); + // Check for overflow + unsigned long secs = m_secs + other.m_secs; + unsigned int usecs = m_usecs + other.m_usecs; + secs += usecs / (1000*1000); + usecs %= (1000*1000); + set( secs, usecs/1000, usecs, m_delta && other.m_delta ); return *this; } @@ -117,7 +136,8 @@ SPELLtime SPELLtime::operator-(const SPELLtime& other) bool delta = (m_delta && other.m_delta) || (!m_delta && !other.m_delta); long secs = m_secs - other.m_secs; int msecs = m_msecs - other.m_msecs; - result.set( (secs>0)? secs: 0, (msecs>0)? msecs: 0, delta ); + int usecs = m_usecs - other.m_usecs; + result.set( (secs>0)? secs: 0, (msecs>0)? msecs: 0, (usecs>0)? usecs: 0, delta ); return result; } @@ -129,7 +149,8 @@ SPELLtime& SPELLtime::operator-=(SPELLtime& other) bool delta = (m_delta && other.m_delta) || (!m_delta && !other.m_delta); long secs = m_secs - other.m_secs; int msecs = m_msecs - other.m_msecs; - set( (secs>0)? secs: 0, (msecs>0)? msecs: 0, delta ); + int usecs = m_usecs - other.m_usecs; + set( (secs>0)? secs: 0, (msecs>0)? msecs: 0, (usecs>0)? usecs: 0, delta ); return *this; } @@ -142,6 +163,10 @@ bool SPELLtime::operator<( const SPELLtime& other ) const if (m_secs == other.m_secs) { if (m_msecs < other.m_msecs) return true; + if (m_msecs == other.m_msecs) + { + if (m_usecs < other.m_usecs) return true; + } } return false; } @@ -155,6 +180,10 @@ bool SPELLtime::operator>( const SPELLtime& other ) const if (m_secs == other.m_secs) { if (m_msecs > other.m_msecs) return true; + if (m_msecs == other.m_msecs) + { + if (m_usecs > other.m_usecs) return true; + } } return false; } @@ -178,25 +207,25 @@ bool SPELLtime::operator<( const unsigned long& secs ) const } //============================================================================= -// METHOD: SPELLtime::operator< +// METHOD: SPELLtime::operator== //============================================================================= bool SPELLtime::operator==( const SPELLtime& other ) const { - if (m_secs == other.m_secs) + if (m_secs == other.m_secs && m_msecs == other.m_msecs && m_usecs == other.m_usecs) { - if (m_msecs == other.m_msecs) return true; + return true; } return false; } //============================================================================= -// METHOD: SPELLtime::operator< +// METHOD: SPELLtime::operator== //============================================================================= bool SPELLtime::operator==( const unsigned long& secs ) const { if (m_secs == secs) { - if (m_msecs == 0) return true; + if (m_msecs == 0 && m_usecs == 0) return true; } return false; } @@ -206,10 +235,14 @@ bool SPELLtime::operator==( const unsigned long& secs ) const //============================================================================= bool SPELLtime::operator>=( const SPELLtime& other ) const { - if (m_secs >= other.m_secs) return true; + if (m_secs > other.m_secs ) return true; if (m_secs == other.m_secs) { - if (m_msecs >= other.m_msecs) return true; + if (m_msecs > other.m_msecs) return true; + if (m_msecs == other.m_msecs) + { + if (m_usecs >= other.m_usecs) return true; + } } return false; } @@ -219,10 +252,14 @@ bool SPELLtime::operator>=( const SPELLtime& other ) const //============================================================================= bool SPELLtime::operator<=( const SPELLtime& other ) const { - if (m_secs <= other.m_secs) return true; + if (m_secs < other.m_secs) return true; if (m_secs == other.m_secs) { - if (m_msecs <= other.m_msecs) return true; + if (m_msecs < other.m_msecs) return true; + if (m_msecs == other.m_msecs) + { + if (m_usecs <= other.m_usecs) return true; + } } return false; } @@ -232,7 +269,7 @@ bool SPELLtime::operator<=( const SPELLtime& other ) const //============================================================================= std::string SPELLtime::toString() const { - if (m_secs==0) + if (m_secs==0 && m_msecs==0 && m_usecs==0) { return "0"; } @@ -245,6 +282,7 @@ std::string SPELLtime::toString() const if (seconds<60) // Very short date format { timeStr = ISTR(seconds); + timeStr += getMicrosecondsSuffix(); } else { @@ -267,6 +305,8 @@ std::string SPELLtime::toString() const //Seconds if ( seconds < 10 ) timeStr += "0"; timeStr += ISTR(seconds); + //Milliseconds+Microseconds + timeStr += getMicrosecondsSuffix(); } } //Absolute date e.g. 2009-12-07 16:55:12 @@ -274,7 +314,7 @@ std::string SPELLtime::toString() const { time_t seconds = m_secs; struct tm* ptm = localtime(&seconds); - if (ptm==NULL) + if (ptm==NULL && m_msecs==0 && m_usecs==0) { return "\?\?\?\?-\?\?-\?\? \?\?:\?\?:\?\?"; } @@ -294,16 +334,19 @@ std::string SPELLtime::toString() const //Seconds if ( ptm->tm_sec < 10 ) timeStr += "0"; timeStr += ISTR(ptm->tm_sec); + //Milliseconds+Microseconds + timeStr += getMicrosecondsSuffix(); } return timeStr; } + //============================================================================= // METHOD: SPELLtime::toString //============================================================================= std::string SPELLtime::toTIMEString() const { - if (m_secs==0) + if (m_secs==0 && m_msecs==0 && m_usecs==0) { return "+000 00:00:00"; } @@ -336,13 +379,15 @@ std::string SPELLtime::toTIMEString() const //Seconds if ( seconds < 10 ) timeStr += "0"; timeStr += ISTR(seconds); + //Milliseconds+Microseconds + timeStr += getMicrosecondsSuffix(); } //Absolute date e.g. e.g. 2009-12-07:16:55:12 else { time_t seconds = m_secs; struct tm* ptm = localtime(&seconds); - if (ptm==NULL) + if (ptm==NULL && m_msecs==0 && m_usecs==0) { return "\?\?\?\?-\?\?-\?\? \?\?:\?\?:\?\?"; } @@ -353,7 +398,7 @@ std::string SPELLtime::toTIMEString() const if (month.length()==1) month = "0" + month; std::string day = ISTR(ptm->tm_mday); if (day.length()==1) day = "0" + day; - timeStr += month + "-" + day + ":"; + timeStr += month + "-" + day + " "; //Hours if ( ptm->tm_hour < 10 ) timeStr += "0"; @@ -364,6 +409,8 @@ std::string SPELLtime::toTIMEString() const //Seconds if ( ptm->tm_sec < 10 ) timeStr += "0"; timeStr += ISTR(ptm->tm_sec); + //Milliseconds+Microseconds + timeStr += getMicrosecondsSuffix(); } return timeStr; } @@ -374,7 +421,7 @@ std::string SPELLtime::toTIMEString() const void SPELLtime::setCurrent() { SPELLutils::SPELLtimeDesc time = SPELLutils::getSystemTime(); - set( time.seconds, time.useconds/1000, false ); + set( time.seconds, time.useconds/1000, time.useconds%1000, false ); } //============================================================================= @@ -382,20 +429,46 @@ void SPELLtime::setCurrent() //============================================================================= void SPELLtime::set( unsigned long secs, unsigned int msecs ) { - set(secs,msecs,true); + set(secs,msecs,0,true); } //============================================================================= // METHOD: SPELLtime::set //============================================================================= -void SPELLtime::set( unsigned long secs, unsigned int msecs, bool delta ) +void SPELLtime::set( unsigned long secs, unsigned int msecs, unsigned int usecs ) +{ + set(secs,msecs,usecs,true); +} + +//============================================================================= +// METHOD: SPELLtime::set +//============================================================================= +void SPELLtime::set( unsigned long secs, unsigned int msecs, unsigned int usecs, bool delta ) { m_secs = secs; m_msecs = msecs; + m_usecs = usecs; m_delta = delta; - //DEBUG("[TIME] Set time: " + ISTR(m_secs) + ", " + ISTR(m_msecs) + ", " + BSTR(m_delta)) + //DEBUG("[TIME] Set time: " + ISTR(m_secs) + ", " + ISTR(m_msecs) + ", " + ISTR(m_usecs) + ", " + BSTR(m_delta)) } +//============================================================================= +// METHOD: SPELLtime::getMicrosecondsSuffix +//============================================================================= +std::string SPELLtime::getMicrosecondsSuffix() const { + std::stringstream ss; + if ( m_msecs == 0 && m_usecs == 0 ) + { + return ""; + } + ss << "."; + ss << std::setfill('0') << std::setw(3) << m_msecs; + if ( m_usecs%1000 != 0) { + ss << std::setfill('0') << std::setw(3) << m_usecs%1000; + } + return ss.str(); +}; + //============================================================================= // STATIC: SPELLticker::tickIn //============================================================================= diff --git a/lib/SPELL_UTIL/src/SPELLutils.C b/lib/SPELL_UTIL/src/SPELLutils.C index 47a0352..36770b5 100644 --- a/lib/SPELL_UTIL/src/SPELLutils.C +++ b/lib/SPELL_UTIL/src/SPELLutils.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the utilities // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -29,6 +29,7 @@ #include "SPELL_UTIL/SPELLbase.H" #include "SPELL_UTIL/SPELLerror.H" #include "SPELL_UTIL/SPELLpythonMonitors.H" +#include "SPELL_IPC/SPELLipcError.H" // Project includes -------------------------------------------------------- #include "SPELL_WRP/SPELLpyHandle.H" // System includes --------------------------------------------------------- @@ -36,8 +37,6 @@ static int s_timeFormat = TIME_FORMAT_DEFAULT; - - //============================================================================ // FUNCTION : PYSIZE //============================================================================ @@ -146,7 +145,7 @@ std::string SPELLutils::pyObjectRepr( PyObject* obj ) SPELLpyHandle str = PyObject_Repr(obj); if (str.get() != NULL) { - result = PyString_AsString(str.get()); + result = std::string(PyString_AsString(str.get())); } return result; } @@ -186,7 +185,6 @@ std::map > SPELLutils::tokenizeData( const std::s std::vector value; unsigned int keyLength; unsigned int valueLength; - unsigned int byte; unsigned int pos; for( pos = 0 ; pos < data.size() ; ) @@ -201,6 +199,10 @@ std::map > SPELLutils::tokenizeData( const std::s valueLength += (((unsigned char) data[pos+2]) << 8); valueLength += (unsigned char) data[pos+3]; pos += 4; + if (pos + valueLength > data.size()) + { + throw SPELLipcError( "Peer has sent bad data disconnecting!", 0); + } value.assign(data.begin() + pos, data.begin() + pos + valueLength); pos += valueLength; @@ -428,6 +430,20 @@ bool SPELLutils::isFile( const std::string& path ) return isFile; } +//============================================================================ +// FUNCTION : SPELLutils::isLink +//============================================================================ +bool SPELLutils::isLink( const std::string& path ) +{ + struct stat buf; + bool isLink = false; + if (stat(path.c_str(),&buf) == 0) + { + isLink = S_ISLNK( buf.st_mode ); + } + return isLink; +} + //============================================================================ // FUNCTION : SPELLutils::fileCopy //============================================================================ @@ -448,6 +464,18 @@ void SPELLutils::copyFile( const std::string& sourcePath, const std::string& tar outfile.close(); } +bool compare_nocase (const std::string& first, const std::string& second) +{ + unsigned int i=0; + while ( (itolower(second[i])) return false; + ++i; + } + return ( first.length() < second.length() ); +} + //============================================================================ // FUNCTION : SPELLutils::getFilesInDir //============================================================================ @@ -455,6 +483,7 @@ std::list SPELLutils::getFilesInDir( const std::string& path ) { DIR *dirp; struct dirent *dp; + char buffer[512]; std::list files; @@ -463,7 +492,29 @@ std::list SPELLutils::getFilesInDir( const std::string& path ) { while ( (dp = readdir(dirp)) != NULL ) { - if (dp->d_type & DT_REG) + if (dp->d_type == DT_LNK) + { + // Check the target of the link + std::string abspath = path + "/" + dp->d_name; + ssize_t fwd = readlink( abspath.c_str(), buffer, 512); + // Ignore it in case of errors + if (fwd<0) + { + LOG_ERROR("Unable to follow link " + std::string(dp->d_name)); + continue; + } + std::string target_name(buffer,fwd); + if (target_name.find("/") != 0) // root path target + { + target_name = path + "/" + target_name; + } + LOG_WARN("Resolving file link " + std::string(dp->d_name) + " to " + target_name); + if (SPELLutils::isFile(target_name)) + { + files.push_back(dp->d_name); + } + } + else if (dp->d_type == DT_REG) { files.push_back(dp->d_name); } @@ -484,6 +535,8 @@ std::list SPELLutils::getFilesInDir( const std::string& path ) { LOG_ERROR("Failed to open directory '" + path + "' to read"); } + files.sort(compare_nocase); + return files; } @@ -494,10 +547,11 @@ std::list SPELLutils::getSubdirs( const std::string& path ) { DIR* dirp; struct dirent *dp; + char buffer[512]; std::string dot = "."; std::string pdot = ".."; - std::string svn = ".svn"; + std::list subdirs; dirp = opendir( path.c_str() ); @@ -505,23 +559,45 @@ std::list SPELLutils::getSubdirs( const std::string& path ) { while ( (dp = readdir(dirp)) != NULL ) { - if (dp->d_type & DT_DIR) + std::string fname = dp->d_name; + if ( fname.find(".") == 0 ) + continue; // discard ., .., all hidden directories including .svn and .git + + if (dp->d_type == DT_LNK) { - if ( dp->d_name != dot && dp->d_name != pdot && dp->d_name != svn ) + // Check the target of the link + std::string abspath = path + "/" + dp->d_name; + LOG_WARN("Found link " + abspath); + + ssize_t fwd = readlink( abspath.c_str(), buffer, 512); + // Ignore it in case of errors + if (fwd<0) + { + LOG_ERROR("Unable to follow link " + std::string(dp->d_name)); + continue; + } + std::string target_name(buffer,fwd); + if (target_name.find("/") != 0) // root path target + { + target_name = path + "/" + target_name; + } + LOG_WARN("Resolving directory link " + std::string(dp->d_name) + " to " + target_name); + if (SPELLutils::isDirectory(target_name)) { subdirs.push_back(dp->d_name); } } + else if (dp->d_type & DT_DIR) + { + subdirs.push_back(dp->d_name); + } // IMPORTANT: in some filesystems, the type may be impossible // to get with readdir. In these cases we need to use stat(). else if (dp->d_type == DT_UNKNOWN) { if ( isDirectory( path + PATH_SEPARATOR + std::string(dp->d_name) ) ) { - if ( dp->d_name != dot && dp->d_name != pdot && dp->d_name != svn ) - { - subdirs.push_back(dp->d_name); - } + subdirs.push_back(dp->d_name); } } // Ignore other types like symbolic links, sockets, etc. @@ -665,9 +741,7 @@ void SPELLutils::showEnvironment() envVar("SPELL_COTS"); envVar("SPELL_DATA"); envVar("SPELL_CONFIG"); - envVar("SPELL_SYS_DATA"); envVar("SPELL_LOG"); - envVar("SPELL_PROCS"); std::cerr << "==============================================================================" << std::endl; } @@ -771,7 +845,11 @@ void SPELLutils::dumpInterpreterInfo( const std::string& id ) dumpFile << "Modules : " << PYSIZE(currIS->modules) << " items." << std::endl; dumpFile << "Sysdict : " << PYSIZE(currIS->sysdict) << " items." << std::endl; dumpFile << "Builtins : " << PYSIZE(currIS->builtins) << " items." << std::endl; +#if PY_MAJOR_VERSION >= 3 + +#else dumpFile << "Reloading : " << PYSIZE(currIS->modules_reloading) << " items." << std::endl; +#endif dumpFile << "Search path : " << PYSIZE(currIS->codec_search_path) << " items." << std::endl; dumpFile << "Search cache: " << PYSIZE(currIS->codec_search_cache) << " items." << std::endl; dumpFile << "Error regst.: " << PYSIZE(currIS->codec_error_registry) << " items." << std::endl; @@ -825,11 +903,22 @@ void SPELLutils::dumpThreadStateInfo( const std::string& id, PyThreadState* ts, dumpFile << "Current exc. type : " << PYREPR(ts->curexc_type) << std::endl; dumpFile << "Current exc. value: " << PYREPR(ts->curexc_value) << std::endl; dumpFile << "Current exc. tback: " << PYREPR(ts->curexc_traceback) << std::endl; +#if PY_MAJOR_VERSION >= 3 + if (ts->exc_info) + { + dumpFile << "Exception type : " << PYREPR(ts->exc_info->exc_type) << std::endl; + dumpFile << "Exception value : " << PYREPR(ts->exc_info->exc_value) << std::endl; + dumpFile << "Exception tback : " << PYREPR(ts->exc_info->exc_traceback) << std::endl; + } +#else dumpFile << "Exception type : " << PYREPR(ts->exc_type) << std::endl; dumpFile << "Exception value : " << PYREPR(ts->exc_value) << std::endl; dumpFile << "Exception tback : " << PYREPR(ts->exc_traceback) << std::endl; +#endif dumpFile << "Main dict : " << PYSIZE(ts->dict) << " items." << std::endl; +#if PY_MAJOR_VERSION < 3 dumpFile << "Tick counter : " << ts->tick_counter << std::endl; +#endif dumpFile << "GIL state counter : " << ts->gilstate_counter << std::endl; dumpFile << "Async. exception : " << PYREPR(ts->async_exc) << std::endl; dumpFile << "Thread id : " << ts->thread_id << std::endl; @@ -866,7 +955,9 @@ void SPELLutils::dumpFrameInfo( const std::string& id, PyFrameObject* frame, int dumpFile << "--------------------------------------" << std::endl; dumpFile << "Address : " << PSTR(frame) << std::endl; dumpFile << "Next address : " << PSTR(frame->f_back) << std::endl; +#if PY_MAJOR_VERSION < 3 dumpFile << "Thread state address : " << PSTR(frame->f_tstate) << std::endl; +#endif dumpFile << "Last instruction : " << frame->f_lasti << std::endl; dumpFile << "Last line : " << frame->f_lineno << std::endl; dumpFile << "Try blocks count : " << frame->f_iblock << std::endl; @@ -875,9 +966,11 @@ void SPELLutils::dumpFrameInfo( const std::string& id, PyFrameObject* frame, int dumpFile << "Stack top : " << PSTR(frame->f_stacktop) << std::endl; dumpFile << "Stack count : " << (frame->f_stacktop - frame->f_valuestack) << std::endl; dumpFile << "Fast locals : " << (frame->f_code->co_nlocals-1) << std::endl; +#if PY_MAJOR_VERSION < 3 dumpFile << "Exception type : " << PYREPR(frame->f_exc_type) << std::endl; dumpFile << "Exception value : " << PYREPR(frame->f_exc_value) << std::endl; dumpFile << "Exception traceback : " << PYREPR(frame->f_exc_traceback) << std::endl; +#endif dumpFile << "Trace function : " << PYREPR(frame->f_trace) << std::endl; dumpFile << "Builtins : " << PYSIZE(frame->f_builtins) << std::endl; dumpFile << "Globals : " << PYSIZE(frame->f_globals) << std::endl; @@ -991,3 +1084,18 @@ SPELLutils::SPELLdateDesc SPELLutils::getSystemDate() return date; } + +//============================================================================ +// FUNCTION: SPELLutils::compareNocase (const std::string& first, const std::string& second) +//============================================================================ +bool SPELLutils::compareNocase (const std::string& first, const std::string& second) +{ + unsigned int i=0; + while ( (itolower(second[i])) return false; + ++i; + } + return ( first.length() < second.length() ); +} diff --git a/lib/SPELL_WRP/Makefile.am b/lib/SPELL_WRP/Makefile.am index dad5810..8967b5a 100644 --- a/lib/SPELL_WRP/Makefile.am +++ b/lib/SPELL_WRP/Makefile.am @@ -1,36 +1,44 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_WRP.la -libSPELL_WRP_la_LDFLAGS = -version-info 1:0:0 -libSPELL_WRP_la_SOURCES = \ - src/SPELLdriverManager.C \ - src/SPELLdatabaseManager.C \ - src/SPELLpyValue.C \ - src/SPELLconfigDict.C \ - src/SPELLregistry.C - + +lib_LTLIBRARIES = libSPELL_WRP_v2.la libSPELL_WRP_v3.la + +libSPELL_WRP_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_WRP_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_WRP_v2_la_SOURCES = src/SPELLdriverManager.C \ + src/SPELLdatabaseManager.C \ + src/SPELLpyValue.C \ + src/SPELLconfigDict.C \ + src/SPELLregistry.C + +libSPELL_WRP_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_WRP_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_WRP_v3_la_SOURCES = src/SPELLdriverManager.C \ + src/SPELLdatabaseManager.C \ + src/SPELLpyValue.C \ + src/SPELLconfigDict.C \ + src/SPELLregistry.C \ No newline at end of file diff --git a/lib/SPELL_WRP/src/SPELLconfigDict.C b/lib/SPELL_WRP/src/SPELLconfigDict.C index 4be6332..72a97f0 100644 --- a/lib/SPELL_WRP/src/SPELLconfigDict.C +++ b/lib/SPELL_WRP/src/SPELLconfigDict.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the configuration dictionary wrapper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WRP/src/SPELLdatabaseManager.C b/lib/SPELL_WRP/src/SPELLdatabaseManager.C index f6bb4b1..774fb3d 100644 --- a/lib/SPELL_WRP/src/SPELLdatabaseManager.C +++ b/lib/SPELL_WRP/src/SPELLdatabaseManager.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the database manager wrapper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -83,15 +83,26 @@ PyObject* SPELLdatabaseManager::getDatabaseManagerObject() //============================================================================= void SPELLdatabaseManager::loadBuiltinDatabases() { - SPELLsafePythonOperations ops("SPELLdatabaseManager::loadBuiltinDatabases()"); - PyObject* mgr = getDatabaseManagerObject(); - // New reference - PyObject* scdb = SPELLpythonHelper::instance().callMethod( mgr, "loadDatabase", STRPY("SCDB"), NULL); - SPELLpythonHelper::instance().checkError(); - // New reference - PyObject* gdb = SPELLpythonHelper::instance().callMethod( mgr, "loadDatabase", STRPY("GDB"), NULL ); - SPELLpythonHelper::instance().checkError(); - SPELLpythonHelper::instance().install( scdb, "SCDB" ); - SPELLpythonHelper::instance().install( gdb, "GDB" ); - SPELLpythonHelper::instance().checkError(); + try { + PyObject* mgr = getDatabaseManagerObject(); + // New reference + PyObject* scdb = SPELLpythonHelper::instance().callMethod( mgr, "loadDatabase", STRPY("SCDB"), NULL); + SPELLpythonHelper::instance().checkError(); + // New reference + PyObject* gdb = SPELLpythonHelper::instance().callMethod( mgr, "loadDatabase", STRPY("GDB"), NULL ); + SPELLpythonHelper::instance().checkError(); + SPELLpythonHelper::instance().install( scdb, "SCDB" ); + SPELLpythonHelper::instance().install( gdb, "GDB" ); + SPELLpythonHelper::instance().checkError(); + } + catch(SPELLcoreException& ex) + { + LOG_ERROR("loadBuiltinDatabases failed: " + ex.what()); + throw ex; + } + catch(...) + { + LOG_ERROR("loadBuiltinDatabases failed: Unknown!"); + throw; + } } diff --git a/lib/SPELL_WRP/src/SPELLdriverManager.C b/lib/SPELL_WRP/src/SPELLdriverManager.C index cddf1f4..48a14a3 100644 --- a/lib/SPELL_WRP/src/SPELLdriverManager.C +++ b/lib/SPELL_WRP/src/SPELLdriverManager.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the driver manager wrapper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -35,7 +35,6 @@ #include "SPELL_CFG/SPELLconfiguration.H" - SPELLdriverManager* SPELLdriverManager::s_instance = 0; //============================================================================= @@ -73,6 +72,7 @@ PyObject* SPELLdriverManager::getDriverManagerObject() if (m_dManager == 0) { // Borrowed + SPELLsafePythonOperations ops("SPELLdriverManager::setup()"); PyObject* classObj = SPELLpythonHelper::instance().getObject("spell.lib.drivermgr", "DriverManager"); m_dManager = SPELLpythonHelper::instance().callMethod( classObj, "instance", NULL ); Py_XINCREF(m_dManager); @@ -85,17 +85,29 @@ PyObject* SPELLdriverManager::getDriverManagerObject() //============================================================================= void SPELLdriverManager::setup( const std::string& ctxName, const std::string& interfaces ) { - SPELLsafePythonOperations ops("SPELLdriverManager::setup()"); - PyObject* pmgr = getDriverManagerObject(); - if (interfaces.empty()) + try + { + PyObject* pmgr = getDriverManagerObject(); + if (interfaces.empty()) + { + SPELLpythonHelper::instance().callMethod( pmgr, "setup", SSTRPY(ctxName), NULL); + } + else + { + SPELLpythonHelper::instance().callMethod( pmgr, "setup", SSTRPY(ctxName), SSTRPY(interfaces), NULL); + } + SPELLpythonHelper::instance().checkError(); + } + catch(SPELLcoreException& ex) { - SPELLpythonHelper::instance().callMethod( pmgr, "setup", SSTRPY(ctxName), NULL); + LOG_ERROR("Setup failed: " + ex.what()); + throw ex; } - else + catch(...) { - SPELLpythonHelper::instance().callMethod( pmgr, "setup", SSTRPY(ctxName), SSTRPY(interfaces), NULL); + LOG_ERROR("Setup failed: Unknown!"); + throw; } - SPELLpythonHelper::instance().checkError(); } //============================================================================= @@ -103,17 +115,27 @@ void SPELLdriverManager::setup( const std::string& ctxName, const std::string& i //============================================================================= void SPELLdriverManager::cleanup( bool shutdown ) { - SPELLsafePythonOperations ops("SPELLdriverManager::cleanup()"); - PyObject* pmgr = getDriverManagerObject(); - if (shutdown) + try + { + PyObject* pmgr = getDriverManagerObject(); + if (shutdown) + { + SPELLpythonHelper::instance().callMethod( pmgr, "cleanup", Py_False, Py_True, NULL ); + } + else + { + SPELLpythonHelper::instance().callMethod( pmgr, "cleanup", NULL); + } + SPELLpythonHelper::instance().checkError(); + } + catch(SPELLcoreException& ex) { - SPELLpythonHelper::instance().callMethod( pmgr, "cleanup", Py_False, Py_True, NULL ); + LOG_ERROR("Cleanup failed: " + ex.what()); } - else + catch(...) { - SPELLpythonHelper::instance().callMethod( pmgr, "cleanup", NULL); + LOG_ERROR("Cleanup failed: Unknown!"); } - SPELLpythonHelper::instance().checkError(); } //============================================================================= @@ -121,11 +143,12 @@ void SPELLdriverManager::cleanup( bool shutdown ) //============================================================================= void SPELLdriverManager::onCommand( const std::string& commandId ) { - PyObject* pmgr = getDriverManagerObject(); - PyObject* cmd = SSTRPY(commandId); - Py_INCREF(cmd); try { + SPELLsafePythonOperations ops("SPELLdriverManager::onCommand"); + PyObject* pmgr = getDriverManagerObject(); + PyObject* cmd = SSTRPY(commandId); + Py_INCREF(cmd); SPELLpythonHelper::instance().callMethod( pmgr, "onCommand", cmd, NULL ); SPELLpythonHelper::instance().checkError(); } diff --git a/lib/SPELL_WRP/src/SPELLpyValue.C b/lib/SPELL_WRP/src/SPELLpyValue.C index 5da3343..f534302 100644 --- a/lib/SPELL_WRP/src/SPELLpyValue.C +++ b/lib/SPELL_WRP/src/SPELLpyValue.C @@ -5,7 +5,7 @@ // DESCRIPTION: Data variable implementation // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -94,7 +94,7 @@ void SPELLpyValue::set( PyObject* pyValue ) { DEBUG("[PYVAL] Int check"); m_type = LONG; - m_intValue = PyInt_AsLong(pyValue); + m_intValue = PyLong_AsLongLong(pyValue); } else if (PyFloat_Check(pyValue)) { @@ -103,7 +103,7 @@ void SPELLpyValue::set( PyObject* pyValue ) } else if (SPELLpythonHelper::instance().isTime(pyValue)) { - m_timeValue = SPELLpythonHelper::instance().evalTime(PYSSTR(pyValue)); + m_timeValue = SPELLpythonHelper::instance().evalTime(pyValue); if (m_timeValue.isDelta()) { m_type = RELTIME; @@ -173,7 +173,7 @@ PyObject* SPELLpyValue::get() const } else if (m_type == LONG ) { - return PyLong_FromLong(m_intValue); + return PyLong_FromLongLong(m_intValue); } else if (m_type == DOUBLE) { diff --git a/lib/SPELL_WRP/src/SPELLregistry.C b/lib/SPELL_WRP/src/SPELLregistry.C index e682910..7f503a0 100644 --- a/lib/SPELL_WRP/src/SPELLregistry.C +++ b/lib/SPELL_WRP/src/SPELLregistry.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the registry wrapper // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/Makefile.am b/lib/SPELL_WS/Makefile.am index 92b0900..1001f30 100644 --- a/lib/SPELL_WS/Makefile.am +++ b/lib/SPELL_WS/Makefile.am @@ -1,55 +1,71 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ include ${top_srcdir}/common.mk -lib_LTLIBRARIES= libSPELL_WS.la - -libSPELL_WS_la_CPPFLAGS = ${AM_CPPFLAGS} -libSPELL_WS_la_LDFLAGS = -version-info 3:0:0 - -libSPELL_WS_la_SOURCES = \ - src/SPELLwsStorage.C \ - src/SPELLwsDataHandler.C \ - src/SPELLwsDataCodes.C \ - src/SPELLwsDataHandlerFactory.C \ - src/SPELLwsObjectDataHandler.C \ - src/SPELLwsInstanceDataHandler.C \ - src/SPELLwsCustomTypeDataHandler.C \ - src/SPELLwsTmItemDataHandler.C \ - src/SPELLwsClassDataHandler.C \ - src/SPELLwsDictDataHandler.C \ - src/SPELLwsListDataHandler.C \ - src/SPELLwsTupleDataHandler.C \ - src/SPELLwsDbDataHandler.C \ - src/SPELLwsTimeDataHandler.C \ - src/SPELLwsWorkingMode.C \ - src/SPELLwsFrame.C \ - src/SPELLwsDynamicData.C \ - src/SPELLwsStaticData.C \ - src/SPELLwsWarmStartImpl.C - - +lib_LTLIBRARIES = libSPELL_WS_v2.la libSPELL_WS_v3.la + +libSPELL_WS_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +libSPELL_WS_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_WS_v2_la_SOURCES = src/SPELLwsStorage.C \ + src/SPELLwsDataHandler.C \ + src/SPELLwsDataCodes.C \ + src/SPELLwsDataHandlerFactory.C \ + src/SPELLwsObjectDataHandler.C \ + src/SPELLwsInstanceDataHandler.C \ + src/SPELLwsCustomTypeDataHandler.C \ + src/SPELLwsTmItemDataHandler.C \ + src/SPELLwsClassDataHandler.C \ + src/SPELLwsDictDataHandler.C \ + src/SPELLwsListDataHandler.C \ + src/SPELLwsTupleDataHandler.C \ + src/SPELLwsDbDataHandler.C \ + src/SPELLwsTimeDataHandler.C \ + src/SPELLwsWorkingMode.C \ + src/SPELLwsFrame.C \ + src/SPELLwsDynamicData.C \ + src/SPELLwsStaticData.C \ + src/SPELLwsWarmStartImpl.C + +libSPELL_WS_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +libSPELL_WS_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} + +libSPELL_WS_v3_la_SOURCES = src/SPELLwsStorage.C \ + src/SPELLwsDataHandler.C \ + src/SPELLwsDataCodes.C \ + src/SPELLwsDataHandlerFactory.C \ + src/SPELLwsObjectDataHandler.C \ + src/SPELLwsCustomTypeDataHandler.C \ + src/SPELLwsTmItemDataHandler.C \ + src/SPELLwsDictDataHandler.C \ + src/SPELLwsListDataHandler.C \ + src/SPELLwsTupleDataHandler.C \ + src/SPELLwsDbDataHandler.C \ + src/SPELLwsTimeDataHandler.C \ + src/SPELLwsWorkingMode.C \ + src/SPELLwsFrame.C \ + src/SPELLwsDynamicData.C \ + src/SPELLwsStaticData.C \ + src/SPELLwsWarmStartImpl.C + \ No newline at end of file diff --git a/lib/SPELL_WS/src/SPELLwsClassDataHandler.C b/lib/SPELL_WS/src/SPELLwsClassDataHandler.C index bf455d4..5a9762d 100644 --- a/lib/SPELL_WS/src/SPELLwsClassDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsClassDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for classes // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsCustomTypeDataHandler.C b/lib/SPELL_WS/src/SPELLwsCustomTypeDataHandler.C index f64a3b3..5cd4b9b 100644 --- a/lib/SPELL_WS/src/SPELLwsCustomTypeDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsCustomTypeDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for instances // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsDataCodes.C b/lib/SPELL_WS/src/SPELLwsDataCodes.C index f0a50f7..029cf81 100644 --- a/lib/SPELL_WS/src/SPELLwsDataCodes.C +++ b/lib/SPELL_WS/src/SPELLwsDataCodes.C @@ -5,7 +5,7 @@ // DESCRIPTION: Data code functions // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsDataHandler.C b/lib/SPELL_WS/src/SPELLwsDataHandler.C index 33ebf07..247762f 100644 --- a/lib/SPELL_WS/src/SPELLwsDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the base data handler // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsDataHandlerFactory.C b/lib/SPELL_WS/src/SPELLwsDataHandlerFactory.C index b52fed6..29525c3 100644 --- a/lib/SPELL_WS/src/SPELLwsDataHandlerFactory.C +++ b/lib/SPELL_WS/src/SPELLwsDataHandlerFactory.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler factory // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -27,8 +27,10 @@ // FILES TO INCLUDE //////////////////////////////////////////////////////// // Local includes ---------------------------------------------------------- #include "SPELL_WS/SPELLwsDataHandlerFactory.H" +#if PY_MAJOR_VERSION < 3 #include "SPELL_WS/SPELLwsClassDataHandler.H" #include "SPELL_WS/SPELLwsInstanceDataHandler.H" +#endif #include "SPELL_WS/SPELLwsCustomTypeDataHandler.H" #include "SPELL_WS/SPELLwsTmItemDataHandler.H" #include "SPELL_WS/SPELLwsDictDataHandler.H" @@ -85,6 +87,7 @@ SPELLwsDataHandler* SPELLwsDataHandlerFactory::createDataHandler( PyObject* obje //DEBUG("[DHF] Object is TIME"); handler = new SPELLwsTimeDataHandler(object); } +#if PY_MAJOR_VERSION < 3 else if (PyClass_Check(object)) { DEBUG("[DHF] Object is a class: " + PYCREPR(object)); @@ -95,6 +98,7 @@ SPELLwsDataHandler* SPELLwsDataHandlerFactory::createDataHandler( PyObject* obje //DEBUG("[DHF] Object is a instance: " + PYCREPR(object)); handler = new SPELLwsInstanceDataHandler(object); } +#endif else if (SPELLpythonHelper::instance().isSubclassInstance(object, "TmItemClass", "spell.lib.adapter.tm_item")) { //DEBUG("[DHF] Object is a TM item: " + PYCREPR(object)); @@ -129,12 +133,14 @@ SPELLwsDataHandler* SPELLwsDataHandlerFactory::createDataHandler( SPELLwsData::C case SPELLwsData::DATA_GENERIC: handler = new SPELLwsObjectDataHandler(NULL); break; +#if PY_MAJOR_VERSION < 3 case SPELLwsData::DATA_CLASS: handler = new SPELLwsClassDataHandler(NULL); break; case SPELLwsData::DATA_INSTANCE: handler = new SPELLwsInstanceDataHandler(NULL); break; +#endif case SPELLwsData::DATA_CUSTOM_TYPE: handler = new SPELLwsCustomTypeDataHandler(NULL); break; diff --git a/lib/SPELL_WS/src/SPELLwsDbDataHandler.C b/lib/SPELL_WS/src/SPELLwsDbDataHandler.C index 6878064..974e272 100644 --- a/lib/SPELL_WS/src/SPELLwsDbDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsDbDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for SPELL databases // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsDictDataHandler.C b/lib/SPELL_WS/src/SPELLwsDictDataHandler.C index cf4e6fd..2a84ec6 100644 --- a/lib/SPELL_WS/src/SPELLwsDictDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsDictDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for dictionaries // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsDynamicData.C b/lib/SPELL_WS/src/SPELLwsDynamicData.C index 13ffa10..0bc2b03 100644 --- a/lib/SPELL_WS/src/SPELLwsDynamicData.C +++ b/lib/SPELL_WS/src/SPELLwsDynamicData.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the dynamic runtime data manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -59,13 +59,13 @@ SPELLwsDynamicData::SPELLwsDynamicData( const SPELLwsStartupInfo& info, unsigned : m_startup(info), m_frame(frame) { - DEBUG("[DYN] Created dynamic data manager for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Created dynamic data manager for frame " + PYCREPR(m_frame)); assert(m_frame != NULL); if (info.persistentFile != "") { m_persistentFile = info.persistentFile + "_" + ISTR(depth) + ".wsd"; - DEBUG("DYN Using persistent file: '" + m_persistentFile + "'"); + //DEBUG("DYN Using persistent file: '" + m_persistentFile + "'"); } else { @@ -75,15 +75,15 @@ SPELLwsDynamicData::SPELLwsDynamicData( const SPELLwsStartupInfo& info, unsigned if (info.recoveryFile != "") { m_recoveryFile = info.recoveryFile + "_" + ISTR(depth) + ".wsd"; - DEBUG("DYN Using recovery file: '" + m_recoveryFile + "'"); + //DEBUG("DYN Using recovery file: '" + m_recoveryFile + "'"); } else { m_recoveryFile = ""; } - DEBUG("DYN working mode: " + WorkingModeToString(m_startup.workingMode)); - DEBUG("DYN perform recovery: " + BSTR(m_startup.performRecovery)); + //DEBUG("DYN working mode: " + WorkingModeToString(m_startup.workingMode)); + //DEBUG("DYN perform recovery: " + BSTR(m_startup.performRecovery)); // If we are in recovery mode if (m_startup.performRecovery && m_recoveryFile != "") @@ -102,7 +102,7 @@ SPELLwsDynamicData::SPELLwsDynamicData( const SPELLwsStartupInfo& info, unsigned //============================================================================= SPELLwsDynamicData::~SPELLwsDynamicData() { - DEBUG("[DYN] Destroyed dynamic data manager for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Destroyed dynamic data manager for frame " + PYCREPR(m_frame)); } //============================================================================= @@ -110,7 +110,7 @@ SPELLwsDynamicData::~SPELLwsDynamicData() //============================================================================= void SPELLwsDynamicData::reset() { - DEBUG("[DYN] Reset dynamic data for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Reset dynamic data for frame " + PYCREPR(m_frame)); m_storage->reset(); m_iBlocks.clear(); // IMPORTANT do not DECREF objects in ValueStack or FastLocals, since they @@ -124,7 +124,7 @@ void SPELLwsDynamicData::reset() //============================================================================= void SPELLwsDynamicData::cleanup() { - DEBUG("[DYN] Remove dynamic data file for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Remove dynamic data file for frame " + PYCREPR(m_frame)); if (m_persistentFile != "") { SPELLutils::deleteFile( m_persistentFile ); @@ -136,7 +136,7 @@ void SPELLwsDynamicData::cleanup() //============================================================================= void SPELLwsDynamicData::update() { - DEBUG("[DYN] Update dynamic data for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Update dynamic data for frame " + PYCREPR(m_frame)); // We need to keep a copy of these these data structures, since the Python interpreter code // unwinds the stack and the try-blocks in case of exceptions. updateTryBlocks(); @@ -149,7 +149,7 @@ void SPELLwsDynamicData::update() //============================================================================= void SPELLwsDynamicData::recover() { - DEBUG("[DYN] Recover dynamic data for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Recover dynamic data for frame " + PYCREPR(m_frame)); // We need to re-create these data structures, since the Python interpreter code // unwinds the stack and the try-blocks in case of exceptions. recoverTryBlocks(); @@ -162,13 +162,13 @@ void SPELLwsDynamicData::recover() //============================================================================= void SPELLwsDynamicData::save() { - DEBUG("[DYN] Save dynamic data for frame " + PYCREPR(m_frame)); - DEBUG("[DYN] Pre-check errors..."); + //DEBUG("[DYN] Save dynamic data for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Pre-check errors..."); SPELLpythonHelper::instance().checkError(); // Empty the file. We only want the latest change // NOTE: this can be removed in case we want the full history of // changes, although some mods would need to be done to the load code - DEBUG("[DYN] Resetting storage first"); + //DEBUG("[DYN] Resetting storage first"); m_storage->reset(); // Store current data storeParameters(); @@ -186,7 +186,7 @@ void SPELLwsDynamicData::save() storeDTA("ARGS"); SPELLpythonHelper::instance().checkError(); storeDTA("IVARS"); - DEBUG("[DYN] Save dynamic data for frame " + PYCREPR(m_frame) + " done"); + //DEBUG("[DYN] Save dynamic data for frame " + PYCREPR(m_frame) + " done"); } //============================================================================= @@ -199,7 +199,7 @@ void SPELLwsDynamicData::restore() THROW_EXCEPTION("Failed to restore dynamic data", "Storage not ready", SPELL_ERROR_WSTART); } - DEBUG("[DYN] Restore dynamic data for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Restore dynamic data for frame " + PYCREPR(m_frame)); loadParameters(); loadTryBlocks(); loadValueStack(); @@ -211,13 +211,13 @@ void SPELLwsDynamicData::restore() recover(); - DEBUG("[DYN] Restore dynamic data for frame " + PYCREPR(m_frame) + " done"); + //DEBUG("[DYN] Restore dynamic data for frame " + PYCREPR(m_frame) + " done"); if (m_persistentFile != "") { // Reset the storage to mode write, using now the assigned persistent file, // not the recovery file - DEBUG("[DYN] Switching to saving state mode"); + //DEBUG("[DYN] Switching to saving state mode"); delete m_storage; m_storage = new SPELLwsStorage( m_persistentFile, SPELLwsStorage::MODE_WRITE ); // Re-save the state, so that the persistent file contains the current state @@ -235,14 +235,14 @@ void SPELLwsDynamicData::updateTryBlocks() unsigned int numTryBlocks = m_frame->f_iblock; if (numTryBlocks>0) { - DEBUG("[DYN] Updating try blocks on frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Updating try blocks on frame " + PYCREPR(m_frame)); // If there is a different number of blocks than before, update. We assume they dont change once created... if ( numTryBlocks > m_iBlocks.size()) { PyTryBlock block = m_frame->f_blockstack[m_frame->f_iblock-1]; m_iBlocks.push_back(block); - DEBUG("[DYN] add block: [" + ISTR(block.b_type) + "," + ISTR(block.b_handler) + "," + ISTR(block.b_level) + "]"); + //DEBUG("[DYN] add block: [" + ISTR(block.b_type) + "," + ISTR(block.b_handler) + "," + ISTR(block.b_level) + "]"); } // Less blocks... else if ((unsigned int) m_frame->f_iblock < m_iBlocks.size()) @@ -250,9 +250,9 @@ void SPELLwsDynamicData::updateTryBlocks() // Just throw it away TryBlocks::iterator it = m_iBlocks.end(); it--; m_iBlocks.erase(it); - DEBUG("[DYN] remove block"); + //DEBUG("[DYN] remove block"); } - DEBUG("[DYN] Updating try blocks done"); + //DEBUG("[DYN] Updating try blocks done"); } // Take into account the case of going out loops and try blocks ( the frame // does not have blocks defined, so we must clear ours ) @@ -272,18 +272,18 @@ void SPELLwsDynamicData::recoverTryBlocks() // If there were blocks defined... if (m_iBlocks.size()>0) { - DEBUG("[DYN] Restoring try blocks on frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Restoring try blocks on frame " + PYCREPR(m_frame)); TryBlocks::iterator it; unsigned int count = 0; for( it = m_iBlocks.begin(); it != m_iBlocks.end(); it++) { PyTryBlock& block = (*it); - DEBUG("[DYN] block " + ISTR(count) + ": [" + ISTR(block.b_type) + "," + ISTR(block.b_handler) + "," + ISTR(block.b_level) + "]"); + //DEBUG("[DYN] block " + ISTR(count) + ": [" + ISTR(block.b_type) + "," + ISTR(block.b_handler) + "," + ISTR(block.b_level) + "]"); PyFrame_BlockSetup( m_frame, block.b_type, block.b_handler, block.b_level ); count++; } m_frame->f_iblock = m_iBlocks.size(); - DEBUG("[DYN] Restoring try blocks done"); + //DEBUG("[DYN] Restoring try blocks done"); } } @@ -292,7 +292,7 @@ void SPELLwsDynamicData::recoverTryBlocks() //============================================================================= void SPELLwsDynamicData::storeTryBlocks() { - DEBUG("[DYN] Storing try blocks (" + ISTR(m_iBlocks.size()) + ")" ); + //DEBUG("[DYN] Storing try blocks (" + ISTR(m_iBlocks.size()) + ")" ); // Store tryblocks first. Size of the list: m_storage->storeLong( m_iBlocks.size() ); // Store the blocks now, if any @@ -302,7 +302,7 @@ void SPELLwsDynamicData::storeTryBlocks() m_storage->storeLong( (*bit).b_type ); m_storage->storeLong( (*bit).b_handler ); m_storage->storeLong( (*bit).b_level ); - DEBUG(" - [" + ISTR((*bit).b_type) + "," + ISTR((*bit).b_handler) + "," + ISTR((*bit).b_level) + "]"); + //DEBUG(" - [" + ISTR((*bit).b_type) + "," + ISTR((*bit).b_handler) + "," + ISTR((*bit).b_level) + "]"); } } @@ -312,14 +312,14 @@ void SPELLwsDynamicData::storeTryBlocks() void SPELLwsDynamicData::loadTryBlocks() { int numBlocks = m_storage->loadLong(); - DEBUG("[DYN] Loading try blocks (" + ISTR(numBlocks) + ")" ); + //DEBUG("[DYN] Loading try blocks (" + ISTR(numBlocks) + ")" ); for( int count=0; countb_type = m_storage->loadLong(); block->b_handler = m_storage->loadLong(); block->b_level = m_storage->loadLong(); - DEBUG(" - [" + ISTR(block->b_type) + "," + ISTR(block->b_handler) + "," + ISTR(block->b_level) + "]"); + //DEBUG(" - [" + ISTR(block->b_type) + "," + ISTR(block->b_handler) + "," + ISTR(block->b_level) + "]"); m_iBlocks.push_back(*block); } } @@ -338,17 +338,18 @@ void SPELLwsDynamicData::updateValueStack() // Add a new item to the stack information if ((unsigned int) stackCount > m_valueStack.size()) { - DEBUG("[DYN] Updating value stack on frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Updating value stack on frame " + PYCREPR(m_frame)); PyObject** p; p = m_frame->f_valuestack; - + if (!p || !*p) // Check for Nullpointer on stack + return; PyTypeObject* type = (PyTypeObject*) PyObject_Type(*p); if (STR(type->tp_name)=="listiterator" ) { // Get the iterator characteristics ListIteratorMirror* iterator = (ListIteratorMirror*) (*p); - DEBUG("[DYN] add list iterator: [" + ISTR(iterator->it_index) + "," + PYCREPR(iterator->it_seq) + "]"); + //DEBUG("[DYN] add list iterator: [" + ISTR(iterator->it_index) + "," + PYCREPR(iterator->it_seq) + "]"); // Create a copy PyObject* newIterator = PyObject_GetIter( (PyObject*)iterator->it_seq ); @@ -356,24 +357,24 @@ void SPELLwsDynamicData::updateValueStack() ListIteratorMirror* itm = (ListIteratorMirror*)newIterator; itm->it_index = iterator->it_index; // IMPORTANT this is a borrowed reference - DEBUG("[DYN] stored iterator: [" + ISTR(itm->it_index) + "," + PYCREPR(itm->it_seq) + "]"); + //DEBUG("[DYN] stored iterator: [" + ISTR(itm->it_index) + "," + PYCREPR(itm->it_seq) + "]"); m_valueStack.push_back(newIterator); } else { - DEBUG("[DYN] Adding to valuestack, unprocessed: " + PYREPR(*p)); + //DEBUG("[DYN] Adding to valuestack, unprocessed: " + PYREPR(*p)); // IMPORTANT this is a borrowed reference m_valueStack.push_back(*p); } - DEBUG("[DYN] Updating value stack done"); + //DEBUG("[DYN] Updating value stack done"); } // Less items else if ((unsigned int) stackCount < m_valueStack.size()) { // Throw it away... ObjectList::iterator it = m_valueStack.end(); it--; - DEBUG("[DYN] remove value stack object"); + //DEBUG("[DYN] remove value stack object"); // IMPORTANT do not DECREF objects in ValueStack or FastLocals, since they // are borrowed references managed by Python layer. m_valueStack.erase(it); @@ -386,14 +387,14 @@ void SPELLwsDynamicData::updateValueStack() for( unsigned int index = 0; index < m_valueStack.size(); index++) { if (*p == NULL) break; - DEBUG("[DYN] checking value stack object: " + PYREPR(*p)); + //DEBUG("[DYN] checking value stack object: " + PYREPR(*p)); PyTypeObject* type = (PyTypeObject*) PyObject_Type(*p); if (STR(type->tp_name)=="listiterator" ) { ListIteratorMirror* stackIterator = (ListIteratorMirror*) (*p); ListIteratorMirror* storedIterator = (ListIteratorMirror*) m_valueStack[index]; storedIterator->it_index = stackIterator->it_index; - DEBUG("[DYN] update iterator: [" + ISTR(stackIterator->it_index) + "," + PYCREPR(stackIterator->it_seq) + "]"); + //DEBUG("[DYN] update iterator: [" + ISTR(stackIterator->it_index) + "," + PYCREPR(stackIterator->it_seq) + "]"); } } } @@ -416,19 +417,21 @@ void SPELLwsDynamicData::recoverValueStack() // If there are values to recover if (m_valueStack.size()>0) { - DEBUG("[DYN] Restoring value stack on frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Restoring value stack on frame " + PYCREPR(m_frame)); PyObject** stack_pointer = m_frame->f_valuestack; for( unsigned int count = 0; counttp_name)); + //DEBUG("[DYN] Type is " + STR(type->tp_name)); if (STR(type->tp_name)=="listiterator" ) { ListIteratorMirror* stackIterator = (ListIteratorMirror*) (stackObject); - DEBUG("[DYN] restoring iterator: [" + ISTR(stackIterator->it_index) + "," + PYCREPR(stackIterator->it_seq) + "]"); + //DEBUG("[DYN] restoring iterator: [" + ISTR(stackIterator->it_index) + "," + PYCREPR(stackIterator->it_seq) + "]"); PyObject* newIterator = PyObject_GetIter( (PyObject*)stackIterator->it_seq ); newIterator->ob_refcnt = stackObject->ob_refcnt; *stack_pointer++ = newIterator; @@ -440,7 +443,7 @@ void SPELLwsDynamicData::recoverValueStack() } m_frame->f_stacktop = stack_pointer--; m_frame->f_code->co_stacksize = m_valueStack.size(); - DEBUG("[DYN] Restoring value stack done"); + //DEBUG("[DYN] Restoring value stack done"); } // Otherwise define the top as the same value as the bottom of the stack else @@ -456,7 +459,7 @@ void SPELLwsDynamicData::storeValueStack() { // Store the value stack. Size of the list first: m_storage->storeLong( m_valueStack.size() ); - DEBUG("[DYN] Storing value stack for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Storing value stack for frame " + PYCREPR(m_frame)); ObjectList::iterator it; for( it = m_valueStack.begin(); it != m_valueStack.end(); it++) { @@ -509,7 +512,7 @@ void SPELLwsDynamicData::storeValueStack() void SPELLwsDynamicData::loadValueStack() { long numValues = m_storage->loadLong(); - DEBUG("[DYN] Loading value stack for frame " + PYCREPR(m_frame)); + //DEBUG("[DYN] Loading value stack for frame " + PYCREPR(m_frame)); for( int count = 0; count < numValues; count++) { // Retrieve the marker @@ -551,7 +554,7 @@ void SPELLwsDynamicData::updateFastLocals() { assert(m_frame != NULL); int numLocals = m_frame->f_code->co_nlocals-1; - DEBUG("[DYN] Update fast locals: " + ISTR(numLocals)); + //DEBUG("[DYN] Update fast locals: " + ISTR(numLocals)); if (numLocals<0) numLocals = 0; m_fastLocals.clear(); if ((numLocals>0) && ((unsigned int)numLocals != m_fastLocals.size())) @@ -561,7 +564,7 @@ void SPELLwsDynamicData::updateFastLocals() { if (*lplus) { - DEBUG(" add fast local: " + PYREPR(*lplus)); + //DEBUG(" add fast local: " + PYREPR(*lplus)); // IMPORTANT this is a borrowed reference m_fastLocals.push_back(*lplus); lplus++; @@ -576,13 +579,13 @@ void SPELLwsDynamicData::updateFastLocals() void SPELLwsDynamicData::recoverFastLocals() { assert(m_frame != NULL); - DEBUG("[DYN] Recover fast locals: " + ISTR(m_fastLocals.size())); + //DEBUG("[DYN] Recover fast locals: " + ISTR(m_fastLocals.size())); if (m_fastLocals.size()>0) { for( unsigned int count = 0; countf_localsplus[count] = obj; } m_frame->f_code->co_nlocals = m_fastLocals.size()+1; @@ -594,13 +597,13 @@ void SPELLwsDynamicData::recoverFastLocals() //============================================================================= void SPELLwsDynamicData::storeFastLocals() { - DEBUG("[DYN] Store fast locals: " + ISTR(m_fastLocals.size())); + //DEBUG("[DYN] Store fast locals: " + ISTR(m_fastLocals.size())); // Store the fast locals. Size of list first m_storage->storeLong( m_fastLocals.size() ); ObjectList::iterator it; for( it = m_fastLocals.begin(); it != m_fastLocals.end(); it++) { - DEBUG(" storing fast local " + PYREPR(*it)); + //DEBUG(" storing fast local " + PYREPR(*it)); m_storage->storeObjectOrNone(*it); } } @@ -611,11 +614,11 @@ void SPELLwsDynamicData::storeFastLocals() void SPELLwsDynamicData::loadFastLocals() { long numLocals = m_storage->loadLong(); - DEBUG("[DYN] Load fast locals: " + ISTR(numLocals)); + //DEBUG("[DYN] Load fast locals: " + ISTR(numLocals)); for(int count=0; countloadObject(); - DEBUG(" loaded fast local " + PYREPR(obj)); + //DEBUG(" loaded fast local " + PYREPR(obj)); m_fastLocals.push_back( obj ); } } @@ -625,7 +628,7 @@ void SPELLwsDynamicData::loadFastLocals() //============================================================================= void SPELLwsDynamicData::storeGlobals() { - DEBUG("[DYN] Storing globals"); + //DEBUG("[DYN] Storing globals"); assert( m_frame->f_globals != NULL ); storeDictionary( m_frame->f_globals ); storeConstReferences( m_frame->f_globals ); @@ -676,7 +679,7 @@ void SPELLwsDynamicData::loadGlobals() //============================================================================= void SPELLwsDynamicData::storeLocals() { - DEBUG("[DYN] Storing locals"); + //DEBUG("[DYN] Storing locals"); // IMPORTANT: do not remove this PyFrame calls. Inside functions, local variables MAY be defined in the // fast locals, depending on their contents. These calls are needed so that the storeDictionary() call // is able to store those local variables which were not moved to fast locals. Fast locals and locals @@ -697,7 +700,7 @@ void SPELLwsDynamicData::loadLocals() if (restored != NULL) { - DEBUG("[DYN] Restored locals dictionary"); + //DEBUG("[DYN] Restored locals dictionary"); // IMPORTANT: do not remove this PyFrame calls. Inside functions, local variables MAY be defined in the // fast locals, depending on their contents. These calls are needed so that the storeDictionary() call // is able to store those local variables which were not moved to fast locals. Fast locals and locals @@ -723,7 +726,7 @@ void SPELLwsDynamicData::loadLocals() //============================================================================= void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary ) { - DEBUG("[DYN] Store const references"); + //DEBUG("[DYN] Store const references"); if (dictionary == NULL) { m_storage->storeLong( 0 ); @@ -731,7 +734,7 @@ void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary ) } // Store possibly loaded functions which are ignored by the dictionary // handler, if they are part of the code definition - DEBUG("[DYN] Counting const references"); + //DEBUG("[DYN] Counting const references"); // Store first the amount of code references unsigned int numReferences = 0; int numConsts = 0; @@ -739,7 +742,7 @@ void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary ) if (co_consts != NULL) { numConsts = PyTuple_Size(co_consts); - DEBUG("[DYN] Defined " + ISTR(numConsts) + " constants in code"); + //DEBUG("[DYN] Defined " + ISTR(numConsts) + " constants in code"); for( int index = 0; index < numConsts; index++ ) { PyObject* item = PyTuple_GetItem(co_consts,index); @@ -756,7 +759,7 @@ void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary ) } } - DEBUG("[DYN] Number of code references: " + ISTR(numReferences)); + //DEBUG("[DYN] Number of code references: " + ISTR(numReferences)); m_storage->storeLong( numReferences ); if (numReferences>0) @@ -771,7 +774,7 @@ void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary ) // And the code object has been loaded in the globals dictionary if (PyDict_Contains( dictionary, code->co_name )) { - DEBUG("[DYN] Storing code reference: " + PYSTR(code->co_name)); + //DEBUG("[DYN] Storing code reference: " + PYSTR(code->co_name)); m_storage->storeObject( code->co_name ); } } @@ -789,7 +792,7 @@ void SPELLwsDynamicData::loadConstReferences( PyObject* dictionary ) if (numReferences > 0) { - DEBUG("[DYN] " + ISTR(numReferences) + " global references to load"); + //DEBUG("[DYN] " + ISTR(numReferences) + " global references to load"); for(unsigned int count = 0; count < numReferences; count++ ) { PyObject* codeName = m_storage->loadObject(); @@ -804,7 +807,7 @@ void SPELLwsDynamicData::loadConstReferences( PyObject* dictionary ) PyCodeObject* code = (PyCodeObject*) item; if (PYSTR(code->co_name) == PYSTR(codeName)) { - DEBUG("[DYN] Loading reference to " + PYREPR(codeName)); + //DEBUG("[DYN] Loading reference to " + PYREPR(codeName)); PyDict_SetItem( dictionary, code->co_name, PyFunction_New( (PyObject*) code, m_frame->f_globals) ); } } @@ -813,7 +816,7 @@ void SPELLwsDynamicData::loadConstReferences( PyObject* dictionary ) } else { - DEBUG("[DYN] No global references to load"); + //DEBUG("[DYN] No global references to load"); } } @@ -822,13 +825,13 @@ void SPELLwsDynamicData::loadConstReferences( PyObject* dictionary ) //============================================================================= void SPELLwsDynamicData::storeParameters() { - DEBUG("[DYN] Storing frame parameters"); + //DEBUG("[DYN] Storing frame parameters"); m_storage->storeLong(m_frame->f_lineno); - DEBUG(" - Lineno : " + ISTR(m_frame->f_lineno)); + //DEBUG(" - Lineno : " + ISTR(m_frame->f_lineno)); m_storage->storeLong(m_frame->f_lasti); - DEBUG(" - Instruction: " + ISTR(m_frame->f_lasti)); + //DEBUG(" - Instruction: " + ISTR(m_frame->f_lasti)); m_storage->storeLong(m_frame->f_iblock); - DEBUG(" - IBlocks : " + ISTR(m_frame->f_iblock)); + //DEBUG(" - IBlocks : " + ISTR(m_frame->f_iblock)); } //============================================================================= @@ -836,9 +839,9 @@ void SPELLwsDynamicData::storeParameters() //============================================================================= void SPELLwsDynamicData::loadParameters() { - DEBUG("[DYN] Loading frame parameters"); + //DEBUG("[DYN] Loading frame parameters"); m_frame->f_lineno = m_storage->loadLong(); - DEBUG(" - Lineno : " + ISTR(m_frame->f_lineno)); + //DEBUG(" - Lineno : " + ISTR(m_frame->f_lineno)); m_frame->f_lasti = m_storage->loadLong(); // The last instruction pointer needs to be adjusted. Same as for fixState() algorithm @@ -849,29 +852,29 @@ void SPELLwsDynamicData::loadParameters() THROW_EXCEPTION("Unable to restore frame dynamic data", "Cannot restore frame parameters", SPELL_ERROR_WSTART); } - DEBUG("[DYN] Adjusting offset"); + //DEBUG("[DYN] Adjusting offset"); int offsetForLine = lnotab.offset(m_frame->f_lineno); // If the current offset matches the first offset corresponding to the restored // line in the lnotab, we are in the main proc and NO function call. We need // to decrease the last instruction offset by 1 (see PyEval_EvalFrameEx) if (offsetForLine == m_frame->f_lasti) { - DEBUG("[DYN] Corresponds to normal statement"); + //DEBUG("[DYN] Corresponds to normal statement"); m_frame->f_lasti = offsetForLine-1; } // Otherwise, we need to increase the offset by 2 (+3,-1) in order to position // the interpreter right after the CALL_FUNCTION opcode, in the POP_TOP opcode else { - DEBUG("[DYN] Corresponds to function call"); + //DEBUG("[DYN] Corresponds to function call"); int nextLine = lnotab.lineAfter(m_frame->f_lineno); - DEBUG("[DYN] Next line is " + ISTR(nextLine)); + //DEBUG("[DYN] Next line is " + ISTR(nextLine)); int nextInstruction = lnotab.offset(nextLine); m_frame->f_lasti = nextInstruction -1; // Will position it in the lastLine but POP_TOP instr. } - DEBUG(" - Instruction: " + ISTR(m_frame->f_lasti)); + //DEBUG(" - Instruction: " + ISTR(m_frame->f_lasti)); m_frame->f_iblock = m_storage->loadLong(); - DEBUG(" - IBlocks : " + ISTR(m_frame->f_iblock)); + //DEBUG(" - IBlocks : " + ISTR(m_frame->f_iblock)); } //============================================================================= @@ -900,7 +903,7 @@ PyObject* SPELLwsDynamicData::loadDictionary() //============================================================================= void SPELLwsDynamicData::storeDTA( const std::string& container ) { - DEBUG("[DYN] Store DTA container: " + container); + //DEBUG("[DYN] Store DTA container: " + container); PyObject* pyObj = PyDict_GetItemString(SPELLpythonHelper::instance().getMainDict(), container.c_str() ); @@ -917,7 +920,7 @@ void SPELLwsDynamicData::storeDTA( const std::string& container ) m_storage->storeLong(numKeys); - DEBUG("[DYN] " + ISTR(numKeys) + " items"); + //DEBUG("[DYN] " + ISTR(numKeys) + " items"); for(unsigned int index=0; index < numKeys; index++) { @@ -931,13 +934,13 @@ void SPELLwsDynamicData::storeDTA( const std::string& container ) std::string format = var->getFormat(); std::string type = var->getType(); - DEBUG(" - key: " + var->getName()); + //DEBUG(" - key: " + var->getName()); // 0. Key m_storage->storeObject( SSTRPY(var->getName()) ); // 1. Value - DEBUG(" - value: " + PYREPR(value)); + //DEBUG(" - value: " + PYREPR(value)); SPELLwsDataHandler* handler = SPELLwsDataHandlerFactory::createDataHandler(value); handler->setStorage(m_storage); m_storage->storeLong(handler->getCode()); @@ -946,22 +949,22 @@ void SPELLwsDynamicData::storeDTA( const std::string& container ) // 2. Format, Type and Confirm if (format.empty()) { - DEBUG(" - no format given"); + //DEBUG(" - no format given"); m_storage->storeObject( Py_None ); } else { - DEBUG(" - format: " + format); + //DEBUG(" - format: " + format); m_storage->storeObject( SSTRPY(format) ); } if (type.empty()) { - DEBUG(" - no type given"); + //DEBUG(" - no type given"); m_storage->storeObject( Py_None ); } else { - DEBUG(" - type: " + type); + //DEBUG(" - type: " + type); m_storage->storeObject( SSTRPY(type) ); } m_storage->storeObject( confirmGet ? Py_True : Py_False ); @@ -983,7 +986,7 @@ void SPELLwsDynamicData::storeDTA( const std::string& container ) } } - DEBUG("[DYN] Data container stored"); + //DEBUG("[DYN] Data container stored"); } //============================================================================= @@ -991,7 +994,7 @@ void SPELLwsDynamicData::storeDTA( const std::string& container ) //============================================================================= void SPELLwsDynamicData::loadDTA( const std::string& container ) { - DEBUG("[DYN] Loading data container: " + container); + //DEBUG("[DYN] Loading data container: " + container); PyObject* pyObj = PyDict_GetItemString(SPELLpythonHelper::instance().getMainDict(), container.c_str() ); @@ -1006,14 +1009,14 @@ void SPELLwsDynamicData::loadDTA( const std::string& container ) unsigned int numKeys = m_storage->loadLong(); - DEBUG("[DYN] Items to load: " + ISTR(numKeys)); + //DEBUG("[DYN] Items to load: " + ISTR(numKeys)); for(unsigned int index=0; index < numKeys; index++) { // 0. Key PyObject* pyName = m_storage->loadObject(); - DEBUG(" - key: " + PYREPR(pyName)); + //DEBUG(" - key: " + PYREPR(pyName)); // 1. Value SPELLwsData::Code code = (SPELLwsData::Code) m_storage->loadLong(); @@ -1023,13 +1026,13 @@ void SPELLwsDynamicData::loadDTA( const std::string& container ) PyObject* value = handler->getObject(); - DEBUG(" - value: " + PYREPR(value)); + //DEBUG(" - value: " + PYREPR(value)); // 2. Format, Type and Confirm PyObject* pyFormat = m_storage->loadObject(); - DEBUG(" - format: " + PYREPR(pyFormat)); + //DEBUG(" - format: " + PYREPR(pyFormat)); PyObject* pyType = m_storage->loadObject(); - DEBUG(" - type: " + PYREPR(pyType)); + //DEBUG(" - type: " + PYREPR(pyType)); PyObject* pyConfirm = m_storage->loadObject(); // 3. Expected @@ -1055,7 +1058,7 @@ void SPELLwsDynamicData::loadDTA( const std::string& container ) } // Create the variable - PyObject* varClass = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "Var"); + PyObject* varClass = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "Var"); Py_INCREF(varClass); assert(varClass != NULL); PyObject* dict = PyDict_New(); @@ -1090,6 +1093,6 @@ void SPELLwsDynamicData::loadDTA( const std::string& container ) args->setValue(pyName,instance); } - DEBUG("[DYN] Data container loaded"); + //DEBUG("[DYN] Data container loaded"); } diff --git a/lib/SPELL_WS/src/SPELLwsFrame.C b/lib/SPELL_WS/src/SPELLwsFrame.C index bf535d0..21948aa 100644 --- a/lib/SPELL_WS/src/SPELLwsFrame.C +++ b/lib/SPELL_WS/src/SPELLwsFrame.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the frame data manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -139,16 +139,19 @@ void SPELLwsFrame::fixState( PyThreadState* newState, bool isHead ) // Reset the frame values m_frame->f_lasti = m_lastInstruction; m_frame->f_lineno = m_lastLine; +#if PY_MAJOR_VERSION < 3 m_frame->f_tstate = newState; +#endif m_frame->f_stacktop = m_frame->f_valuestack; // Reset exception trace +#if PY_MAJOR_VERSION < 3 Py_XDECREF(m_frame->f_exc_traceback); Py_XDECREF(m_frame->f_exc_type); Py_XDECREF(m_frame->f_exc_value); m_frame->f_exc_traceback = NULL; m_frame->f_exc_type = NULL; m_frame->f_exc_value = NULL; - +#endif // Recover the dynamic data and update the frame DEBUG("[FRM] Recovering dynamic data"); m_dynamic->recover(); diff --git a/lib/SPELL_WS/src/SPELLwsInstanceDataHandler.C b/lib/SPELL_WS/src/SPELLwsInstanceDataHandler.C index f2c3087..e7d92f0 100644 --- a/lib/SPELL_WS/src/SPELLwsInstanceDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsInstanceDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for instances // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsListDataHandler.C b/lib/SPELL_WS/src/SPELLwsListDataHandler.C index ac0ea9c..35cb0b5 100644 --- a/lib/SPELL_WS/src/SPELLwsListDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsListDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for lists // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsObjectDataHandler.C b/lib/SPELL_WS/src/SPELLwsObjectDataHandler.C index 6a9c6ce..a9bc45c 100644 --- a/lib/SPELL_WS/src/SPELLwsObjectDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsObjectDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for objects // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsStaticData.C b/lib/SPELL_WS/src/SPELLwsStaticData.C index f7cbe77..f4841b4 100644 --- a/lib/SPELL_WS/src/SPELLwsStaticData.C +++ b/lib/SPELL_WS/src/SPELLwsStaticData.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the static data manager // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsStorage.C b/lib/SPELL_WS/src/SPELLwsStorage.C index 75b8f08..55ce1bb 100644 --- a/lib/SPELL_WS/src/SPELLwsStorage.C +++ b/lib/SPELL_WS/src/SPELLwsStorage.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the storage model // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -148,7 +148,7 @@ void SPELLwsStorage::storeObject( PyObject* object ) SPELLpythonHelper::instance().checkError(); int marshal_len = PyObject_Length(marshal); DEBUG("Marshal length: " + ISTR(marshal_len)); - char* encoded = PyString_AsString(marshal); + const char* encoded = PyString_AsString(marshal); // FORMAT IN FILE: // COUNT \1 PTYPE \1 MARSHAL LENGTH diff --git a/lib/SPELL_WS/src/SPELLwsTimeDataHandler.C b/lib/SPELL_WS/src/SPELLwsTimeDataHandler.C index a1dafda..220c3c6 100644 --- a/lib/SPELL_WS/src/SPELLwsTimeDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsTimeDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for SPELL TIME // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsTmItemDataHandler.C b/lib/SPELL_WS/src/SPELLwsTmItemDataHandler.C index 4c8a9ca..9735f2e 100644 --- a/lib/SPELL_WS/src/SPELLwsTmItemDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsTmItemDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for tm items // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsTupleDataHandler.C b/lib/SPELL_WS/src/SPELLwsTupleDataHandler.C index 4ebbaa6..9ad43b6 100644 --- a/lib/SPELL_WS/src/SPELLwsTupleDataHandler.C +++ b/lib/SPELL_WS/src/SPELLwsTupleDataHandler.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the data handler for lists // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/lib/SPELL_WS/src/SPELLwsWarmStartImpl.C b/lib/SPELL_WS/src/SPELLwsWarmStartImpl.C index b8b617a..a89e819 100644 --- a/lib/SPELL_WS/src/SPELLwsWarmStartImpl.C +++ b/lib/SPELL_WS/src/SPELLwsWarmStartImpl.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the warm start mechanism controller // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -175,6 +175,7 @@ void SPELLwsWarmStartImpl::saveState() SPELLsafePythonOperations ops("SPELLwsWarmstartImpl::saveState()"); //TODO check, possibly there are several states that need to be saved +#if PY_MAJOR_VERSION < 3 PyThreadState* state = m_topFrame->getFrameObject()->f_tstate; DEBUG("Current thread state: " + PSTR(state)); @@ -188,6 +189,7 @@ void SPELLwsWarmStartImpl::saveState() m_storage->storeLong( state->tick_counter ); DEBUG(" - GIL counter : " + ISTR(state->gilstate_counter)); m_storage->storeLong( state->gilstate_counter ); +#endif DEBUG(" - Number of frames: " + ISTR(m_frames.size())); m_storage->storeLong( m_frames.size() ); @@ -233,8 +235,10 @@ PyFrameObject* SPELLwsWarmStartImpl::restoreState() tstate->recursion_depth = m_storage->loadLong(); DEBUG(" - Recursion depth : " + ISTR(tstate->recursion_depth)); +#if PY_MAJOR_VERSION < 3 tstate->tick_counter = m_storage->loadLong(); DEBUG(" - Tcik counter : " + ISTR(tstate->tick_counter)); +#endif tstate->gilstate_counter = m_storage->loadLong(); DEBUG(" - GIL counter : " + ISTR(tstate->gilstate_counter)); int numFrames = m_storage->loadLong(); @@ -338,7 +342,9 @@ PyFrameObject* SPELLwsWarmStartImpl::fixState() newState->recursion_depth = oldState->recursion_depth; newState->tracing = oldState->tracing; newState->use_tracing = oldState->use_tracing; +#if PY_MAJOR_VERSION < 3 newState->tick_counter = oldState->tick_counter; +#endif newState->gilstate_counter = oldState->gilstate_counter; newState->dict = PyDict_Copy(oldState->dict); @@ -349,7 +355,7 @@ PyFrameObject* SPELLwsWarmStartImpl::fixState() for( unsigned int index = 0; index < frameCount; index++) { bool isHead = (index == (frameCount-1)); - DEBUG("[WS] Fix state on frame index " + ISTR(index) + " frame=" + PYCREPR(m_frames[index])); + DEBUG("[WS] Fix state on frame index " + ISTR(index) + " frame=" + PYCREPR(m_frames[index]->getFrameObject())); m_topFrame = m_frames[index]; m_topFrame->fixState(newState, isHead); } diff --git a/lib/SPELL_WS/src/SPELLwsWorkingMode.C b/lib/SPELL_WS/src/SPELLwsWorkingMode.C index 2abc876..004d1ae 100644 --- a/lib/SPELL_WS/src/SPELLwsWorkingMode.C +++ b/lib/SPELL_WS/src/SPELLwsWorkingMode.C @@ -5,7 +5,7 @@ // DESCRIPTION: Implementation of the warmstart working mode // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 0000000..94e6f26 --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1,5 @@ +/libtool.m4 +/ltoptions.m4 +/ltsugar.m4 +/ltversion.m4 +/lt~obsolete.m4 diff --git a/m4/ax_compare_version.m4 b/m4/ax_compare_version.m4 new file mode 100644 index 0000000..9c8e208 --- /dev/null +++ b/m4/ax_compare_version.m4 @@ -0,0 +1,177 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# +# DESCRIPTION +# +# This macro compares two version strings. Due to the various number of +# minor-version numbers that can exist, and the fact that string +# comparisons are not compatible with numeric comparisons, this is not +# necessarily trivial to do in a autoconf script. This macro makes doing +# these comparisons easy. +# +# The six basic comparisons are available, as well as checking equality +# limited to a certain number of minor-version levels. +# +# The operator OP determines what type of comparison to do, and can be one +# of: +# +# eq - equal (test A == B) +# ne - not equal (test A != B) +# le - less than or equal (test A <= B) +# ge - greater than or equal (test A >= B) +# lt - less than (test A < B) +# gt - greater than (test A > B) +# +# Additionally, the eq and ne operator can have a number after it to limit +# the test to that number of minor versions. +# +# eq0 - equal up to the length of the shorter version +# ne0 - not equal up to the length of the shorter version +# eqN - equal up to N sub-version levels +# neN - not equal up to N sub-version levels +# +# When the condition is true, shell commands ACTION-IF-TRUE are run, +# otherwise shell commands ACTION-IF-FALSE are run. The environment +# variable 'ax_compare_version' is always set to either 'true' or 'false' +# as well. +# +# Examples: +# +# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[lt],[3.15.8]) +# +# would both be true. +# +# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[gt],[3.15.8]) +# +# would both be false. +# +# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8]) +# +# would be true because it is only comparing two minor versions. +# +# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15]) +# +# would be true because it is only comparing the lesser number of minor +# versions of the two values. +# +# Note: The characters that separate the version numbers do not matter. An +# empty string is the same as version 0. OP is evaluated by autoconf, not +# configure, so must be a string, not a variable. +# +# The author would like to acknowledge Guido Draheim whose advice about +# the m4_case and m4_ifvaln functions make this macro only include the +# portions necessary to perform the specific comparison specified by the +# OP argument in the final configure script. +# +# LICENSE +# +# Copyright (c) 2008 Tim Toolan +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 12 + +dnl ######################################################################### +AC_DEFUN([AX_COMPARE_VERSION], [ + AC_REQUIRE([AC_PROG_AWK]) + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + AS_VAR_PUSHDEF([A],[ax_compare_version_A]) + A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + AS_VAR_PUSHDEF([B],[ax_compare_version_B]) + B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary + dnl # then the first line is used to determine if the condition is true. + dnl # The sed right after the echo is to remove any indented white space. + m4_case(m4_tolower($2), + [lt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [gt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [le],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ], + [ge],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ],[ + dnl Split the operator from the subversion count if present. + m4_bmatch(m4_substr($2,2), + [0],[ + # A count of zero means use the length of the shorter version. + # Determine the number of characters in A and B. + ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'` + ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'` + + # Set A to no more than B's length and B to no more than A's length. + A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` + B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` + ], + [[0-9]+],[ + # A count greater than zero means use only that many subversions + A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + ], + [.+],[ + AC_WARNING( + [illegal OP numeric parameter: $2]) + ],[]) + + # Pad zeros at end of numbers to make same length. + ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" + B="$B`echo $A | sed 's/./0/g'`" + A="$ax_compare_version_tmp_A" + + # Check for equality or inequality as necessary. + m4_case(m4_tolower(m4_substr($2,0,2)), + [eq],[ + test "x$A" = "x$B" && ax_compare_version=true + ], + [ne],[ + test "x$A" != "x$B" && ax_compare_version=true + ],[ + AC_WARNING([illegal OP parameter: $2]) + ]) + ]) + + AS_VAR_POPDEF([A])dnl + AS_VAR_POPDEF([B])dnl + + dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. + if test "$ax_compare_version" = "true" ; then + m4_ifvaln([$4],[$4],[:])dnl + m4_ifvaln([$5],[else $5])dnl + fi +]) dnl AX_COMPARE_VERSION diff --git a/m4/ax_python_devel.m4 b/m4/ax_python_devel.m4 index 92054e6..c6bf445 100644 --- a/m4/ax_python_devel.m4 +++ b/m4/ax_python_devel.m4 @@ -23,7 +23,7 @@ # version number. Don't use "PYTHON_VERSION" for this: that environment # variable is declared as precious and thus reserved for the end-user. # -# This macro should work for all versions of Python >= 2.1.0. As an end +# This macro should work fior all versions of Python >= 2.1.0. As an end # user, you can disable the check for the python version by setting the # PYTHON_NOVERSIONCHECK environment variable to something else than the # empty string. @@ -68,31 +68,31 @@ #serial 3 -AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL]) -AC_DEFUN([AX_PYTHON_DEVEL],[ +AU_ALIAS([AC_PYTHON_DEVEL_V2], [AX_PYTHON_DEVEL_V2]) +AC_DEFUN([AX_PYTHON_DEVEL_V2],[ # # Allow the use of a (user set) custom python version # - AC_ARG_VAR([PYTHON_VERSION],[The installed Python + AC_ARG_VAR([PYTHON2_VERSION],[The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name.]) - AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) - if test -z "$PYTHON"; then - AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path]) - PYTHON_VERSION="" + AC_PATH_PROG([PYTHON2],[python[$PYTHON2_VERSION]]) + if test -z "$PYTHON2"; then + AC_MSG_ERROR([Cannot find python$PYTHON2_VERSION in your system path]) + PYTHON2_VERSION="" fi # # Check for a version of Python >= 2.5.0 # AC_MSG_CHECKING([for a version of Python >= '2.5.0']) - ac_supports_python_ver=`$PYTHON -c "import sys; \ + ac_supports_python_ver=`$PYTHON2 -c "import sys; \ ver = sys.version.split ()[[0]]; \ print (ver >= '2.5.0')"` if test "$ac_supports_python_ver" != "True"; then - if test -z "$PYTHON_NOVERSIONCHECK"; then + if test -z "$PYTHON2_NOVERSIONCHECK"; then AC_MSG_RESULT([no]) AC_MSG_FAILURE([ This version of the AC@&t@_PYTHON_DEVEL macro @@ -115,9 +115,9 @@ to something else than an empty string. # if test -n "$1"; then AC_MSG_CHECKING([for a version of Python $1]) - ac_supports_python_ver=`$PYTHON -c "import sys; \ - ver = sys.version.split ()[[0]]; \ - print (ver $1)"` + ac_supports_python_ver=`$PYTHON2 -c "import sys; \ + ver = sys.version.split()[[0]]; \ + print (ver >= '$1')"` if test "$ac_supports_python_ver" = "True"; then AC_MSG_RESULT([yes]) else @@ -127,7 +127,7 @@ If you have it installed, but it isn't the default Python interpreter in your system path, please pass the PYTHON_VERSION variable to configure. See ``configure --help'' for reference. ]) - PYTHON_VERSION="" + PYTHON2_VERSION="" fi fi @@ -135,7 +135,7 @@ variable to configure. See ``configure --help'' for reference. # Check if you have distutils, else fail # AC_MSG_CHECKING([for the distutils Python package]) - ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` + ac_distutils_result=`$PYTHON2 -c "import distutils" 2>&1` if test -z "$ac_distutils_result"; then AC_MSG_RESULT([yes]) else @@ -143,32 +143,32 @@ variable to configure. See ``configure --help'' for reference. AC_MSG_ERROR([cannot import Python module "distutils". Please check your Python installation. The error was: $ac_distutils_result]) - PYTHON_VERSION="" + PYTHON2_VERSION="" fi # # Check for Python include path # AC_MSG_CHECKING([for Python include path]) - if test -z "$PYTHON_CPPFLAGS"; then - python_path=`$PYTHON -c "import distutils.sysconfig; \ + if test -z "$PYTHON2_CPPFLAGS"; then + python2_path=`$PYTHON2 -c "import distutils.sysconfig; \ print (distutils.sysconfig.get_python_inc ());"` - if test -n "${python_path}"; then - python_path="-I$python_path" + if test -n "${python2_path}"; then + python2_path="-I$python2_path" fi - PYTHON_CPPFLAGS=$python_path + PYTHON2_CPPFLAGS=$python2_path fi - AC_MSG_RESULT([$PYTHON_CPPFLAGS]) - AC_SUBST([PYTHON_CPPFLAGS]) + AC_MSG_RESULT([$PYTHON2_CPPFLAGS]) + AC_SUBST([PYTHON2_CPPFLAGS]) # # Check for Python library path # AC_MSG_CHECKING([for Python library path]) - if test -z "$PYTHON_LDFLAGS"; then + if test -z "$PYTHON2_LDFLAGS"; then # (makes two attempts to ensure we've got a version number # from the interpreter) - ac_python_version=`cat<]], @@ -316,7 +316,7 @@ EOD` for your distribution. The exact name of this package varies among them. ============================================================================ ]) - PYTHON_VERSION="" + PYTHON2_VERSION="" fi # diff --git a/m4/ax_python_devel_v3.m4 b/m4/ax_python_devel_v3.m4 new file mode 100644 index 0000000..e770632 --- /dev/null +++ b/m4/ax_python_devel_v3.m4 @@ -0,0 +1,325 @@ +# =========================================================================== +# http://www.nongnu.org/autoconf-archive/ax_python_devel.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PYTHON_DEVEL([version]) +# +# DESCRIPTION +# +# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it +# in your configure.ac. +# +# This macro checks for Python and tries to get the include path to +# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) +# output variables. It also exports $(PYTHON_EXTRA_LIBS) and +# $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code. +# +# You can search for some particular version of Python by passing a +# parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please +# note that you *have* to pass also an operator along with the version to +# match, and pay special attention to the single quotes surrounding the +# version number. Don't use "PYTHON_VERSION" for this: that environment +# variable is declared as precious and thus reserved for the end-user. +# +# This macro should work for all versions of Python >= 2.1.0. As an end +# user, you can disable the check for the python version by setting the +# PYTHON_NOVERSIONCHECK environment variable to something else than the +# empty string. +# +# If you need to use this macro for an older Python version, please +# contact the authors. We're always open for feedback. +# +# LICENSE +# +# Copyright (c) 2009 Sebastian Huber +# Copyright (c) 2009 Alan W. Irwin +# Copyright (c) 2009 Rafael Laboissiere +# Copyright (c) 2009 Andrew Collier +# Copyright (c) 2009 Matteo Settenvini +# Copyright (c) 2009 Horst Knorr +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 3 + +AU_ALIAS([AC_PYTHON_DEVEL_V3], [AX_PYTHON_DEVEL_V3]) +AC_DEFUN([AX_PYTHON_DEVEL_V3],[ + # + # Allow the use of a (user set) custom python version + # + AC_ARG_VAR([PYTHON2_VERSION],[The installed Python + version to use, for example '2.3'. This string + will be appended to the Python interpreter + canonical name.]) + + AC_PATH_PROG([PYTHON3],[python[$PYTHON3_VERSION]]) + if test -z "$PYTHON3"; then + AC_MSG_ERROR([Cannot find python$PYTHON3_VERSION in your system path]) + PYTHON3_VERSION="" + fi + + # + # Check for a version of Python >= 2.5.0 + # + AC_MSG_CHECKING([for a version of Python >= '2.5.0']) + ac_supports_python_ver=`$PYTHON3 -c "import sys; \ + ver = sys.version.split ()[[0]]; \ + print (ver >= '2.5.0')"` + if test "$ac_supports_python_ver" != "True"; then + if test -z "$PYTHON3_NOVERSIONCHECK"; then + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([ +This version of the AC@&t@_PYTHON_DEVEL macro +doesn't work properly with versions of Python before +2.1.0. You may need to re-run configure, setting the +variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG, +PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand. +Moreover, to disable this check, set PYTHON_NOVERSIONCHECK +to something else than an empty string. +]) + else + AC_MSG_RESULT([skip at user request]) + fi + else + AC_MSG_RESULT([yes]) + fi + + # + # if the macro parameter ``version'' is set, honour it + # + if test -n "$1"; then + AC_MSG_CHECKING([for a version of Python $1]) + ac_supports_python_ver=`$PYTHON3 -c "import sys; \ + ver = sys.version.split()[[0]]; \ + print (ver >= '$1')"` + if test "$ac_supports_python_ver" = "True"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([this package requires Python $1. +If you have it installed, but it isn't the default Python +interpreter in your system path, please pass the PYTHON_VERSION +variable to configure. See ``configure --help'' for reference. +]) + PYTHON3_VERSION="" + fi + fi + + # + # Check if you have distutils, else fail + # + AC_MSG_CHECKING([for the distutils Python package]) + ac_distutils_result=`$PYTHON3 -c "import distutils" 2>&1` + if test -z "$ac_distutils_result"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([cannot import Python module "distutils". +Please check your Python installation. The error was: +$ac_distutils_result]) + PYTHON3_VERSION="" + fi + + # + # Check for Python include path + # + AC_MSG_CHECKING([for Python include path]) + if test -z "$PYTHON3_CPPFLAGS"; then + python_path=`$PYTHON3 -c "import distutils.sysconfig; \ + print (distutils.sysconfig.get_python_inc ());"` + if test -n "${python_path}"; then + python_path="-I$python_path" + fi + PYTHON3_CPPFLAGS=$python_path + fi + AC_MSG_RESULT([$PYTHON3_CPPFLAGS]) + AC_SUBST([PYTHON3_CPPFLAGS]) + + # + # Check for Python library path + # + AC_MSG_CHECKING([for Python library path]) + if test -z "$PYTHON3_LDFLAGS"; then + # (makes two attempts to ensure we've got a version number + # from the interpreter) + ac_python_version=`cat<]], + [[Py_Initialize();]]) + ],[pythonexists=yes],[pythonexists=no]) + AC_LANG_POP([C]) + # turn back to default flags + CPPFLAGS="$ac_save_CPPFLAGS" + LIBS="$ac_save_LIBS" + + AC_MSG_RESULT([$pythonexists]) + + if test ! "x$pythonexists" = "xyes"; then + AC_MSG_FAILURE([ + Could not link test program to Python. Maybe the main Python library has been + installed in some non-standard library path. If so, pass it to configure, + via the LDFLAGS environment variable. + Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib" + ============================================================================ + ERROR! + You probably have to install the development version of the Python package + for your distribution. The exact name of this package varies among them. + ============================================================================ + ]) + PYTHON3_VERSION="" + fi + + # + # all done! + # +]) diff --git a/proto/IBus.proto b/proto/IBus.proto new file mode 100644 index 0000000..05a16e1 --- /dev/null +++ b/proto/IBus.proto @@ -0,0 +1,61 @@ +syntax = "proto3"; + +package IBus; + +enum MessageType { + MSG_UNDEF = 0; + MSG_INIT = 1; + MSG_ACK = 2; + MSG_EOT = 3; + MSG_STATUS = 4; + MSG_RESUME = 5; + MSG_NAK = 6; +} + +enum StatusType { + STATUS_UNDEF = 0; + STATUS_OK = 1; + STATUS_NOT_FOUND = 2; +} + +enum ClientType { + CLIENT_UNDEF = 0; + CLIENT_DUMB = 1; +} + +message Type { + MessageType msgType = 1; // message type + string id = 2; // client identifier +} + +// Initial message +message InitMsg { + MessageType msgType = 1; // msgType=MSG_INIT + string id = 2; // client identifier + ClientType clientType = 3; // client type + uint64 ts = 4; // start time with historical=True, ts=0 means "everything" + bool live = 5; // goes live after historical (or immediately) + bool historical = 6; // request historical, makes startTime meaningful + bool reset = 7; // start afresh, deleting previous client information if any +} + +// Packet acknowledged message +message AckMsg { + MessageType msgType = 1; // msgType=MSG_ACK + string id = 2; // client identifier + uint64 ts = 3; // represents the acknowledged timestamp +} + +// End-of-transmission message +message EotMsg { + MessageType msgType = 1; // msgType=MSG_EOT + string id = 2; // client identifier +} + +// Status message +message StatusMsg { + MessageType msgType = 1; // msgType=MSG_STATUS + string id = 2; // client identifier + StatusType status = 3; // status +} + diff --git a/proto/OBus.proto b/proto/OBus.proto new file mode 100644 index 0000000..f93e3c6 --- /dev/null +++ b/proto/OBus.proto @@ -0,0 +1,215 @@ +syntax="proto3"; + +package OBus; + +option go_package = ".;service"; +option java_package = "com.ses.grpc.obus"; + +// Not implemented. +service FleetTMControlService { + rpc LoadReferenceLimits (Satellite) returns (Empty){} + rpc SelectOverlay (Overlay) returns (Empty){} + rpc SubmitLimitUpdate (LimitUpdate) returns (Empty){} +} + +// FleetTMService provides (streaming) functions to retrieve telemetry incl. limit information. +service FleetTMService { + // Waits for an update and returns the sample of the requested mnemonic or pid. + // Set requestCurrentValue to True in the request to return the current value instead. + rpc GetTelemetrySample (TelemetrySampleRequest) returns (TelemetrySample){} + // Streams sample updates of the subscribed mnemonics or pids. + // Set requestCurrentValue to True in the request to return the current values at the beginning. + // During runtime, the clients must keep the subscription thread running and update subscriptions as necessary. + rpc GetTelemetrySamples (stream TelemetryStreamRequest) returns (stream TelemetrySamples){} + // Returns the current value table (CVT) of all known samples. + rpc GetTelemetryCvt (TelemetryCvtRequest) returns (TelemetrySamples){} + + // Returns the current value table (CVT) of all known samples with limitVal > INFO. + rpc GetLimitCvt (TelemetryCvtRequest) returns (TelemetrySamples){} + // Streams sample updates where limit information is changing. + rpc GetLimitChanges (LimitStreamRequest) returns (stream TelemetrySamples){} + + // Not implemented. + rpc GetLimitDefinition (TelemetrySampleRequest) returns (LimitDefinition){} + rpc GetLimitDefinitions (stream TelemetryStreamRequest) returns (stream LimitDefinitions){} + + // Returns the status of available TM streams. + // A stream is flagged as stalled after 5 seconds of inactivity. + rpc GetTelemetryStatus(TelemetryStatusRequest) returns (TelemetryStatus){} +} + +enum STATEV { + VALID = 0; + INVALID = 1; + CRC_ERROR = 2; + INVALID_AND_CRC_ERROR = 3; + EXPIRED = 4; + INVALID_AND_EXPIRED = 5; + CRC_ERROR_AND_EXPIRED = 6; + INVALID_AND_CRC_ERROR_AND_EXPIRED = 7; +} + +enum TM_TYPE { + UNKNOWN = 0; + DOUBLE = 1; + LONG = 2; + STRING = 3; + UNSIGNED_LONG = 4; +} + +enum ERROR_CODES { + NONE = 0; + NOT_FOUND = 1; +} + +enum LIMIT { + NORMAL = 0; + INFO = 1; + WARNING = 2; + HAZARDOUS = 3; + CRITICAL = 4; + OOR = 5; +} + +message TelemetrySampleRequest { + string satelliteName = 1; // Mandatory + string seatName = 2; // Leave empty for real S/C + string mnemonic = 3; // Mandatory if pid is not set + bool requestCurrentValue = 4; // Default: False + uint32 pid = 5; // Mandatory if mnemonic is not set +} + +message TelemetryStreamRequest { + string satelliteName = 1; // Mandatory + string seatName = 2; // Leave empty for real S/C + // (subscribeMnemonics /\ unsubscribeMnemonics != {}) => (subscribePids /\ unsubscribePids == {}) + repeated string subscribeMnemonics = 3; + repeated string unsubscribeMnemonics = 4; + bool requestCurrentValue = 5; // Default: False + // (subscribePids /\ unsubscribePids != {}) => (subscribeMnemonics /\ unsubscribeMnemonics == {}) + repeated uint32 subscribePids = 6; + repeated uint32 unsubscribePids = 7; +} + +message TelemetryCvtRequest { + string satelliteName = 1; // Mandatory + string seatName = 2; // Leave empty for real S/C +} + +message LimitStreamRequest { + string satelliteName = 1; // Mandatory + string seatName = 2; // Leave empty for real S/C +} + +message TelemetryStatusRequest { +} + +message TelemetrySamples { + repeated TelemetrySample samples = 1; +} + +message AnalogLimit { + uint32 limitSet = 1; + uint32 hysteresis = 2; + double low = 3; + double high = 4; + LIMIT level = 5; + string conditionName = 6; + string conditionAlgo = 7; + int64 version = 8; +} + +message StatusLimit { + uint32 limitSet = 1; + uint32 hysteresis = 2; + int64 limitVal = 3; + LIMIT level = 4; + string conditionName = 5; + string conditionAlgo = 6; + int64 version = 7; +} + +message LimitDefinition { + repeated string mnemonic = 1; + map entries = 2; +} + +message LimitDefinitions { + repeated LimitDefinition definitions = 1; +} + +message LimitDefinitionEntry { + uint64 limitTS = 1; + string overlayName = 2; + + oneof LimitValues { + AnalogLimit analogLimit = 3; + StatusLimit statusLimit = 4; + } +} + +message TelemetrySample { + repeated string mnemonic = 1; + uint64 onboardTS = 2; + uint64 groundTS = 3; + double engV = 4; + int64 rawV = 5; + string calV = 6; + STATEV stateV = 7; + int32 strmID = 8; + int32 pktID = 9; + ERROR_CODES error = 10; + TM_TYPE tmType = 11; + oneof LimitValues { + AnalogLimit analogLimit = 12; + StatusLimit statusLimit = 13; + } + uint32 pid = 14; +} + +message Empty { +} + +message Overlay { + string satelliteName = 1; + string overlayName = 2; +} + +message Satellite { + string satelliteName = 1; + string seatName = 2; +} + +message LimitUpdate { + message AnalogLimit { + } + message StatusLimit { + } + string satelliteName = 1; + string mnemonic = 2; + repeated AnalogLimit updatedAnalogLimit = 3; + repeated StatusLimit updatedStatusLimit = 4; +} + +message Reply { + enum RETURN_CODE { + SUCCESS = 0; + ERROR = 1; + } + RETURN_CODE errorCode = 1; +} + +message TelemetryStreamInfo { + enum STREAM_STATUS { + NORMAL = 0; + STALLED = 1; // No updates within 5 seconds + } + string satelliteName = 1; + string seatName = 2; + STREAM_STATUS status = 3; + uint64 time = 4; // Last known reception time +} + +message TelemetryStatus { + repeated TelemetryStreamInfo info = 1; +} diff --git a/proto/SpacecraftInfo.proto b/proto/SpacecraftInfo.proto new file mode 100644 index 0000000..1af4727 --- /dev/null +++ b/proto/SpacecraftInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message SpacecraftInfo { + uint32 msgType = 1; + uint32 scID = 2; + uint64 period = 3; // time between two frames at highest speed (nanoseconds) + uint32 totalFrames = 4; // number of minor frames in a major frame +} diff --git a/proto/TelemetryFrame.proto b/proto/TelemetryFrame.proto new file mode 100644 index 0000000..fd365a0 --- /dev/null +++ b/proto/TelemetryFrame.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; + +message TelemetryPacket { + uint32 vcID = 1; + uint32 apID = 2; + uint32 sequenceCounter = 3; + uint32 length = 4; + bool pecfValid = 5; + bool pusHeader = 6; + uint32 pusService = 7; + uint32 pusSubservice = 8; + uint32 destination = 9; + uint32 subCounter = 10; + uint64 onboardTS = 11; + bytes rawPacket = 100; +} + +message TelemetryPoint { + uint32 pID = 1; + uint64 onboardTS = 2; + double engV = 3; + int64 rawV = 4; + string calV = 5; + + enum STATEV { + VALID = 0; + INVALID = 1; + CRC_ERROR = 2; + INVALID_AND_CRC_ERROR = 3; + EXPIRED = 4; + INVALID_AND_EXPIRED = 5; + CRC_ERROR_AND_EXPIRED = 6; + INVALID_AND_CRC_ERROR_AND_EXPIRED = 7; + } + + STATEV stateV = 6; + int32 pktID = 7; +} + +message TelemetryFrame { + uint32 msgType = 1; + uint32 scID = 2; + + enum STREAMID { + STREAM1 = 0; + STREAM2 = 1; + } + + STREAMID streamID = 3; + uint32 frameCounter = 4; + uint64 groundTS = 5; + uint32 familyID = 6; + + repeated bytes rawFrame = 98; + repeated TelemetryPacket packet = 99; + repeated TelemetryPoint point = 100; +} diff --git a/proto/TelemetryFrameLt.proto b/proto/TelemetryFrameLt.proto new file mode 100644 index 0000000..10249be --- /dev/null +++ b/proto/TelemetryFrameLt.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +message TelemetryFrame { + uint32 msgType = 1; + uint32 scID = 2; + + enum STREAMID { + STREAM1 = 0; + STREAM2 = 1; + } + + STREAMID streamID = 3; + uint32 frameCounter = 4; + uint64 groundTS = 5; + uint32 familyID = 6; +} diff --git a/proto/alerts.proto b/proto/alerts.proto new file mode 100644 index 0000000..42d66ac --- /dev/null +++ b/proto/alerts.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +import "header.proto"; + +package Alerts; + +enum SeverityType { + SEV_NORMAL = 0; + SEV_INFO = 1; + SEV_WARNING = 2; + SEV_HAZARDOUS = 3; + SEV_CRITICAL = 4; +}; + +message Alert { + string machineName = 1; // short name (lowercase) of the machine (p1anal01, p1cntl, opsb-ses10tec1, etc.) + uint64 eventTS = 2; // timestamp of the event, represents the number of Nano-seconds since Unix epoch + string appName = 3; // identifier of the application that generated the message + SeverityType severity = 4; // severity of the alert (refer to SeverityType definition) + string label = 5; // sentence to describe the alert, one line (no linefeed) + string eventData = 6; // additional data as per application defined pattern (no free text, strict template to be published) +}; + +message Item { + Messages.Header header = 1; + + oneof these { + Alert alert = 8; + }; +}; + diff --git a/proto/header.proto b/proto/header.proto new file mode 100644 index 0000000..873a3dd --- /dev/null +++ b/proto/header.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package Messages; + +message Header { + string topic = 1; // topic identifier + uint64 publisherID = 2; // unique identifier of the publisher, 0 if not publishing + uint32 scID = 3; // satellite identifier as per SATDB + uint32 familyID = 4; // family identifier as per SATDB + string key = 5; // key +}; + diff --git a/proto/limits.proto b/proto/limits.proto new file mode 100644 index 0000000..895cc7f --- /dev/null +++ b/proto/limits.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; + +package Limits; + +import "header.proto"; + +message DefinitionUpdate { + string url = 1; // URL of the new overlay or reference database + string filename = 2; // filename, e.g. main + uint32 version = 3; // version number + uint32 scID = 4; // SCID as per SATDB + uint64 ts = 5; // update timestamp +}; + +message Fileset { + uint64 ts = 1; // update timestamp + repeated string urls = 2; // Ordered list of URLs of the databases +}; + +message Item { + Messages.Header header = 1; + + oneof these { + DefinitionUpdate limit_definition_update = 6; + Fileset fileset = 7; + }; +}; + diff --git a/proto/messages.proto b/proto/messages.proto new file mode 100644 index 0000000..b22af4c --- /dev/null +++ b/proto/messages.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +import "header.proto"; +import "alerts.proto"; +import "limits.proto"; +import "msgbus.proto"; + +package Messages; + +message Item { + Header header = 1; + + oneof these { + MsgBus.CreateNewTopic newtopic = 2; + MsgBus.RequestValues request_values = 3; + MsgBus.KeyList keylist = 4; + MsgBus.Status status = 5; + Limits.DefinitionUpdate limit_definition_update = 6; + Limits.Fileset fileset = 7; + Alerts.Alert alert = 8; + MsgBus.RequestType request = 9; + }; +}; + diff --git a/proto/msgbus.proto b/proto/msgbus.proto new file mode 100644 index 0000000..70e4fb7 --- /dev/null +++ b/proto/msgbus.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; + +import "header.proto"; + +package MsgBus; + +enum StatusType { + STATUS_UNDEF = 0; // DO NOT USE + STATUS_TOPIC_NOT_FOUND = 2; + STATUS_KEY_NOT_FOUND = 3; + STATUS_EOT = 4; +}; + +enum RequestType { + REQ_KEYLIST = 0; +} + +message KeyList { + repeated string keys = 1; // key list +}; + +message Status { + StatusType status = 1; + string info = 2; +}; + +// Topic creation +message CreateNewTopic { + uint32 queueSize = 1; // retention size (1 for last value only, more for history) +}; + +// Request value(s) from a topic +message RequestValues { + repeated string keys = 1; // keys +}; + +message Item { + Messages.Header header = 1; + + oneof these { + CreateNewTopic newtopic = 2; + RequestValues request_values = 3; + KeyList keylist = 4; + Status status = 5; + RequestType request = 9; + }; +}; diff --git a/proto/tmt.proto b/proto/tmt.proto new file mode 100644 index 0000000..a4bdb68 --- /dev/null +++ b/proto/tmt.proto @@ -0,0 +1,139 @@ +syntax = "proto3"; + +package tmtdata; + +option java_package = "com.ses.tmt.data.codec.protoc"; +option java_outer_classname = "TmTProtocCodec"; + +enum MessageType { + UNDEF_TYPE = 0; + REQ = 1; + DATA = 2; + END = 3; + HBEAT = 4; + JOIN = 5; + PROCESSING_DONE = 6; + RECONNECT = 7; +} + +enum STATEV { + VALID = 0; + INVALID = 1; + CRC_ERROR = 2; + INVALID_AND_CRC_ERROR = 3; + EXPIRED = 4; + INVALID_AND_EXPIRED = 5; + CRC_ERROR_AND_EXPIRED = 6; + INVALID_AND_CRC_ERROR_AND_EXPIRED = 7; +} + +enum ErrorCode { + UNDEF_ERROR = 0; + NO_ERROR = 1; + UNKNOWN_SAT = 2; + UNKNOWN_SEAT = 3; + MAX_PIDS_EXCEEDED = 4; + INVALID_PID = 5; + START_AFTER_END = 6; + START_AFTER_NOW = 7; + WRONG_LEVELID = 8; + INVALID_PROTOCOL = 9; + SERVER_ERROR = 10; + HBEAT_TIMEOUT = 11; + BAD_REQUEST = 12; + CANCELED = 13; + REQUEST_EXPIRED = 14; + UNKNOWN_SAT_DRIVER_MAPPING = 15; +} + +enum ReqCode { + NO_REQ_CODE = 0; + NO_UPDATE_VALUE = 1; + INITIAL_VALUES = 2; + INITIAL_VALUES_VALID = 3; +} + +enum LIMIT { + NORMAL = 0; + INFO = 1; + WARNING = 2; + HAZARDOUS = 3; + CRITICAL = 4; + OOR = 5; +} + +message Header { + MessageType msgType = 1; +} + +message ReadyWorker { + string workerName = 1; + string workerHost = 2; + string workerState = 3; + string workerData = 4; + string workerRequest = 5; + string workerHb = 6; +} + +message ProcessingDone { + string workerName = 1; + string clientId = 2; +} + +message HeartBeat { + string workerName = 1; + uint32 hbCount = 2; + float cpuLoad = 3; +} + +message HisRequest { + string satName = 1; + string seatName = 2; + ReqCode reqCode = 3; + repeated uint32 pids = 4; + int64 startTime = 5; + int64 endTime = 6; + int32 level = 7; + bool withOol = 8; + bool withRaw = 9; +} + +message End { + ErrorCode errorCode = 1; +} + +message Ool { + LIMIT level = 1; + uint32 limitSet = 2; +} + +message TmSample { + int64 rawV = 1; + double engV = 2; + Ool ool = 3; +} + +message TmStats { + double mean = 1; + double min = 2; + double max = 3; +} + +message TmData { + uint64 time = 1; + uint32 pid = 2; + STATEV stateV = 3; + oneof data { + TmSample tmSample = 4; + TmStats tmStats = 5; + } +} + +message TmDataSet { + repeated TmData tmData = 1; +} + +message TmDataSetPacket { + repeated TmDataSet tmDataSet = 1; +} + diff --git a/protos/SPELLDriver.proto b/protos/SPELLDriver.proto new file mode 100644 index 0000000..7b3d2f9 --- /dev/null +++ b/protos/SPELLDriver.proto @@ -0,0 +1,566 @@ +syntax = "proto3"; + +package spell.driver; + +import "google/protobuf/empty.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/wrappers.proto"; + +option java_multiple_files = true; +option java_package = "lu.ses.engineering.spell.grpc.driver"; +option java_outer_classname = "SPELLDriverProto"; +option go_package = "driver"; + +service SPELLDriverInterface { + rpc GetDriverInfo (DriverInfo) returns (DriverInfo); + rpc Ping (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Close (google.protobuf.Empty) returns (google.protobuf.Empty); +} + +service SPELLDriverInterface_TM { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + + rpc DatabaseLookup (LookupRequest) returns (LookupAnswer); + //Load a set of limits definitions for a given parameter, from a given file. + // + //param: telemetry parameter name + //limits: file with limit definitions + //config: configuration parameters + // returns True/False for Success +// rpc LoadLimits (google.protobuf.Empty) returns (google.protobuf.BoolValue); + //Modify an Out Of Limits definition for a given telemetry parameter + // + //param: the telemetry parameter name + //limits: dictionary containing the limit parameters + //config: configuration dictionary with modifiers + // + //Relevant modifiers are: + // + //- Select=ACTIVE/ALL/: indicates which definitions should be affected + // (all, only the active ones, or the one indicated by + // the string) + // + //Limit parameters dictionary may contain the following: + // + //LoRed,LoYel,HiRed,HiYel: indicate the hard and soft limit values + // + //Midpoint,Tolerance: indicate a middle limit point and a tolerance that is + // used to calculate the upper and lower limits (M+T, M-T) + // Hard and soft limits are considered equal. + // + //Nominal,Earning,Error,Ignore: the values are lists containing the values + // assigned to each category, e.g. Nominal:['ValueA','ValueB'] + // + //Delta: set a step or spike limit + rpc SetLimits (LimitSetRequest) returns (google.protobuf.BoolValue); + //Obtain an Out Of Limits definition for a given telemetry parameter + // + //param: the telemetry parameter name + //config: configuration dictionary with modifiers + // + //Relevant modifiers are: + // + //- Select=ACTIVE/ALL/: indicates which definitions should be considered + // (all, only the active ones, or the one indicated by + // the string) + // + //The limit definition to be returned may be one of the following: + // + //{LoRed,LoYel,HiRed,HiYel}: indicate the hard and soft limit values + // + //{Nominal,Earning,Error,Ignore}: the values are lists containing the values + // assigned to each category, e.g. Nominal:['ValueA','ValueB'] + // + //{Delta}: step or spike limit + rpc GetLimits (TmItemValue) returns (LimitSet); + rpc IsAlarmed (TmItemValue) returns (google.protobuf.BoolValue); + //Inject a ground value for a TM parameter. + // + //tmItem : instance of TmItemClass with the parameter information + //value : contains the required value + //config : configuration dictionary with modifiers. + // returns True/False for success + rpc InjectItem (TmItemValue) returns (google.protobuf.BoolValue); + //Acquire the value for a TM parameter. + // + //tmItem : instance of TmItemClass with the parameter information + //config : configuration dictionary with modifiers. + // + //Relevant modifiers are + // + //- Wait=True/False: when True, the system shall block the caller until + //a new sample of the required parameter arrives to the GCS. If False, + //the last recorded value of the parameter shall be returned immediately. + // + //- ValueFormat=RAW/ENG: if RAW is given, the raw or uncalibrated value + //of the parameter shall be given. If ENG is used, the engineering or + //calibrated value shall be returned. + // + //- Timeout=(TIME): maximum amount of time to wait for new samples, + //before the parameter is declared as impossible to acquire. It only + //makes sense when Wait=True. + // + //Returned value: a list with the value and True/False indicating the validity + //of the parameter + rpc RefreshItem (TmItemValue) returns (TmItemValue); + rpc RestoreNormalLimits (google.protobuf.Any) returns (google.protobuf.BoolValue); + //Instantiate a telemetry parameter (usually taking the information from GCS) + // + //The item shall be derived from TmItemClass class. + // + //If not overriden, the adapter class provides a generic TM item structure. + rpc CreateTmItem (TmItemDesc) returns (TmItemDesc); +} + + +message LookupRequest { + string name = 1; + string type = 2; + string source = 3; +} + +message LookupAnswer { + google.protobuf.Any lookup = 1; +} + +message LimitSetRequest { + TmItemDesc item = 1; + LimitSet set = 2; +} + +message LimitSet { + google.protobuf.Any limitset = 1; +} + +message TmItemValue { + TmItemDesc item = 1; + bool validity = 3; + google.protobuf.Any engValue = 4; + google.protobuf.Any rawValue = 5; + string timestamp = 6; + google.protobuf.Any config = 7; +} + +message TmItemDesc { + string mnemonic = 1; + string description = 2; + string id = 3; +} + +service SPELLDriverInterface_TC { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + + rpc CreateTcItem (TcItemDesc) returns (TcItemDesc); + + //Inject a block of TC items into the GCS. Blocked items are injected + //and transmitted as a single TC frame. + // + //tcItemList : list of TcItemClass instance with the command information. + //config : configuration dictionary + rpc SendBlock (CommandList) returns (google.protobuf.BoolValue); + //Inject a group of TC items into the GCS. + // + //tcItemList : list of TcItemClass instance with the command information. + //config : configuration dictionary + rpc SendList (CommandList) returns (google.protobuf.BoolValue); + //Inject a TC item into the GCS. + // + //tcItem : TcItemClass instance with the command information. + //config : configuration dictionary + rpc SendCommand (CommandDesc) returns (google.protobuf.BoolValue); + +// rpc CheckCriticalCommands (google.protobuf.Empty) returns (google.protobuf.Empty); + +} + +message CommandList { + repeated CommandDesc commands = 1; + google.protobuf.Any config = 2; +} + +message TcItemDesc { + string mnemonic = 1; + string description = 2; + string id = 3; +} + +message CommandDesc { + TcItemDesc command = 1; + google.protobuf.Any args = 2; + google.protobuf.Any config = 3; +} + +service SPELLDriverInterface_EV { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + // Invoked by the system in order to inject an event into the GCS. + // + // message: string containing the event message + // config: dictionary containing the event parameters: + // - Severity modifier (INFORMATION/WARNING/ERROR/FATAL) + // - Scope (SCOPE_PROC,SCOPE_SYS,SCOPE_CFG) + rpc RaiseEvent (Event) returns (google.protobuf.Empty); + //NOT USED AT THE MOMENT! + rpc RegisterForEvents (google.protobuf.Empty) returns (stream google.protobuf.Empty); + //NOT USED AT THE MOMENT! + rpc UnRegisterForEvents (google.protobuf.Empty) returns (google.protobuf.Empty); + //NOT USED AT THE MOMENT! + rpc PullEvents (google.protobuf.Empty) returns (google.protobuf.Empty); +} + +message Event { + string message = 1; + google.protobuf.Any config = 2; +} + +service SPELLDriverInterface_PCS { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + + rpc CreatePtcItem (PtcItemDesc) returns (PtcItemDesc); + + rpc PCS_GetStatus (google.protobuf.Any) returns (google.protobuf.Any); + rpc PCS_IsArqEnabled (google.protobuf.Any) returns (google.protobuf.BoolValue); + rpc PCS_IsVerifyModeEnabled (google.protobuf.Any) returns (google.protobuf.BoolValue); + rpc PCS_ReadyToCommand (google.protobuf.Any) returns (google.protobuf.StringValue); + rpc PCS_AbortPtc (google.protobuf.Any) returns (google.protobuf.BoolValue); + + rpc SendPtcCommand (PtcDesc) returns (PtcResult); + rpc SendPtcList (PtcList) returns (PtcResult); + rpc PCS_Control (PtcDesc) returns (PtcResult); + +} +message PtcItemDesc { + string mnemonic = 1; + string description = 2; + string id = 3; +} +message PtcList { + repeated PtcDesc commands = 1; + google.protobuf.Any config = 2; +} + +message PtcDesc { + PtcItemDesc command = 1; + google.protobuf.Any args = 2; + google.protobuf.Any config = 3; +} + +message PtcResult { + repeated int64 code = 1; + repeated bool success = 2; + repeated string stage = 3; + repeated string data = 4; + repeated string error = 5; +} + +service SPELLDriverInterface_MEM { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + + rpc GenerateReport (MemoryReportRequest) returns (google.protobuf.BoolValue); + rpc CompareImages (CompareMemoryReportRequest) returns (google.protobuf.BoolValue); + rpc CreateGoldenImage (GoldenImageRequest) returns (google.protobuf.BoolValue); + rpc MemoryLookup (MemoryLookupRequest) returns (google.protobuf.Any); + rpc DataObjectLookup (DataObjectLookupRequest) returns (google.protobuf.Any); + rpc DataItemLookup (DataItemLookupRequest) returns (google.protobuf.Any); +} + +message MemoryReportRequest { + string image = 1; + string report_type = 2; + string begin = 3; + string end = 4; + string source = 5; + google.protobuf.Any config = 6; +} + +message CompareMemoryReportRequest { + string image1 = 1; + string image2 = 2; + string report_type = 3; + string begin = 4; + string end = 5; + string source = 6; + google.protobuf.Any config = 7; +} + +message GoldenImageRequest { + string scp = 1; + string filename = 2; + google.protobuf.Any config = 3; +} + +message MemoryLookupRequest { + string name = 1; + string address = 2; + string image = 3; + string report_type = 4; + string source = 5; + google.protobuf.Any config = 6; +} + +message DataObjectLookupRequest { + string name = 1; + string type = 2; + google.protobuf.Any config = 3; +} + +message DataItemLookupRequest { + string name = 1; + string type = 2; + string source = 3; + string valformat = 4; + google.protobuf.Any config = 5; +} + +service SPELLDriverInterface_RSC { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + + // Enable or disable a GCS link (TM, TC or others) + // + // name: link identifier + // enable: True/False, indicates if the link needs to be enabled or disabled + // config: configuration modifiers + rpc SetLink (LinkRequest) returns (google.protobuf.BoolValue); + // Check if a GCS link (TM, TC or others) is enabled or disabled + // + // name: link identifier + // config: configuration modifiers + rpc CheckLink (LinkRequest) returns (google.protobuf.BoolValue); + // Assign the value of one resource or configuration parameter in the GCS + // + // name: resource identifier + // value: resource value + // config: configuration modifiers + rpc SetResource (ResourceRequest) returns (google.protobuf.BoolValue); + // Acquire the value of one resource or configuration parameter in the GCS + // + // name: resource identifier + // config: configuration modifiers + rpc GetResource (ResourceRequest) returns (ResourceRequest); + // Acquire the name-value map of all resource or configuration parameters + // in the GCS + // + // name: resource identifier + // config: configuration modifiers + rpc GetResources (ResourcesRequest) returns (ResourcesRequest); + // Acquire the current status of one resource or configuration parameter + // in the GCS + // + // name: resource identifier + // config: configuration modifiers + rpc GetResourceStatus (ResourceRequest) returns (ResourceRequest); + // Check if the current value of one resource or configuration parameter + // in the GCS is correct or incorrect + // + // name: resource identifier + // config: configuration modifiers + rpc IsResourceOK (ResourceRequest) returns (google.protobuf.BoolValue); +} + +message LinkRequest { + string name = 1; + bool status = 2; + google.protobuf.Any config = 3; +} + +message ResourceRequest { + string name = 1; + google.protobuf.Any value = 2; + google.protobuf.Any config = 3; +} + +message ResourcesRequest { + google.protobuf.Any value = 2; + google.protobuf.Any config = 3; +} + +service SPELLDriverInterface_TASK { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + // Invoked by the system in order to stop a GCS task. + // + // name: string containing the task name + // config: configuration dictionary with modifiers. + rpc StartTask (Task) returns (google.protobuf.BoolValue); + // Invoked by the system in order to stop a GCS task. + // + // name: string containing the task name + // config: configuration dictionary with modifiers. + rpc StopTask (Task) returns (google.protobuf.BoolValue); + // Invoked by the system in order to check the status of a GCS task. + // + // name: string containing the task name + // config: configuration dictionary with modifiers. + rpc CheckTask (Task) returns (google.protobuf.Int32Value); + // Invoked by the system in order to open a telemetry display on the GCS + // + // displayName: name or identifier of the display + // config: configuration dictionary with modifiers. + // + // Relevant modifiers are: + // + // Host: the machine name where the display should be open. + rpc OpenDisplay (Display) returns (google.protobuf.Empty); + // Invoked by the system in order to print a telemetry display from the GCS + // + // displayName: name or identifier of the display + // config: configuration dictionary with modifiers. + // + // Relevant modifiers are: + // + // Printer: the printer name + // Format: PS (postcript) or VECTOR (ASCII text, for alphanumeric displays only) + rpc PrintDisplay (Display) returns (google.protobuf.Empty); + // Invoked by the system in order to close a telemetry display on the GCS + // + // displayName: name or identifier of the display + // config: configuration dictionary with modifiers. + // + // Relevant modifiers are: + // + // Host: the machine name where the display should be closed. + rpc CloseDisplay (Display) returns (google.protobuf.Empty); +} + +message Task { + string name = 1; + google.protobuf.Any args = 2; + google.protobuf.Any config = 3; +} + +message Display { + string name = 1; + google.protobuf.Any config = 2; +} + +service SPELLDriverInterface_RNG { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + + rpc EnableRanging (Ranging) returns (google.protobuf.BoolValue); + rpc DisableRanging (Ranging) returns (google.protobuf.BoolValue); + rpc AbortRanging (Ranging) returns (google.protobuf.BoolValue); + rpc StartRanging (Ranging) returns (google.protobuf.BoolValue); + rpc StartCalibration (Ranging) returns (google.protobuf.BoolValue); + + rpc GetBasebandConfig (BaseBandConfig) returns (BaseBandConfig); + rpc SetBasebandConfig (BaseBandConfig) returns (google.protobuf.BoolValue); + + rpc GetAntennaNames (google.protobuf.Any) returns (Names); + rpc GetRangingPaths (google.protobuf.Any) returns (Names); + rpc GetBasebandNames (google.protobuf.Any) returns (Names); + rpc GetRangingStatus (google.protobuf.Any) returns (google.protobuf.StringValue); + rpc UpdateCortexConf (google.protobuf.Any) returns (google.protobuf.BoolValue); +} + +message Ranging { + string bbe = 1; + string antenna = 2; + google.protobuf.Any config = 3; +} + +message BaseBandConfig { + string bbe = 1; + string param = 2; + string value = 4; + google.protobuf.Any config = 3; +} + +message Names { + repeated string names = 1; +} + +service SPELLDriverInterface_USER { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + // Login the given user in the GCS system. + // + // username: user name + // password: the user password + // config: configuration dictionary with modifiers. + rpc Login (LoginCred) returns (google.protobuf.BoolValue); + // Logout the given user from the GCS system. + // + // username: user name + // config: configuration dictionary with modifiers. + rpc Logout (LoginCred) returns (google.protobuf.BoolValue); + // Check if the given user is logged in the GCS system. + // + // username: user name + // config: configuration dictionary with modifiers. + rpc IsLoggedIn (LoginCred) returns (google.protobuf.BoolValue); +} + +message LoginCred { + string username = 1; + string password = 2; + google.protobuf.Any config = 3; +} + +service SPELLDriverInterface_TIME { + rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty); + // Obtain the current UTC time according to the GCS time. If the present + // example is not change, the interface provices the current system local + // time. + // + // config: SPELL configuration dictionary. + rpc GetUTC (google.protobuf.Any) returns (Time); +} + +message Interfaces { + // Dummy message just for the namespace + enum DriverInterface { + TM = 0; + TC = 1; + EV = 2; + PCS = 3; + MEM = 4; + RSC = 5; + TASK = 6; + RNG = 7; + USER = 8; + CONFIG = 9; + TIME = 10; + } +} + +message DriverInfo { + string host = 1; + uint32 port = 2; + string driverName = 3; + repeated Interfaces.DriverInterface interfaces = 4; +} + +message List { + repeated google.protobuf.Any entries = 1; +} + +message Dict { + repeated DictEntry entries = 1; +} + +message Time { + string timeMsg = 1; +} + +message DictEntry { + google.protobuf.Any key = 1; + google.protobuf.Any value = 2; +} diff --git a/protos/SPELLExecutor.proto b/protos/SPELLExecutor.proto new file mode 100644 index 0000000..63db07b --- /dev/null +++ b/protos/SPELLExecutor.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package spell.core; + +import "SPELLDriver.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +option java_multiple_files = true; +option java_package = "lu.ses.engineering.spell.grpc.executor"; +option java_outer_classname = "SPELLExecutorProto"; +option go_package = "driver"; + +service SPELLExecutor { + rpc DriverLogin(driver.DriverInfo) returns (ExecutorCapability); + + rpc Ping (google.protobuf.Empty) returns (google.protobuf.Empty); + rpc Close (google.protobuf.Empty) returns (google.protobuf.Empty); +} + +message ExecutorCapability { + bool providesSpellAccess = 1; + bool providesControlAccess = 2; + bool providesMonitorAccess = 3; +} diff --git a/protos/SPELLService.proto b/protos/SPELLService.proto new file mode 100644 index 0000000..012a7fd --- /dev/null +++ b/protos/SPELLService.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package spell.service; + +import "google/protobuf/empty.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/wrappers.proto"; + +option java_multiple_files = true; +option java_package = "lu.ses.engineering.spell.service"; +option java_outer_classname = "SPELLServiceProto"; +option go_package = "service"; + +service SPELLServiceRegistry { + +} diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 4242a27..f020941 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -1,29 +1,36 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ -include ${top_srcdir}/common.mk +SRC=${srcdir}/src +DST=${exec_prefix}/bin -SUBDIRS=linux +install-exec-hook: + mkdir -p ${exec_prefix}/bin + cp -u ${SRC}/setup-environment.sh ${DST} + cp -u ${SRC}/SPELL-Driver ${DST} + cp -u ${SRC}/SPELL-Server ${DST} + cp -u ${SRC}/SPELL-Server-Docker ${DST} + cp -u ${SRC}/Kill-Server ${DST} + cp -u ${SRC}/Shell ${DST} +if WITH_PACE + cp -u ${SRC}/PACE-Server ${DST} + cp -u ${SRC}/Kill-PACE ${DST} +endif diff --git a/scripts/src/Kill-PACE b/scripts/src/Kill-PACE new file mode 100644 index 0000000..12b0903 --- /dev/null +++ b/scripts/src/Kill-PACE @@ -0,0 +1,74 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +function terminate_gracefully() { + PID=$1 + TRIES=10 + echo "Terminating process $PID" + # terminate + kill $PID > /dev/null 2>&1 + for i in $(seq 1 $TRIES); do + sleep 1 + if ps -p $PID > /dev/null; then + echo "Process $PID is still running (attempt #$i out of $TRIES)" + else + echo "Process $PID exited gracefully" + break + fi + done + # kill it + if ps -p $PID > /dev/null; then + echo "Could not terminate process $PID gracefully, killing it" + kill -9 $PID > /dev/null 2>&1 + fi +} + +# Satellite +SATELLITE=$1 +[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1 + +# SPELL home +if [ -z $SPELL_HOME ]; then + export SPELL_HOME=/home/spell/SPELL +fi +[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1 + +# Set the server configuration file to be used +if [ -z $SPELL_CONFIG ]; then + SPELL_CONFIG=/home/spell/SPELL_CONFIG +fi +CFG_FILE=$SPELL_CONFIG/server/server_$SATELLITE.xml +[ ! -f $CFG_FILE ] && echo "ERROR: cannot find configuration file: $CFG_FILE" && exit 1 + +echo "Terminating all PACE processes started with config ${CFG_FILE}" + +PROCESSES="PACE" +for P in $PROCESSES; do + PIDS=(`pgrep -u $USER -f "$P .*-c ${CFG_FILE}.*"`) + if [ ${#PIDS[@]} == 0 ]; then + continue + fi + echo "Terminating ${#PIDS[@]} $P instance(s)" + for PID in ${PIDS[@]}; do + terminate_gracefully $PID + done +done diff --git a/scripts/src/Kill-Server b/scripts/src/Kill-Server new file mode 100644 index 0000000..010095d --- /dev/null +++ b/scripts/src/Kill-Server @@ -0,0 +1,77 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +function terminate_gracefully() { + PID=$1 + TRIES=10 + echo "Terminating process $PID" + # terminate + kill $PID > /dev/null 2>&1 + for i in $(seq 1 $TRIES); do + sleep 1 + if ps -p $PID > /dev/null; then + echo "Process $PID is still running (attempt #$i out of $TRIES)" + else + echo "Process $PID exited gracefully" + break + fi + done + # kill it + if ps -p $PID > /dev/null; then + echo "Could not terminate process $PID gracefully, killing it" + kill -9 $PID > /dev/null 2>&1 + fi +} + +# Satellite +SATELLITE=$1 +[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1 + +# SPELL home +if [ -z $SPELL_HOME ]; then + export SPELL_HOME=/home/spell/SPELL +fi +[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1 + +# Set the server configuration file to be used +if [ -z $SPELL_CONFIG ]; then + SPELL_CONFIG=/home/spell/SPELL_CONFIG +fi +CFG_FILE=$SPELL_CONFIG/server/server_$SATELLITE.xml +[ ! -f $CFG_FILE ] && echo "ERROR: cannot find configuration file: $CFG_FILE" && exit 1 + +echo "Terminating SPELL processes started with config ${CFG_FILE}" + +PROCESSES="SPELL-Executor SPELL-ExecutorCmd SPELL-Shell SPELL-Executor_v3 SPELL-ExecutorCmd_v3 SPELL-Shell_v3 SPELL-Context SPELL-Listener" +if [[ "$2" != "skipservice" ]]; then + PROCESSES="SPELL-Service $PROCESSES" +fi +for P in $PROCESSES; do + PIDS=(`pgrep -u $USER -f "$P .*-c ${CFG_FILE}.*"`) + if [ ${#PIDS[@]} == 0 ]; then + continue + fi + echo "Terminating ${#PIDS[@]} $P instance(s)" + for PID in ${PIDS[@]}; do + terminate_gracefully $PID + done +done diff --git a/scripts/src/PACE-Server b/scripts/src/PACE-Server new file mode 100644 index 0000000..4d1c25b --- /dev/null +++ b/scripts/src/PACE-Server @@ -0,0 +1,70 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +#=============================================================================== +# Setup main environment variables +#=============================================================================== + +# Satellite +SATELLITE=$1 +[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1 + +# Set SPELL home +if [ -z $SPELL_HOME ]; then + export SPELL_HOME=/home/spell/SPELL +fi +[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1 + +#=============================================================================== +# Setup environment +#=============================================================================== +SETUP_SCRIPT=$SPELL_HOME/bin/setup-environment.sh +[ ! -f $SETUP_SCRIPT ] && echo "ERROR: cannot find environment setup script: $SETUP_SCRIPT" && exit 1 +! source $SETUP_SCRIPT && echo "ERROR: SPELL environment setup failed" && exit 1 + +#=============================================================================== +# Launcher configuration +#=============================================================================== +APP_PATH=$SPELL_HOME/bin/PACE +CFG_PATH=$SPELL_CONFIG/server/server_$SATELLITE.xml +[ ! -f $CFG_PATH ] && echo "ERROR: could not find configuration file: $CFG_PATH" && exit 1 +[ ! -f $APP_PATH ] && echo "ERROR: could not find application: $APP_PATH" && exit 1 + +#=============================================================================== +# Pre-execution cleanup +#=============================================================================== +echo "Cleanup of previous PACE instances" +$SPELL_HOME/bin/Kill-PACE $SATELLITE + +#=============================================================================== +# Execute application +#=============================================================================== +VERSION=$($APP_PATH -version) +echo "Starting $VERSION server for $SATELLITE" +if [[ ( "$USER" == "hifly_admin" ) && ( -f $BIN_DIR/APPLInotify ) ]] +then + echo "Notifying hifly..." + $BIN_DIR/APPLInotify start $$ + exec $APP_PATH -c $CFG_PATH -n $SATELLITE && $BIN_DIR/APPLInotify stop $$ +else + nohup $APP_PATH -c $CFG_PATH -n $SATELLITE >> $SPELL_LOG/pace_$SATELLITE.log 2>&1 & +fi diff --git a/scripts/src/SPELL-Compile b/scripts/src/SPELL-Compile new file mode 100644 index 0000000..ad18786 --- /dev/null +++ b/scripts/src/SPELL-Compile @@ -0,0 +1,37 @@ +#!/usr/bin/env python +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +import py_compile, sys + +if len(sys.argv) not in [2, 3]: + print("please provide an input file and optionally an output file") + sys.exit(1) + +outFile = '/tmp/ignore.py' +if len(sys.argv) == 3: + outFile = sys.argv[2] + +try: + py_compile.compile(sys.argv[1], cfile=outFile, doraise=True) +except Exception as e: + sys.stderr.write('### Python compile error:\n' + str(e) + '\n') + raise diff --git a/scripts/src/SPELL-Disassemble b/scripts/src/SPELL-Disassemble new file mode 100644 index 0000000..38fccf4 --- /dev/null +++ b/scripts/src/SPELL-Disassemble @@ -0,0 +1,100 @@ +#!/usr/bin/env python +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +import dis, marshal, struct, sys, time, types, os + +def show_file(fname): + if os.path.exists(fname): + f = open(fname, "rb") + magic = f.read(4) + moddate = f.read(4) + modtime = time.asctime(time.localtime(struct.unpack('L', moddate)[0])) + print("magic %s" % (magic.encode('hex'))) + print("moddate %s (%s)" % (moddate.encode('hex'), modtime)) + code = marshal.load(f) + code_tree(code) + show_code(code) + +def show_code(code, indent=''): + print("%scode" % indent) + indent += ' ' + print("%sargcount %d" % (indent, code.co_argcount)) + print("%snlocals %d" % (indent, code.co_nlocals)) + print("%sstacksize %d" % (indent, code.co_stacksize)) + print("%sflags %04x" % (indent, code.co_flags)) + show_hex("code", code.co_code, indent=indent) + dis.disassemble(code) + print("%sconsts" % indent) + for const in code.co_consts: + if type(const) == types.CodeType: + show_code(const, indent+' ') + else: + print(" %s%r" % (indent, const)) + print("%snames %r" % (indent, code.co_names)) + print("%svarnames %r" % (indent, code.co_varnames)) + print("%sfreevars %r" % (indent, code.co_freevars)) + print("%scellvars %r" % (indent, code.co_cellvars)) + print("%sfilename %r" % (indent, code.co_filename)) + print("%sname %r" % (indent, code.co_name)) + print("%sfirstlineno %d" % (indent, code.co_firstlineno)) + show_hex("lnotab", code.co_lnotab, indent=indent) + show_table(code.co_lnotab,indent=indent) + +def code_tree(code, indent=''): + print("%scode object: %s" % (indent,code)) + for const in code.co_consts: + if type(const) == types.CodeType: + code_tree(const, indent+' ') + +def show_table( lnotab, indent ): + lnotab = lnotab.encode('hex') + if len(lnotab) < 32: + print(indent, end=' ') + for idx in range(0,len(lnotab),4): + offset = int(lnotab[idx:idx+2], 16) + sline = int(lnotab[idx+2:idx+4], 16) + print("(%s,%s) " % (offset,sline), end=' ') + print() + else: + for i in range(0, len(lnotab), 32): + line = lnotab[i:i+32] + print(indent, end=' ') + for idx in range(0,len(line),4): + offset = int(lnotab[idx:idx+2], 16) + sline = int(lnotab[idx+2:idx+4], 16) + print("(%s,%s) " % (offset,sline), end=' ') + print() + +def show_hex(label, h, indent): + h = h.encode('hex') + if len(h) < 60: + print("%s%s %s" % (indent, label, h)) + else: + print("%s%s" % (indent, label)) + for i in range(0, len(h), 60): + print("%s %s" % (indent, h[i:i+60])) + +if len(sys.argv) != 2: + print("please provide an input file") + sys.exit(1) + +show_file(sys.argv[1]) diff --git a/scripts/src/SPELL-Driver b/scripts/src/SPELL-Driver new file mode 100644 index 0000000..555b3d3 --- /dev/null +++ b/scripts/src/SPELL-Driver @@ -0,0 +1,75 @@ +#!/usr/bin/env python + +# Prototype for a standalone driver execution with an gRPC interface +# Author: Raimondas Sasnauskas +# Date: 2018-03-09 + +import os, sys +import argparse + +# parse command line arguments +parser = argparse.ArgumentParser() +parser.add_argument("context", type=str, help="context name") +group = parser.add_argument_group() +group.add_argument("--host", type=str, help="executor service host") +group.add_argument("--port", type=int, help="executor service port") +group.add_argument("--debug", dest='debug', action='store_true') +parser.set_defaults(debug=False) +args = parser.parse_args() + +if (args.host and not args.port) or (not args.host and args.port): + parser.error("both executor host and port must be specified") + +# check necessary environment variables +for e in ["SPELL_HOME", "SPELL_CONFIG", "SPELL_COTS"]: + if os.getenv(e): + continue + parser.error("%s environment variable not set" % e) + +# check if the config file exists +SPELL_HOME = os.getenv("SPELL_HOME") +SPELL_CONFIG = os.getenv("SPELL_CONFIG") +config = SPELL_CONFIG + os.sep + "server" + os.sep + "server_" + args.context + ".xml" +if not os.path.isfile(config): + parser.error("Configuration file does not exist: " + config) + +# Extend PYTHONPATH +sys.path.append(SPELL_HOME + os.sep + "spell") +sys.path.append(SPELL_HOME + os.sep + "spell" + os.sep + "spell" + os.sep + "stubs") +sys.path.append(SPELL_HOME + os.sep + "lib") +sys.path.append(SPELL_HOME + os.sep + "drivers" + os.sep + "service") + +# always load grpc imports first +import driverserver +from exec_client import * +from cif_client import * + +from spell.utils.log import LOG +# set the log file +if not args.debug: + LOG.setLogFile('SPELL-Driver-%s' % args.context) + LOG.setShowLog(False) + +# spell imports +from spell.config.reader import Config +from spell.lib.drivermgr import DriverManager +from spell.lib.registry import REGISTRY + +def run(): + # load config file + Config.instance().load(config) + + # load the driver + mgr = DriverManager.instance() + mgr.setup(args.context, skipSetup=True) + # always setup config interface + REGISTRY['CONFIG'].setup(mgr.contextConfig, mgr.driverConfig) + + # start gRPC server + driverserver.serve(args.host, args.port) + + # cleanup the driver + mgr.cleanup(True, True) + +if __name__ == "__main__": + run() diff --git a/scripts/src/SPELL-Server b/scripts/src/SPELL-Server new file mode 100644 index 0000000..4af2a50 --- /dev/null +++ b/scripts/src/SPELL-Server @@ -0,0 +1,69 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +#=============================================================================== +# Setup main environment variables +#=============================================================================== + +# Satellite +SATELLITE=$1 +[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1 + +# Set SPELL home +if [ -z $SPELL_HOME ]; then + export SPELL_HOME=/home/spell/SPELL +fi +[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1 + +#=============================================================================== +# Setup environment +#=============================================================================== +SETUP_SCRIPT=$SPELL_HOME/bin/setup-environment.sh +[ ! -f $SETUP_SCRIPT ] && echo "ERROR: cannot find environment setup script: $SETUP_SCRIPT" && exit 1 +! source $SETUP_SCRIPT && echo "ERROR: SPELL environment setup failed" && exit 1 + +#=============================================================================== +# Launcher configuration +#=============================================================================== +APP_PATH=$SPELL_HOME/bin/SPELL-Listener +CFG_PATH=$SPELL_CONFIG/server/server_$SATELLITE.xml +[ ! -f $CFG_PATH ] && echo "ERROR: could not find configuration file: $CFG_PATH" && exit 1 +[ ! -f $APP_PATH ] && echo "ERROR: could not find application: $APP_PATH" && exit 1 + +#=============================================================================== +# Pre-execution cleanup +#=============================================================================== +echo "Cleanup of previous server instances except of running SPELL services" +$SPELL_HOME/bin/Kill-Server $SATELLITE skipservice + +#=============================================================================== +# Execute application +#=============================================================================== +echo "Starting SPELL server for $SATELLITE" +if [[ ( "$USER" == "hifly_admin" ) && ( -f $BIN_DIR/APPLInotify ) ]] +then + echo "Notifying hifly..." + $BIN_DIR/APPLInotify start $$ + exec $APP_PATH -c $CFG_PATH && $BIN_DIR/APPLInotify stop $$ +else + nohup $APP_PATH -c $CFG_PATH >> $SPELL_LOG/server_$SATELLITE.log 2>&1 & +fi diff --git a/scripts/src/SPELL-Server-Docker b/scripts/src/SPELL-Server-Docker new file mode 100644 index 0000000..0f1d087 --- /dev/null +++ b/scripts/src/SPELL-Server-Docker @@ -0,0 +1,80 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +#=============================================================================== +# Setup main environment variables +#=============================================================================== + +# Satellite +SATELLITE=$1 +[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1 + +# Set SPELL home +if [ -z $SPELL_HOME ]; then + export SPELL_HOME=/home/spell/SPELL +fi +[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1 + +#=============================================================================== +# Setup environment +#=============================================================================== +SETUP_SCRIPT=$SPELL_HOME/bin/setup-environment.sh +[ ! -f $SETUP_SCRIPT ] && echo "ERROR: cannot find environment setup script: $SETUP_SCRIPT" && exit 1 +! source $SETUP_SCRIPT && echo "ERROR: SPELL environment setup failed" && exit 1 + +#=============================================================================== +# Launcher configuration +#=============================================================================== +APP_PATH=$SPELL_HOME/bin/SPELL-Listener +CFG_PATH=$SPELL_CONFIG/server/server_$SATELLITE.xml +[ ! -f $CFG_PATH ] && echo "ERROR: could not find configuration file: $CFG_PATH" && exit 1 +[ ! -f $APP_PATH ] && echo "ERROR: could not find application: $APP_PATH" && exit 1 + +#=============================================================================== +# Pre-execution cleanup +#=============================================================================== +echo "Cleanup of previous server instances except of running SPELL services" +$SPELL_HOME/bin/Kill-Server $SATELLITE skipservice + +#============================================================================== +# SPELL COTS +#============================================================================== + +export PATH=$SPELL_COTS/bin:$PATH +export LD_LIBRARY_PATH=$SPELL_COTS/lib:$SPELL_HOME/lib:$SPELL_DRIVER/lib:$LD_LIBRARY_PATH +export BACKWARD_CXX_SOURCE_PREFIXES=/home/spell/src/lib/SPELL_CFG/src + + +#=============================================================================== +# Execute application +#=============================================================================== +echo "Starting SPELL server for $SATELLITE" +if [[ ( -f $BIN_DIR/APPLInotify ) ]] +then + echo "Notifying hifly..." + $BIN_DIR/APPLInotify start $$ + $APP_PATH -c $CFG_PATH && $BIN_DIR/APPLInotify stop $$ +else + $APP_PATH -c $CFG_PATH 2>&1 | tee -a $SPELL_LOG/server_$SATELLITE.log +fi + +#tail -f $SPELL_LOG/server_$SATELLITE.log \ No newline at end of file diff --git a/scripts/src/Shell b/scripts/src/Shell new file mode 100644 index 0000000..0b88a15 --- /dev/null +++ b/scripts/src/Shell @@ -0,0 +1,40 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +#=============================================================================== +# Setup main environment variables +#=============================================================================== + +# SPELL home +if [ -z $SPELL_HOME ]; then + export SPELL_HOME=/home/spell/SPELL +fi +[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1 + +#=============================================================================== +# Setup environment +#=============================================================================== +SETUP_SCRIPT=$SPELL_HOME/bin/setup-environment.sh +[ ! -f $SETUP_SCRIPT ] && echo "ERROR: cannot find SPELL environment setup script: $SETUP_SCRIPT" && exit 1 +! source $SETUP_SCRIPT && echo "ERROR: SPELL environment setup failed" && exit 1 + +$SPELL_HOME/bin/SPELL-Shell $@ diff --git a/scripts/src/generate-release-nfo.sh b/scripts/src/generate-release-nfo.sh new file mode 100644 index 0000000..85c18f4 --- /dev/null +++ b/scripts/src/generate-release-nfo.sh @@ -0,0 +1,59 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +if [ -f "/etc/centos-release" ]; then + PLATFORM=$(cat /etc/centos-release) +elif [ `which lsb_release` ]; then + PLATFORM=$(lsb_release -a | grep Description | cut -d: -f2 | tr -d '\t') +elif [ -f "/etc/lsb_release" ]; then + PLATFORM=$(cat /etc/lsb-release | grep -Po '.*DISTRIB_DESCRIPTION="\K([^"]*)') +else + PLATFORM="Unknown" +fi + +if [ -z "${VERSION_TAG}" ]; then + REVISION=$(git describe --tags --always --long 2> /dev/null) +else + REVISION="${VERSION_TAG}" +fi + +echo "\ +--------- +CHANGELOG +--------- + +$(cat $1 2> /dev/null) + +================================================================================ +Generation date : $(date +%Y-%m-%d) +Revision : $REVISION +Version : $2 +Build host : $(hostname) +Build user : $(whoami) +Platform : $PLATFORM +Installation path : $3 +GCC : $(gcc --version | head -1) +Configure log : + +$(head -8 config.log) +================================================================================\ +" diff --git a/scripts/src/setup-environment.sh b/scripts/src/setup-environment.sh new file mode 100644 index 0000000..ecf197f --- /dev/null +++ b/scripts/src/setup-environment.sh @@ -0,0 +1,122 @@ +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +#============================================================================== +# HELPER FUNCTIONS +#============================================================================== + +function check_env_variable() { + DST=${!1} + if [ -z $DST ]; then + echo "$1 is not set, defaulting to $2" + export $1=$2 + fi + DST=${!1} + if [ ! -d $DST ]; then + echo "ERROR: cannot find $1 directory: $DST" + return 1 + else + return 0 + fi +} + +#============================================================================== +# ENVIRONMENT VARIABLES FOR SPELL +#============================================================================== + +echo ">>> SPELL environment setup begin" +! check_env_variable SPELL_LOG $SPELL_HOME/log && mkdir -p $SPELL_LOG + +# check/set environment variables +! check_env_variable SPELL_HOME /home/spell/SPELL && return 1 +! check_env_variable SPELL_DATA /home/spell/SPELL_PROCS && return 1 +! check_env_variable SPELL_CONFIG /home/spell/SPELL_CONFIG && return 1 +! check_env_variable SPELL_LOG $SPELL_HOME/log && return 1 +! check_env_variable SPELL_COTS /home/spell/spell_cots && return 1 + +# parse release.nfo +RELEASENFO=$SPELL_HOME/release.nfo +[ ! -f $RELEASENFO ] && echo "ERROR: $RELEASENFO not found, check installation" && return 1 +VERSION=`grep ^Version $RELEASENFO | cut -d: -f 2 | tr -d ' '` +[ -z $VERSION ] && echo "ERROR: $RELEASENFO does not contain SPELL version" && return 1 + +[ -z "$USER" ] && export USER=spell + +echo "*** SPELL version $VERSION" +echo "*** SPELL_HOME=$SPELL_HOME" +echo "*** SPELL_DATA=$SPELL_DATA" +echo "*** SPELL_CONFIG=$SPELL_CONFIG" +echo "*** SPELL_LOG=$SPELL_LOG" +echo "*** SPELL_COTS=$SPELL_COTS" +echo "*** current User: $USER" + +#============================================================================== +# SPELL ulimits +#============================================================================== + +echo "*** Setting ulimits" +ulimit -c unlimited > /dev/null 2>&1 +ulimit -s unlimited > /dev/null 2>&1 +ulimit -u 30000 > /dev/null 2>&1 +ulimit -a | grep "core file size" +ulimit -a | grep "stack size" +ulimit -a | grep "max user processes" + +#============================================================================== +# SPELL COTS +#============================================================================== + +export PATH=$SPELL_COTS/bin:$PATH +export LD_LIBRARY_PATH=$SPELL_COTS/lib:$SPELL_HOME/lib:$LD_LIBRARY_PATH + +#============================================================================== +# PYTHON CHECKS +#============================================================================== + +PYTHON=`which python` +[ -z $PYTHON ] && echo "ERROR: no python executable in PATH" && return 1 + +# is the python version supported? +PYVERSION=`$PYTHON -V 2>&1 | cut -d' ' -f 2` +PYREL=`echo $PYVERSION | cut -d'.' -f 1` +PYMAJOR=`echo $PYVERSION | cut -d'.' -f 2` +(( $PYREL != 2 )) && echo "ERROR: python > 2.X.Y required" && return 1 +(( $PYMAJOR < 5 )) && echo "ERROR: python > 2.5.Y required" && return 1 + +echo "*** Using python version $PYVERSION in $PYTHON" + +# is the python executable coming from COTS? +[[ "$(dirname $PYTHON)" != "$SPELL_COTS/bin" ]] \ + && echo "ERROR: python executable must be in COTS, check installation" && return 1 + +# is the python interpreter shared library matching? +EXC=$SPELL_HOME/bin/SPELL-Executor +[ ! -f $EXC ] && echo "ERROR: SPELL-Executor not found $SPELL_HOME/bin, check installation" && return 1 +EXPECTED=`readelf -d $EXC | grep ".*NEEDED.*Shared.*libpython.*" | cut -d[ -f 2 | cut -d] -f1` +AVAILABLE=`readelf -d $PYTHON | grep ".*NEEDED.*Shared.*libpython.*" | cut -d[ -f 2 | cut -d] -f1` +[[ "$EXPECTED" != "$AVAILABLE" ]] \ + && echo "ERROR: shared library mismatch, SPELL was compiled with $EXPECTED, got $AVAILABLE" && return 1 + +# print python path for validation +$PYTHON -c "import sys; print sys.path" + +echo ">>> SPELL environment setup and validation done" +echo diff --git a/scripts/src/version.sh b/scripts/src/version.sh new file mode 100644 index 0000000..67771d1 --- /dev/null +++ b/scripts/src/version.sh @@ -0,0 +1,29 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +if [ -z "${VERSION_TAG}" ]; then + REVISION=$(git describe --tags --always --long 2> /dev/null) +else + REVISION="${VERSION_TAG}" +fi + +echo -ne "$REVISION" diff --git a/src/Makefile.am b/src/Makefile.am index a4004d5..bde773d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,52 +1,23 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2012 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### -AUTOMAKE_OPTIONS = foreign -SUBDIRS=spell - -if WITH_EXECUTOR -SUBDIRS += executor -endif - -if WITH_EXECUTOR_CMD -SUBDIRS += executorcmd -endif - -if WITH_SHELL -SUBDIRS += shell -endif - -if WITH_LISTENER -SUBDIRS += listener -endif - -if WITH_CONTEXT -SUBDIRS += context -endif - -if WITH_GUI -SUBDIRS += spel-gui -endif +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ +SUBDIRS = context executor executorcmd listener service shell ping spell + \ No newline at end of file diff --git a/src/context/Makefile.am b/src/context/Makefile.am index e2f215c..c10aa73 100644 --- a/src/context/Makefile.am +++ b/src/context/Makefile.am @@ -1,50 +1,40 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ -include $(top_srcdir)/common.mk +include ${top_srcdir}/common.mk bin_PROGRAMS = SPELL-Context SPELL_Context_SOURCES = src/SPELLcontextMain.C -SPELL_Context_LDFLAGS = -lxerces-c -lpthread -lrt -lutil -ldl -lz -lcrypto $(AM_LDFLAGS) - -SPELL_Context_LDADD = ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL.la \ - ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC.la \ - ${top_builddir}/lib/SPELL_WS/libSPELL_WS.la \ - ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN.la \ - ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP.la \ - ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG.la \ - ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD.la \ - ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC.la \ - ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF.la \ - ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA.la \ - ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB.la \ - ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS.la \ - ${top_builddir}/lib/SPELL_PRC/libSPELL_PRC.la \ - ${top_builddir}/lib/SPELL_CTX/libSPELL_CTX.la +SPELL_Context_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} +SPELL_Context_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} +SPELL_Context_LDADD = ${top_builddir}/lib/SPELL_CTX/libSPELL_CTX_v2.la \ + ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v2.la \ + ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \ + ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \ + ${top_builddir}/lib/SPELL_PRC/libSPELL_PRC_v2.la \ + ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \ + ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \ + ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \ + ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la diff --git a/src/context/src/SPELLcontextMain.C b/src/context/src/SPELLcontextMain.C index 7c2b300..c8e7662 100644 --- a/src/context/src/SPELLcontextMain.C +++ b/src/context/src/SPELLcontextMain.C @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL context main program // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -33,6 +33,12 @@ #include "SPELL_UTIL/SPELLerror.H" // Local includes ---------------------------------------------------------- #include "SPELL_CTX/SPELLcontext.H" +#ifdef WITH_KUBERNETES +#include +#endif +#ifdef WITH_BACKTRACE +#include +#endif // GLOBALS /////////////////////////////////////////////////////////////////// @@ -45,7 +51,6 @@ static std::string context = ""; // For POST // STATIC //////////////////////////////////////////////////////////////////// - //============================================================================ // Show usage //============================================================================ @@ -116,6 +121,13 @@ int parseArgs( int argc, char** argv ) //============================================================================ int main( int argc, char** argv ) { + #ifdef WITH_KUBERNETES + prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); + #endif + #ifdef WITH_BACKTRACE + backward::SignalHandling sh; + std::cout << "Singal Handlers loaded: " << sh.loaded() << std::endl; + #endif if ( parseArgs(argc,argv) != 0 ) return 1; // The time identifier is used for unique log file names diff --git a/src/executor/Makefile.am b/src/executor/Makefile.am index 1193feb..82ed20b 100644 --- a/src/executor/Makefile.am +++ b/src/executor/Makefile.am @@ -1,48 +1,61 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### - -include $(top_srcdir)/common.mk - -bin_PROGRAMS = SPELL-Executor +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +include ${top_srcdir}/common.mk + +bin_PROGRAMS = SPELL-Executor SPELL-Executor_v3 + +SPELL_Executor_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +SPELL_Executor_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} SPELL_Executor_SOURCES = src/SPELLexecutorMain.C -SPELL_Executor_LDFLAGS = -lxerces-c -lpthread -lrt -lutil -ldl -lz -lcrypto $(AM_LDFLAGS) +SPELL_Executor_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v2.la \ + ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v2.la \ + ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v2.la \ + ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v2.la \ + ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \ + ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v2.la \ + ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \ + ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \ + ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \ + ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \ + ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la + +SPELL_Executor_v3_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} -SPELL_Executor_LDADD = ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL.la \ - ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC.la \ - ${top_builddir}/lib/SPELL_WS/libSPELL_WS.la \ - ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN.la \ - ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP.la \ - ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG.la \ - ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD.la \ - ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC.la \ - ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA.la \ - ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB.la \ - ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS.la \ - ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF.la +SPELL_Executor_v3_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} +SPELL_Executor_v3_SOURCES = src/SPELLexecutorMain.C +SPELL_Executor_v3_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v3.la \ + ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v3.la \ + ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v3.la \ + ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v3.la \ + ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v3.la \ + ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v3.la \ + ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v3.la \ + ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v3.la \ + ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v3.la \ + ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v3.la \ + ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v3.la + \ No newline at end of file diff --git a/src/executor/src/SPELLexecutorMain.C b/src/executor/src/SPELLexecutorMain.C index 27bfd0c..e3ad630 100644 --- a/src/executor/src/SPELLexecutorMain.C +++ b/src/executor/src/SPELLexecutorMain.C @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL executor main program // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -34,7 +34,12 @@ #include "SPELL_EXC/SPELLinterpreter.H" #include "SPELL_CIFS/SPELLserverCif.H" #include "SPELL_UTIL/SPELLpythonHelper.H" - +#ifdef WITH_KUBERNETES +#include +#endif +#ifdef WITH_BACKTRACE +#include +#endif // GLOBALS /////////////////////////////////////////////////////////////////// // Initialization/configuration variables @@ -48,6 +53,7 @@ static std::string procId = ""; static std::string persis = ""; static std::string timeId = ""; + // STATIC //////////////////////////////////////////////////////////////////// //============================================================================ @@ -140,8 +146,15 @@ int parseArgs( int argc, char** argv ) //============================================================================ int main( int argc, char** argv ) { + #ifdef WITH_KUBERNETES + prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); + #endif + #ifdef WITH_BACKTRACE + backward::SignalHandling sh; + std::cout << "Singal Handlers loaded: " << sh.loaded() << std::endl; + #endif if ( parseArgs(argc,argv) != 0 ) return 1; - + // Create an instance of the interpreter. SPELLinterpreter& interp = SPELLinterpreter::instance(); @@ -154,10 +167,6 @@ int main( int argc, char** argv ) // Setup the logging capabilities SPELLlog::instance().setLogFile("_Executor_" + procId, timeId); -#ifdef WITH_DEBUG - LOG_ENABLE -#endif - // Configuration of the interpreter SPELLinterpreterConfig config; config.warmstart = (warm == 1); // Enable warm-start and error recovery capabilities diff --git a/src/executorcmd/Makefile.am b/src/executorcmd/Makefile.am index 0ff57c2..d53a87d 100644 --- a/src/executorcmd/Makefile.am +++ b/src/executorcmd/Makefile.am @@ -1,49 +1,65 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Mar 17, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### - -include $(top_srcdir)/common.mk - -bin_PROGRAMS = SPELL-ExecutorCmd +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +include ${top_srcdir}/common.mk + +bin_PROGRAMS = SPELL-ExecutorCmd SPELL-ExecutorCmd_v3 SPELL_ExecutorCmd_SOURCES = src/SPELLexecutorMain.C -SPELL_ExecutorCmd_LDFLAGS = -lxerces-c -lpthread -lrt -lncurses -lmenu -lutil -ldl -lz -lcrypto $(AM_LDFLAGS) +SPELL_ExecutorCmd_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +SPELL_ExecutorCmd_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu + +SPELL_ExecutorCmd_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v2.la \ + ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v2.la \ + ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v2.la \ + ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v2.la \ + ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v2.la \ + ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v2.la \ + ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \ + ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v2.la \ + ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \ + ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \ + ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \ + ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \ + ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la + +SPELL_ExecutorCmd_v3_SOURCES = src/SPELLexecutorMain.C -SPELL_ExecutorCmd_LDADD = ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL.la \ - ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC.la \ - ${top_builddir}/lib/SPELL_WS/libSPELL_WS.la \ - ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN.la \ - ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP.la \ - ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG.la \ - ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD.la \ - ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC.la \ - ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC.la \ - ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA.la \ - ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB.la \ - ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS.la \ - ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF.la +SPELL_ExecutorCmd_v3_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} +SPELL_ExecutorCmd_v3_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu +SPELL_ExecutorCmd_v3_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v3.la \ + ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v3.la \ + ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v3.la \ + ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v3.la \ + ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v3.la \ + ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v3.la \ + ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v3.la \ + ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v3.la \ + ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v3.la \ + ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v3.la \ + ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v3.la \ + ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v3.la \ + ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v3.la + \ No newline at end of file diff --git a/src/executorcmd/src/SPELLexecutorMain.C b/src/executorcmd/src/SPELLexecutorMain.C index 705ddda..dff2b56 100644 --- a/src/executorcmd/src/SPELLexecutorMain.C +++ b/src/executorcmd/src/SPELLexecutorMain.C @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL command line executor main program // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -35,8 +35,9 @@ #include "SPELL_EXC/SPELLinterpreter.H" #include "SPELL_CIFC/SPELLstandaloneCif.H" #include "SPELL_CIFC/SPELLautomaticCif.H" - - +#ifdef WITH_BACKTRACE +#include +#endif // GLOBALS /////////////////////////////////////////////////////////////////// // Initialization/configuration variables @@ -54,7 +55,6 @@ static std::string arguments = ""; // STATIC //////////////////////////////////////////////////////////////////// - //============================================================================ // Show usage //============================================================================ @@ -156,6 +156,10 @@ int parseArgs( int argc, char** argv ) //============================================================================ int main( int argc, char** argv ) { + #ifdef WITH_BACKTRACE + backward::SignalHandling sh; + std::cout << "Singal Handlers loaded: " << sh.loaded() << std::endl; + #endif if ( parseArgs(argc,argv) != 0 ) return 1; // Show the environment configuration diff --git a/src/listener/Makefile.am b/src/listener/Makefile.am index 693b505..3d1bca6 100644 --- a/src/listener/Makefile.am +++ b/src/listener/Makefile.am @@ -1,43 +1,38 @@ -################################################################################### -## FILE : Makefile.am -## DATE : Jul 26, 2011 -## PROJECT : SPELL -## DESCRIPTION: Automake rules -## -------------------------------------------------------------------------------- -## -## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. -## -## This file is part of SPELL. -## -## SPELL is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## SPELL is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with SPELL. If not, see . -## -################################################################################### +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ +AUTOMAKE_OPTIONS = subdir-objects -include $(top_srcdir)/common.mk +include ${top_srcdir}/common.mk bin_PROGRAMS = SPELL-Listener SPELL_Listener_SOURCES = src/SPELLlistenerMain.C -SPELL_Listener_LDFLAGS = -lxerces-c -lpthread -lrt -lutil -ldl -lz -lcrypto $(AM_LDFLAGS) - -SPELL_Listener_LDADD = \ - ${top_builddir}/lib/SPELL_LST/libSPELL_LST.la \ - ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC.la \ - ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL.la \ - ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN.la \ - ${top_builddir}/lib/SPELL_PRC/libSPELL_PRC.la \ - ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG.la +SPELL_Listener_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} +SPELL_Listener_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} +SPELL_Listener_LDADD = ${top_builddir}/lib/SPELL_LST/libSPELL_LST_v2.la \ + ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \ + ${top_builddir}/lib/SPELL_PRC/libSPELL_PRC_v2.la \ + ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \ + ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \ + ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la diff --git a/src/listener/src/SPELLlistenerMain.C b/src/listener/src/SPELLlistenerMain.C index fd2ea41..87aa320 100644 --- a/src/listener/src/SPELLlistenerMain.C +++ b/src/listener/src/SPELLlistenerMain.C @@ -5,7 +5,7 @@ // DESCRIPTION: SPELL listener main program // -------------------------------------------------------------------------------- // -// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L. +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. // // This file is part of SPELL. // @@ -32,6 +32,12 @@ #include "SPELL_LST/SPELLlistener.H" // System includes ----------------------------------------------------------- #include +#ifdef WITH_KUBERNETES +#include +#endif +#ifdef WITH_BACKTRACE +#include +#endif // Local includes ------------------------------------------------------------ // GLOBALS /////////////////////////////////////////////////////////////////// @@ -116,9 +122,9 @@ int parseArgs( int argc, char** argv ) //============================================================================ void signal_handler(int signum) { - if (signum < NumSignals) + if ((unsigned)signum < NumSignals) { - std::cerr << "[***] Captured signal " << signalList[signum].name << std::endl; + std::cerr << "[***] Captured signal " << signum << " "<< signalList[signum].name << std::endl; } else { @@ -162,6 +168,13 @@ void setupSignals() //============================================================================ int main( int argc, char** argv ) { + #ifdef WITH_KUBERNETES + prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); + #endif + #ifdef WITH_BACKTRACE + backward::SignalHandling sh; + std::cout << "Singal Handlers loaded: " << sh.loaded() << std::endl; + #endif std::string timeId = SPELLutils::fileTimestamp(); SPELLlog::instance().setLogFile("_Listener", timeId); diff --git a/src/ping/Makefile.am b/src/ping/Makefile.am new file mode 100644 index 0000000..f3ec786 --- /dev/null +++ b/src/ping/Makefile.am @@ -0,0 +1,44 @@ +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + +include ${top_srcdir}/common.mk + +bin_PROGRAMS = SPELL-Ping + +SPELL_Ping_SOURCES = src/SPELLPing.C + +SPELL_Ping_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +SPELL_Ping_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu + +SPELL_Ping_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v2.la \ + ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v2.la \ + ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v2.la \ + ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v2.la \ + ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v2.la \ + ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v2.la \ + ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \ + ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v2.la \ + ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \ + ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \ + ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \ + ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \ + ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la diff --git a/src/ping/src/SPELLPing.C b/src/ping/src/SPELLPing.C new file mode 100644 index 0000000..6d7cb9e --- /dev/null +++ b/src/ping/src/SPELLPing.C @@ -0,0 +1,133 @@ +// ################################################################################ +// FILE : SPELLPing.C +// DATE : Mar 18, 2011 +// PROJECT : SPELL +// DESCRIPTION: SPELL command line executor main program +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE ////////////////////////////////////////////////////////// +// System includes ----------------------------------------------------------- +// Local includes ------------------------------------------------------------ +// Project includes ---------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" +#include "SPELL_UTIL/SPELLpythonHelper.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLutils.H" +#include "SPELL_WRP/SPELLconstants.H" +#include "SPELL_IPC/SPELLipcClientInterface.H" +#include "SPELL_IPC/SPELLipc.H" +#include "SPELL_IPC/SPELLipc_Context.H" + +// GLOBALS /////////////////////////////////////////////////////////////////// + +// Initialization/configuration variables + +static int logging = 0; +static std::string context = ""; +static std::string configFile = ""; +static int port = 19888; + +// STATIC //////////////////////////////////////////////////////////////////// + + +//============================================================================ +// Show usage +//============================================================================ +void usage( char** argv ) +{ + std::cerr << "Syntax:" << std::endl; + std::cerr << " " << argv[0] << " -p [-d]" << std::endl; + std::cerr << std::endl; + std::cerr << " - p : context port" << std::endl; + std::cerr << " - d : enable debug traces" << std::endl; + std::cerr << std::endl; +} + +//============================================================================ +// Parse program arguments +//============================================================================ +int parseArgs( int argc, char** argv ) +{ + int code; + while( ( code = getopt(argc, argv, "dp:n:c:")) != -1) + { + switch(code) + { + case 'd': + logging = 1; + break; + case 'p': + port = atoi(optarg); + std::cout << "* Port " << port << std::endl; + break; + } + } + + return 0; +} + +//============================================================================ +// MAIN PROGRAM +//============================================================================ +int main( int argc, char** argv ) +{ + if ( parseArgs(argc,argv) != 0 ) return 1; + + // Show the environment configuration + SPELLutils::showEnvironment(); + // The time identifier is used to create unique file names + + SPELLipcClientInterface* ipc = new SPELLipcClientInterface("Ping","localhost",port); + + std::cout << "SPELL-Ping ### Connecting to Context" << std::endl; + ipc->connect(); + bool connectSuccessful = ipc->isConnected(); + std::cout << "SPELL-Ping ### Connection Successful: " << (connectSuccessful ? "yes" : "no") << std::endl; + if (connectSuccessful) { + SPELLipcMessage* msg = new SPELLipcMessage(ContextMessages::REQ_CURRENT_TIME); + msg->setType(MSG_TYPE_REQUEST); + msg->setSender("PING"); + msg->setReceiver("CTX"); + std::cout << "SPELL-Ping ### Sending Ping." << std::endl; + SPELLipcMessage answer = ipc->sendRequest(*msg,5000); + std::cout << "SPELL-Ping ### Ping was sent." << std::endl; + bool errorFound = answer.hasField(MessageField::FIELD_FATAL); + + std::cout << "SPELL-Ping ### Sending EOC" << std::endl; + SPELLipcMessage* eoc = new SPELLipcMessage("EOC"); + eoc->setType( MSG_TYPE_EOC ); + + ipc->sendMessage(*eoc); + + ipc->disconnect(); + if (errorFound){ + std::cout << "SPELL-Ping ### Ping not successful." << std::endl; + return -2; + } else { + std::cout << "SPELL-Ping ### Ping successful." << std::endl; + return 0; + } + } else { + std::cout << "SPELL-Ping ### Connection failed." << std::endl; + return -1; + } +} diff --git a/src/service/Makefile.am b/src/service/Makefile.am new file mode 100644 index 0000000..406575d --- /dev/null +++ b/src/service/Makefile.am @@ -0,0 +1,65 @@ +################################################################################ +# +# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +# +# This file is part of SPELL. +# +# SPELL is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SPELL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SPELL. If not, see . +# +################################################################################ + + +include ${top_srcdir}/common.mk + +bin_PROGRAMS = SPELL-Service SPELL-Service_v3 + +SPELL_Service_SOURCES = src/SPELLserviceMain.C + +SPELL_Service_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} + +SPELL_Service_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu + +SPELL_Service_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v2.la \ + ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v2.la \ + ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v2.la \ + ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v2.la \ + ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v2.la \ + ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v2.la \ + ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \ + ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v2.la \ + ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \ + ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \ + ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \ + ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \ + ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la + +SPELL_Service_v3_SOURCES = src/SPELLserviceMain.C + +SPELL_Service_v3_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} + +SPELL_Service_v3_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu + +SPELL_Service_v3_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v3.la \ + ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v3.la \ + ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v3.la \ + ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v3.la \ + ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v3.la \ + ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v3.la \ + ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v3.la \ + ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v3.la \ + ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v3.la \ + ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v3.la \ + ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v3.la \ + ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v3.la \ + ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v3.la diff --git a/src/service/src/SPELLserviceMain.C b/src/service/src/SPELLserviceMain.C new file mode 100644 index 0000000..7b0cec8 --- /dev/null +++ b/src/service/src/SPELLserviceMain.C @@ -0,0 +1,213 @@ +// ################################################################################ +// FILE : SPELLserviceMain.C +// DATE : Mar 18, 2011 +// PROJECT : SPELL +// DESCRIPTION: SPELL command line executor main program +// -------------------------------------------------------------------------------- +// +// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L. +// +// This file is part of SPELL. +// +// SPELL is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SPELL is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SPELL. If not, see . +// +// ################################################################################ + +// FILES TO INCLUDE ////////////////////////////////////////////////////////// +// System includes ----------------------------------------------------------- +// Local includes ------------------------------------------------------------ +// Project includes ---------------------------------------------------------- +#include "SPELL_UTIL/SPELLbase.H" +#include "SPELL_UTIL/SPELLpythonHelper.H" +#include "SPELL_UTIL/SPELLlog.H" +#include "SPELL_UTIL/SPELLutils.H" +#include "SPELL_EXC/SPELLserviceInterpreter.H" +#include "SPELL_CIFS/SPELLserverCif.H" +#ifdef WITH_KUBERNETES +#include +#endif +#ifdef WITH_BACKTRACE +#include +#endif +// GLOBALS /////////////////////////////////////////////////////////////////// + +// Initialization/configuration variables +static int warm = 0; +static int recover = 0; +static int script = 0; +static int interactive = 0; +static int logging = 0; +static int port = 0; +static std::string context = ""; +static std::string configFile = ""; +static std::string procId = ""; +static std::string persis = ""; +static std::string promptFile = ""; +static std::string arguments = ""; + +// STATIC //////////////////////////////////////////////////////////////////// + + +//============================================================================ +// Show usage +//============================================================================ +void usage( char** argv ) +{ + std::cerr << "Syntax:" << std::endl; + std::cerr << " " << argv[0] << " {-p |-f