summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRamón M. Gómez <ramongomez@us.es>2019-04-09 11:20:15 +0200
committerRamón M. Gómez <ramongomez@us.es>2019-04-09 11:20:15 +0200
commitce738c82052cda8f576c1227b89efcee04c05d56 (patch)
treeb6a7fc8e6588b71dc1e1bec4a7037cda8773b0af
parent6e4ee7974fe1787ae955543f8a73f85595ff031a (diff)
parent18789001de4763b88ac61eaea8272d5228d85d64 (diff)
#761 #750: Merge branch {{{ogagent-oglive}}} into {{{webconsole3}}}.
-rw-r--r--admin/Sources/Clients/ogagent/oglive/Makefile57
-rwxr-xr-xadmin/Sources/Clients/ogagent/oglive/build-package.sh7
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/changelog6
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/compat1
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/control15
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/copyright26
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/docs1
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.links2
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postinst21
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postinst.debhelper5
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postrm10
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postrm.debhelper12
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.substvars2
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/ogagent.init23
-rwxr-xr-xadmin/Sources/Clients/ogagent/oglive/debian/rules44
-rw-r--r--admin/Sources/Clients/ogagent/oglive/debian/source/format1
-rw-r--r--admin/Sources/Clients/ogagent/oglive/readme.txt3
-rw-r--r--admin/Sources/Clients/ogagent/oglive/scripts/OGAgentTool6
-rw-r--r--admin/Sources/Clients/ogagent/oglive/scripts/OGAgentTool-startup10
-rw-r--r--admin/Sources/Clients/ogagent/oglive/scripts/ogagent6
-rw-r--r--admin/Sources/Clients/ogagent/src/opengnsys/linux/operations.py12
-rw-r--r--admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py261
-rw-r--r--admin/Sources/Clients/ogagent/src/opengnsys/oglive/__init__.py32
-rw-r--r--admin/Sources/Clients/ogagent/src/opengnsys/oglive/daemon.py182
-rw-r--r--admin/Sources/Clients/ogagent/src/opengnsys/oglive/operations.py236
-rw-r--r--admin/Sources/Clients/ogagent/src/opengnsys/operations.py27
-rw-r--r--admin/Sources/Clients/ogagent/src/setup.py2
-rw-r--r--admin/WebConsole/rest/ogagent.php35
-rw-r--r--installer/vagrant/Vagrantfile-ogagent-vbox2
29 files changed, 989 insertions, 58 deletions
diff --git a/admin/Sources/Clients/ogagent/oglive/Makefile b/admin/Sources/Clients/ogagent/oglive/Makefile
new file mode 100644
index 00000000..832e2dc7
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/Makefile
@@ -0,0 +1,57 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Directories
+SOURCEDIR := ../src
+LIBDIR := $(DESTDIR)/usr/share/OGAgent
+BINDIR := $(DESTDIR)/usr/bin
+SBINDIR = $(DESTDIR)/usr/sbin
+APPSDIR := $(DESTDIR)/usr/share/applications
+CFGDIR := $(DESTDIR)/etc/ogagent
+INITDIR := $(DESTDIR)/etc/init.d
+
+PYC := $(shell find $(SOURCEDIR) -name '*.py[co]')
+CACHES := $(shell find $(SOURCEDIR) -name '__pycache__')
+
+clean:
+ rm -rf $(PYC) $(CACHES) $(DESTDIR)
+install-ogagent:
+ rm -rf $(DESTDIR)
+ mkdir -p $(LIBDIR)
+ mkdir -p $(BINDIR)
+ mkdir -p $(SBINDIR)
+ mkdir -p $(APPSDIR)
+ mkdir -p $(CFGDIR)
+
+ mkdir $(LIBDIR)/img
+
+ # Cleans up .pyc and cache folders
+ rm -f $(PYC) $(CACHES)
+
+ cp -r $(SOURCEDIR)/opengnsys $(LIBDIR)/opengnsys
+ cp -r $(SOURCEDIR)/cfg $(LIBDIR)/cfg
+
+ # scripts
+ cp scripts/ogagent $(BINDIR)
+ cp scripts/OGAgentTool-startup $(BINDIR)
+ cp scripts/OGAgentTool $(BINDIR)
+
+ # Fix permissions
+ chmod 755 $(BINDIR)/ogagent
+ chmod 755 $(BINDIR)/OGAgentTool-startup
+ chmod 600 $(LIBDIR)/cfg/ogagent.cfg
+
+ # If for red hat based, copy init.d
+ifeq ($(DISTRO),rh)
+ mkdir -p $(INITDIR)
+ cp debian/ogagent.init $(INITDIR)/ogagent
+ chmod +x $(INITDIR)/ogagent
+ ln -fs /usr/share/OGAgent/cfg/ogagent.cfg $(CFGDIR)
+ ln -fs /usr/share/OGAgent/cfg/ogclient.cfg $(CFGDIR)
+endif
+
+ # chmod 0755 $(BINDIR)/ogagent
+uninstall:
+ rm -rf $(LIBDIR)
+ # rm -f $(BINDIR)/ogagent
+ rm -rf $(CFGDIR)
diff --git a/admin/Sources/Clients/ogagent/oglive/build-package.sh b/admin/Sources/Clients/ogagent/oglive/build-package.sh
new file mode 100755
index 00000000..c0e03c5f
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/build-package.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+cd $(dirname "$0")
+
+# Build package
+dpkg-buildpackage -b -d
+
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/changelog b/admin/Sources/Clients/ogagent/oglive/debian/changelog
new file mode 100644
index 00000000..57a05aba
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/changelog
@@ -0,0 +1,6 @@
+ogagent-oglive (1.1.1) unstable; urgency=medium
+
+ * Initial release.
+
+ -- Ramón M. Gómez <ramongomez@us.es> Mon, 18 Jun 2018 13:00:00 +0200
+
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/compat b/admin/Sources/Clients/ogagent/oglive/debian/compat
new file mode 100644
index 00000000..f11c82a4
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/compat
@@ -0,0 +1 @@
+9 \ No newline at end of file
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/control b/admin/Sources/Clients/ogagent/oglive/debian/control
new file mode 100644
index 00000000..374bc554
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/control
@@ -0,0 +1,15 @@
+Source: ogagent-oglive
+Section: admin
+Priority: optional
+Maintainer: Ramón M. Gómez <ramongomez@us.es>
+Build-Depends: debhelper (>= 7), po-debconf
+Standards-Version: 3.9.2
+Homepage: https://opengnsys.es
+
+Package: ogagent-oglive
+Section: admin
+Priority: optional
+Architecture: all
+Depends: python-requests (>=0.8.2), python-six(>=1.1), python-prctl(>=1.1.1), python (>=2.7), libxss1, ${misc:Depends}
+Description: OpenGnsys Agent for ogLive client
+ This package provides the required components to allow this machine to work on an environment managed by OpenGnsys.
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/copyright b/admin/Sources/Clients/ogagent/oglive/debian/copyright
new file mode 100644
index 00000000..7b6ef31b
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/copyright
@@ -0,0 +1,26 @@
+Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
+Name: ogagent
+Maintainer: Ramón M. Gómez
+Source: https://opengnsys.es
+
+Copyright: 2014 Virtual Cable S.L.U.
+License: BSD-3-clause
+
+License: GPL-2+
+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 2 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, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+.
+On Debian systems, the full text of the GNU General Public
+License version 2 can be found in the file
+`/usr/share/common-licenses/GPL-2'.
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/docs b/admin/Sources/Clients/ogagent/oglive/debian/docs
new file mode 100644
index 00000000..b2b2a781
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/docs
@@ -0,0 +1 @@
+readme.txt
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.links b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.links
new file mode 100644
index 00000000..9b970d7b
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.links
@@ -0,0 +1,2 @@
+/usr/share/OGAgent/cfg/ogagent.cfg /etc/ogagent/ogagent.cfg
+/usr/share/OGAgent/cfg/ogclient.cfg /etc/ogagent/ogclient.cfg
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postinst b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postinst
new file mode 100644
index 00000000..b59cfa6f
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postinst
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+. /usr/share/debconf/confmodule
+
+set -e
+case "$1" in
+ configure)
+ chmod 600 /usr/share/OGAgent/cfg/ogagent.cfg
+ ;;
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+#DEBHELPER#
+
+exit 0
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postinst.debhelper b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postinst.debhelper
new file mode 100644
index 00000000..e75924dc
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postinst.debhelper
@@ -0,0 +1,5 @@
+# Automatically added by dh_installinit
+if [ -x "/etc/init.d/ogagent" ]; then
+ update-rc.d ogagent defaults >/dev/null || exit $?
+fi
+# End automatically added section
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postrm b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postrm
new file mode 100644
index 00000000..a46fa487
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postrm
@@ -0,0 +1,10 @@
+#!/bin/sh -e
+
+. /usr/share/debconf/confmodule
+
+set -e
+
+if [ "$1" = "purge" ] ; then
+ rm -rf /usr/share/OGAgent || true > /dev/null 2>&1
+fi
+
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postrm.debhelper b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postrm.debhelper
new file mode 100644
index 00000000..3167f1f8
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.postrm.debhelper
@@ -0,0 +1,12 @@
+# Automatically added by dh_installinit
+if [ "$1" = "purge" ] ; then
+ update-rc.d ogagent remove >/dev/null
+fi
+
+
+# In case this system is running systemd, we make systemd reload the unit files
+# to pick up changes.
+if [ -d /run/systemd/system ] ; then
+ systemctl --system daemon-reload >/dev/null || true
+fi
+# End automatically added section
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.substvars b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.substvars
new file mode 100644
index 00000000..978fc8b5
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/ogagent-oglive.substvars
@@ -0,0 +1,2 @@
+misc:Depends=
+misc:Pre-Depends=
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/ogagent.init b/admin/Sources/Clients/ogagent/oglive/debian/ogagent.init
new file mode 100644
index 00000000..3eee35c1
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/ogagent.init
@@ -0,0 +1,23 @@
+#!/bin/sh -e
+### BEGIN INIT INFO
+# Provides: ogagent
+# Required-Start: $local_fs $remote_fs $network $syslog $named
+# Required-Stop: $local_fs $remote_fs $network $syslog $named
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: OpenGnsys Agent Service
+### END INIT INFO
+#
+
+# . /lib/lsb/init-functions
+
+case "$1" in
+ start|stop|restart)
+ /usr/bin/ogagent $1
+ ;;
+ force-reload)
+ /usr/bin/ogagent restart
+ ;;
+ *) echo "Usage: $0 {start|stop|restart|force-reload}" >&2; exit 1 ;;
+esac
+
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/rules b/admin/Sources/Clients/ogagent/oglive/debian/rules
new file mode 100755
index 00000000..0a5c3e5c
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/rules
@@ -0,0 +1,44 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ touch configure-stamp
+build: build-arch build-indep
+build-arch: build-stamp
+build-indep: build-stamp
+build-stamp: configure-stamp
+ dh_testdir
+ $(MAKE)
+ touch $@
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+ dh_clean
+install: build
+ dh_testdir
+ dh_testroot
+ dh_prep
+ dh_installdirs
+ $(MAKE) DESTDIR=$(CURDIR)/debian/ogagent-oglive install-ogagent
+binary-arch: build install
+ # emptyness
+binary-indep: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+ dh_installdebconf
+ dh_installinit --no-start
+ dh_python2=python
+ dh_compress
+ dh_link
+ dh_fixperms
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+binary: binary-indep
+.PHONY: build clean binary-indep binary install configure
diff --git a/admin/Sources/Clients/ogagent/oglive/debian/source/format b/admin/Sources/Clients/ogagent/oglive/debian/source/format
new file mode 100644
index 00000000..9f674278
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/debian/source/format
@@ -0,0 +1 @@
+3.0 (native) \ No newline at end of file
diff --git a/admin/Sources/Clients/ogagent/oglive/readme.txt b/admin/Sources/Clients/ogagent/oglive/readme.txt
new file mode 100644
index 00000000..a2771def
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/readme.txt
@@ -0,0 +1,3 @@
+OGAgent is the agent intended for OpengGnsys interaction.
+
+Please, visit https://opengnsys.es for more information
diff --git a/admin/Sources/Clients/ogagent/oglive/scripts/OGAgentTool b/admin/Sources/Clients/ogagent/oglive/scripts/OGAgentTool
new file mode 100644
index 00000000..5b300523
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/scripts/OGAgentTool
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+FOLDER=/usr/share/OGAgent
+
+cd $FOLDER
+python OGAgentUser.py $@
diff --git a/admin/Sources/Clients/ogagent/oglive/scripts/OGAgentTool-startup b/admin/Sources/Clients/ogagent/oglive/scripts/OGAgentTool-startup
new file mode 100644
index 00000000..bb3a848e
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/scripts/OGAgentTool-startup
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# Simple hack to wait for systray to be present
+# Exec tool if not already runned by session manager
+ps -ef | grep "$USER" | grep -v grep | grep -v OGAgentTool-startup | grep 'OGAgentTool' -q
+# If not already running
+if [ $? -eq 1 ]; then
+ sleep 5
+ exec /usr/bin/OGAgentTool
+fi \ No newline at end of file
diff --git a/admin/Sources/Clients/ogagent/oglive/scripts/ogagent b/admin/Sources/Clients/ogagent/oglive/scripts/ogagent
new file mode 100644
index 00000000..1bcc29b0
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/oglive/scripts/ogagent
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+FOLDER=/usr/share/OGAgent
+
+cd $FOLDER
+python -m opengnsys.linux.OGAgentService $@
diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/linux/operations.py b/admin/Sources/Clients/ogagent/src/opengnsys/linux/operations.py
index 0c08f95f..db6ea18c 100644
--- a/admin/Sources/Clients/ogagent/src/opengnsys/linux/operations.py
+++ b/admin/Sources/Clients/ogagent/src/opengnsys/linux/operations.py
@@ -152,11 +152,7 @@ def reboot(flags=0):
import threading
threading._DummyThread._Thread__stop = lambda x: 42
- # Check for OpenGnsys Client or GNU/Linux distribution.
- if os.path.exists('/scripts/oginit'):
- subprocess.call('source /opt/opengnsys/etc/preinit/loadenviron.sh; /opt/opengnsys/scripts/reboot', shell=True)
- else:
- subprocess.call(['/sbin/reboot'])
+ subprocess.call(['/sbin/reboot'])
def poweroff(flags=0):
@@ -168,11 +164,7 @@ def poweroff(flags=0):
import threading
threading._DummyThread._Thread__stop = lambda x: 42
- # Check for OpenGnsys Client or GNU/Linux distribution.
- if os.path.exists('/scripts/oginit'):
- subprocess.call('source /opt/opengnsys/etc/preinit/loadenviron.sh; /opt/opengnsys/scripts/poweroff', shell=True)
- else:
- subprocess.call(['/sbin/poweroff'])
+ subprocess.call(['/sbin/poweroff'])
def logoff():
diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py
index 850dfb0f..d9704259 100644
--- a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py
+++ b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py
@@ -25,31 +25,30 @@
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-'''
+"""
@author: Ramón M. Gómez, ramongomez at us dot es
-'''
+"""
from __future__ import unicode_literals
-import subprocess
-import threading
-import thread
import os
-import platform
-import time
import random
import shutil
import string
+import threading
+import time
import urllib
-from opengnsys.workers import ServerWorker
-from opengnsys import REST, RESTError
+from opengnsys import REST
from opengnsys import operations
from opengnsys.log import logger
from opengnsys.scriptThread import ScriptExecutorThread
+from opengnsys.workers import ServerWorker
+from six.moves.urllib import parse
+
# Error handler decorator.
-def catchBackgroundError(fnc):
+def catch_background_error(fnc):
def wrapper(*args, **kwargs):
this = args[0]
try:
@@ -59,11 +58,39 @@ def catchBackgroundError(fnc):
return wrapper
+def check_locked_partition(sync=False):
+ """
+ Decorator to check if a partition is locked
+ """
+ def outer(fnc):
+ def wrapper(*args, **kwargs):
+ part_id = 'None'
+ try:
+ this, path, get_params, post_params, server = args # @UnusedVariable
+ part_id = post_params['disk'] + post_params['part']
+ if this.locked.get(part_id, False):
+ this.locked[part_id] = True
+ fnc(*args, **kwargs)
+ else:
+ return 'partition locked'
+ except Exception as e:
+ this.locked[part_id] = False
+ return 'error {}'.format(e)
+ finally:
+ if sync is True:
+ this.locked[part_id] = False
+ logger.debug('Lock status: {} {}'.format(fnc, this.locked))
+ return wrapper
+ return outer
+
+
class OpenGnSysWorker(ServerWorker):
name = 'opengnsys'
interface = None # Bound interface for OpenGnsys
+ REST = None # REST object
loggedin = False # User session flag
- locked = {}
+ locked = {} # Locked partitions
+ commands = [] # Running commands
random = None # Random string for secure connections
length = 32 # Random string length
@@ -82,9 +109,13 @@ class OpenGnSysWorker(ServerWorker):
"""
Sends OGAgent activation notification to OpenGnsys server
"""
- self.cmd = None
# Ensure cfg has required configuration variables or an exception will be thrown
- self.REST = REST(self.service.config.get('opengnsys', 'remote'))
+ url = self.service.config.get('opengnsys', 'remote')
+ if operations.os_type == 'ogLive' and 'oglive' in os.environ:
+ # Replacing server IP if its running on ogLive clinet
+ logger.debug('Activating on ogLive client, new server is {}'.format(os.environ['oglive']))
+ url = parse.urlsplit(url)._replace(netloc=os.environ['oglive']).geturl()
+ self.REST = REST(url)
# Get network interfaces until they are active or timeout (5 minutes)
for t in range(0, 300):
try:
@@ -119,8 +150,13 @@ class OpenGnSysWorker(ServerWorker):
try:
try:
self.REST.sendMessage('ogagent/started', {'mac': self.interface.mac, 'ip': self.interface.ip,
- 'secret': self.random, 'ostype': operations.osType,
- 'osversion': operations.osVersion})
+ 'secret': self.random, 'ostype': operations.os_type,
+ 'osversion': operations.os_version})
+ # New web compatibility.
+ #self.REST.sendMessage('clients/statuses', {'mac': self.interface.mac, 'ip': self.interface.ip,
+ # 'secret': self.random, 'ostype': operations.os_type,
+ # 'osversion': operations.os_version,
+ # 'status': operations.os_type.lower()})
except:
# Trying to initialize on alternative server, if defined
# (used in "exam mode" from the University of Seville)
@@ -128,6 +164,11 @@ class OpenGnSysWorker(ServerWorker):
self.REST.sendMessage('ogagent/started', {'mac': self.interface.mac, 'ip': self.interface.ip,
'secret': self.random, 'ostype': operations.osType,
'osversion': operations.osVersion, 'alt_url': True})
+ # New web compatibility.
+ #self.REST.sendMessage('clients/statuses', {'mac': self.interface.mac, 'ip': self.interface.ip,
+ # 'secret': self.random, 'ostype': operations.os_type,
+ # 'osversion': operations.os_version,
+ # 'status': operations.os_type.lower()})
except:
logger.error('Initialization error')
@@ -136,8 +177,11 @@ class OpenGnSysWorker(ServerWorker):
Sends OGAgent stopping notification to OpenGnsys server
"""
logger.debug('onDeactivation')
- self.REST.sendMessage('ogagent/stopped', {'mac': self.interface.mac, 'ip': self.interface.ip,
- 'ostype': operations.osType, 'osversion': operations.osVersion})
+ #self.REST.sendMessage('ogagent/stopped', {'mac': self.interface.mac, 'ip': self.interface.ip,
+ # 'ostype': operations.os_type, 'osversion': operations.os_version})
+ self.REST.sendMessage('clients/statuses', {'mac': self.interface.mac, 'ip': self.interface.ip,
+ 'ostype': operations.os_type, 'osversion': operations.os_version
+ 'status': 'off'})
def processClientMessage(self, message, data):
logger.debug('Got OpenGnsys message from client: {}, data {}'.format(message, data))
@@ -150,7 +194,7 @@ class OpenGnSysWorker(ServerWorker):
logger.debug('Received login for {} with language {}'.format(user, language))
self.loggedin = True
self.REST.sendMessage('ogagent/loggedin', {'ip': self.interface.ip, 'user': user, 'language': language,
- 'ostype': operations.osType, 'osversion': operations.osVersion})
+ 'ostype': operations.os_type, 'osversion': operations.os_version})
def onLogout(self, user):
"""
@@ -190,25 +234,16 @@ class OpenGnSysWorker(ServerWorker):
def process_status(self, path, getParams, postParams, server):
"""
- Returns client status.
+ Returns client status (OS type and login status).
"""
- res = {'status': '', 'loggedin': self.loggedin}
- if platform.system() == 'Linux': # GNU/Linux
- # Check if it's OpenGnsys Client.
- if os.path.exists('/scripts/oginit'):
- # Check if OpenGnsys Client is busy.
- if self.locked:
- res['status'] = 'BSY'
- else:
- res['status'] = 'OPG'
- else:
- # Check if there is an active session.
- res['status'] = 'LNX'
- elif platform.system() == 'Windows': # Windows
- # Check if there is an active session.
- res['status'] = 'WIN'
- elif platform.system() == 'Darwin': # Mac OS X ??
- res['status'] = 'OSX'
+ res = {'loggedin': self.loggedin}
+ try:
+ res['status'] = operations.os_type.lower()
+ except KeyError:
+ res['status'] = ''
+ # Check if OpenGnsys Client is busy
+ if res['status'] == 'oglive' and self.locked:
+ res['status'] = 'busy'
return res
def process_reboot(self, path, getParams, postParams, server):
@@ -277,3 +312,157 @@ class OpenGnSysWorker(ServerWorker):
def process_client_popup(self, params):
self.REST.sendMessage('popup_done', params)
+
+ def process_config(self, path, get_params, post_params, server):
+ """
+ Returns client configuration
+ :param path:
+ :param get_params:
+ :param post_params:
+ :param server:
+ :return: object
+ """
+ serialno = '' # Serial number
+ storage = [] # Storage configuration
+ warnings = 0 # Number of warnings
+ logger.debug('Received getconfig operation')
+ self.checkSecret(server)
+ # Processing data
+ for row in operations.get_configuration().split(';'):
+ cols = row.split(':')
+ if len(cols) == 1:
+ if cols[0] != '':
+ # Serial number
+ serialno = cols[0]
+ else:
+ # Skip blank rows
+ pass
+ elif len(cols) == 7:
+ disk, npart, tpart, fs, opsys, size, usage = cols
+ try:
+ if int(npart) == 0:
+ # Disk information
+ storage.append({'disk': int(disk), 'parttable': int(tpart), 'size': int(size)})
+ else:
+ # Partition information
+ storage.append({'disk': int(disk), 'partition': int(npart), 'parttype': tpart,
+ 'filesystem': fs, 'operatingsystem': opsys, 'size': int(size),
+ 'usage': int(usage)})
+ except ValueError:
+ logger.warn('Configuration parameter error: {}'.format(cols))
+ warnings += 1
+ else:
+ # Logging warnings
+ logger.warn('Configuration data error: {}'.format(cols))
+ warnings += 1
+ # Returning configuration data and count of warnings
+ return {'serialno': serialno, 'storage': storage, 'warnings': warnings}
+
+ def task_command(self, code, route, op_id):
+ """
+ Task to execute a command
+ :param code: Code to execute
+ :param route: server callback REST route to return results
+ :param op_id: operation id.
+ """
+ # Executing command
+ (stat, out, err) = operations.exec_command(code)
+ # Removing command from the list
+ for c in self.commands:
+ if c.getName() == op_id:
+ self.commands.remove(c)
+ # Sending results
+ self.REST.sendMessage(route, {'client': self.interface.ip, 'trace': op_id, 'status': stat, 'output': out,
+ 'error': err})
+
+ def process_command(self, path, get_params, post_params, server):
+ """
+ Launches a thread to executing a command
+ :param path: ignored
+ :param get_params: ignored
+ :param post_params: object with format:
+ id: operation id.
+ script: command code
+ redirect_url: callback REST route
+ :param server: headers data
+ :rtype: object with launching status
+ """
+ logger.debug('Received command operation with params: {}'.format(post_params))
+ self.checkSecret(server)
+ # Processing data
+ try:
+ script = post_params.get('script')
+ op_id = post_params.get('id')
+ route = post_params.get('redirect_url')
+ # Checking if the thread id. exists
+ for c in self.commands:
+ if c.getName() == str(op_id):
+ raise Exception('Task id. already exists: {}'.format(op_id))
+ # Launching a new thread
+ thr = threading.Thread(name=op_id, target=self.task_command, args=(script, route, op_id))
+ thr.start()
+ self.commands.append(thr)
+ except Exception as e:
+ logger.error('Got exception {}'.format(e))
+ return {'error': e}
+ return {'op': 'launched'}
+
+ def process_execinfo(self, path, get_params, post_params, server):
+ """
+ Returns running commands information
+ :param path:
+ :param get_params:
+ :param post_params:
+ :param server:
+ :return: object
+ """
+ data = []
+ logger.debug('Received execinfo operation')
+ self.checkSecret(server)
+ # Returning the arguments of all running threads
+ for c in self.commands:
+ if c.is_alive():
+ data.append(c.__dict__['_Thread__args'])
+ return data
+
+ def process_stopcmd(self, path, get_params, post_params, server):
+ logger.debug('Received stopcmd operation with params {}:'.format(post_params))
+ self.checkSecret(server)
+ op_id = post_params.get('trace')
+ for c in self.commands:
+ if c.is_alive() and c.getName() == str(op_id):
+ c._Thread__stop()
+ return {"stopped": op_id}
+ return {}
+
+ def process_hardware(self, path, get_params, post_params, server):
+ """
+ Returns client's hardware profile
+ :param path:
+ :param get_params:
+ :param post_params:
+ :param server:
+ """
+ data = []
+ logger.debug('Received hardware operation')
+ self.checkSecret(server)
+ # Processing data
+ try:
+ for comp in operations.get_hardware():
+ data.append({'component': comp.split('=')[0], 'value': comp.split('=')[1]})
+ except:
+ pass
+ # Return list of hardware components
+ return data
+
+ def process_software(self, path, get_params, post_params, server):
+ """
+ Returns software profile installed on an operating system
+ :param path:
+ :param get_params:
+ :param post_params:
+ :param server:
+ :return:
+ """
+ logger.debug('Received software operation with params: {}'.format(post_params))
+ return operations.get_software(post_params.get('disk'), post_params.get('part'))
diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/oglive/__init__.py b/admin/Sources/Clients/ogagent/src/opengnsys/oglive/__init__.py
new file mode 100644
index 00000000..3a98c780
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/src/opengnsys/oglive/__init__.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2014 Virtual Cable S.L.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Virtual Cable S.L. nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''
+@author: Adolfo Gómez, dkmaster at dkmon dot com
+'''
+from __future__ import unicode_literals
diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/oglive/daemon.py b/admin/Sources/Clients/ogagent/src/opengnsys/oglive/daemon.py
new file mode 100644
index 00000000..3753808a
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/src/opengnsys/oglive/daemon.py
@@ -0,0 +1,182 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2014 Virtual Cable S.L.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Virtual Cable S.L. nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+'''
+@author: : http://www.jejik.com/authors/sander_marechal/
+@see: : http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
+'''
+
+from __future__ import unicode_literals
+import sys
+import os
+import time
+import atexit
+from opengnsys.log import logger
+
+from signal import SIGTERM
+
+
+class Daemon:
+ """
+ A generic daemon class.
+
+ Usage: subclass the Daemon class and override the run() method
+ """
+ def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
+ self.stdin = stdin
+ self.stdout = stdout
+ self.stderr = stderr
+ self.pidfile = pidfile
+
+ def daemonize(self):
+ """
+ do the UNIX double-fork magic, see Stevens' "Advanced
+ Programming in the UNIX Environment" for details (ISBN 0201563177)
+ http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
+ """
+ try:
+ pid = os.fork()
+ if pid > 0:
+ # exit first parent
+ sys.exit(0)
+ except OSError as e:
+ logger.error("fork #1 error: {}".format(e))
+ sys.stderr.write("fork #1 failed: {}\n".format(e))
+ sys.exit(1)
+
+ # decouple from parent environment
+ os.chdir("/")
+ os.setsid()
+ os.umask(0)
+
+ # do second fork
+ try:
+ pid = os.fork()
+ if pid > 0:
+ # exit from second parent
+ sys.exit(0)
+ except OSError as e:
+ logger.error("fork #2 error: {}".format(e))
+ sys.stderr.write("fork #2 failed: {}\n".format(e))
+ sys.exit(1)
+
+ # redirect standard file descriptors
+ sys.stdout.flush()
+ sys.stderr.flush()
+ si = open(self.stdin, 'r')
+ so = open(self.stdout, 'a+')
+ se = open(self.stderr, 'a+', 0)
+ os.dup2(si.fileno(), sys.stdin.fileno())
+ os.dup2(so.fileno(), sys.stdout.fileno())
+ os.dup2(se.fileno(), sys.stderr.fileno())
+
+ # write pidfile
+ atexit.register(self.delpid)
+ pid = str(os.getpid())
+ with open(self.pidfile, 'w+') as f:
+ f.write("{}\n".format(pid))
+
+ def delpid(self):
+ try:
+ os.remove(self.pidfile)
+ except Exception:
+ # Not found/not permissions or whatever...
+ pass
+
+ def start(self):
+ """
+ Start the daemon
+ """
+ logger.debug('Starting daemon')
+ # Check for a pidfile to see if the daemon already runs
+ try:
+ pf = open(self.pidfile, 'r')
+ pid = int(pf.read().strip())
+ pf.close()
+ except IOError:
+ pid = None
+
+ if pid:
+ message = "pidfile {} already exist. Daemon already running?\n".format(pid)
+ logger.error(message)
+ sys.stderr.write(message)
+ sys.exit(1)
+
+ # Start the daemon
+ self.daemonize()
+ try:
+ self.run()
+ except Exception as e:
+ logger.error('Exception running process: {}'.format(e))
+
+ if os.path.exists(self.pidfile):
+ os.remove(self.pidfile)
+
+ def stop(self):
+ """
+ Stop the daemon
+ """
+ # Get the pid from the pidfile
+ try:
+ pf = open(self.pidfile, 'r')
+ pid = int(pf.read().strip())
+ pf.close()
+ except IOError:
+ pid = None
+
+ if pid is None:
+ message = "pidfile {} does not exist. Daemon not running?\n".format(self.pidfile)
+ logger.info(message)
+ # sys.stderr.write(message)
+ return # not an error in a restart
+
+ # Try killing the daemon process
+ try:
+ for i in range(10):
+ os.kill(pid, SIGTERM)
+ time.sleep(1)
+ except OSError as err:
+ if err.errno == 3: # No such process
+ if os.path.exists(self.pidfile):
+ os.remove(self.pidfile)
+ else:
+ sys.stderr.write(err)
+ sys.exit(1)
+
+ def restart(self):
+ """
+ Restart the daemon
+ """
+ self.stop()
+ self.start()
+
+ # Overridables
+ def run(self):
+ """
+ You should override this method when you subclass Daemon. It will be called after the process has been
+ daemonized by start() or restart().
+ """
diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/oglive/operations.py b/admin/Sources/Clients/ogagent/src/opengnsys/oglive/operations.py
new file mode 100644
index 00000000..342cfb06
--- /dev/null
+++ b/admin/Sources/Clients/ogagent/src/opengnsys/oglive/operations.py
@@ -0,0 +1,236 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2014 Virtual Cable S.L.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Virtual Cable S.L. nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""
+@author: Ramón M. Gómez, ramongomez at us dot es
+"""
+from __future__ import unicode_literals
+
+import socket
+import platform
+import fcntl
+import subprocess
+import struct
+import array
+import six
+from opengnsys import utils
+
+
+def _getMacAddr(ifname):
+ """
+ Returns the mac address of an interface
+ Mac is returned as unicode utf-8 encoded
+ """
+ if isinstance(ifname, list):
+ return dict([(name, _getMacAddr(name)) for name in ifname])
+ if isinstance(ifname, six.text_type):
+ ifname = ifname.encode('utf-8') # If unicode, convert to bytes (or str in python 2.7)
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ info = bytearray(fcntl.ioctl(s.fileno(), 0x8927, struct.pack(str('256s'), ifname[:15])))
+ return six.text_type(''.join(['%02x:' % char for char in info[18:24]])[:-1])
+ except Exception:
+ return None
+
+
+def _getIpAddr(ifname):
+ """
+ Returns the ip address of an interface
+ Ip is returned as unicode utf-8 encoded
+ """
+ if isinstance(ifname, list):
+ return dict([(name, _getIpAddr(name)) for name in ifname])
+ if isinstance(ifname, six.text_type):
+ ifname = ifname.encode('utf-8') # If unicode, convert to bytes (or str in python 2.7)
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ return six.text_type(socket.inet_ntoa(fcntl.ioctl(
+ s.fileno(),
+ 0x8915, # SIOCGIFADDR
+ struct.pack(str('256s'), ifname[:15])
+ )[20:24]))
+ except Exception:
+ return None
+
+
+def _getInterfaces():
+ """
+ Returns a list of interfaces names coded in utf-8
+ """
+ max_possible = 128 # arbitrary. raise if needed.
+ space = max_possible * 16
+ if platform.architecture()[0] == '32bit':
+ offset, length = 32, 32
+ elif platform.architecture()[0] == '64bit':
+ offset, length = 16, 40
+ else:
+ raise OSError('Unknown arquitecture {0}'.format(platform.architecture()[0]))
+
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ names = array.array(str('B'), b'\0' * space)
+ outbytes = struct.unpack(str('iL'), fcntl.ioctl(
+ s.fileno(),
+ 0x8912, # SIOCGIFCONF
+ struct.pack(str('iL'), space, names.buffer_info()[0])
+ ))[0]
+ namestr = names.tostring()
+ # return namestr, outbytes
+ return [namestr[i:i + offset].split(b'\0', 1)[0].decode('utf-8') for i in range(0, outbytes, length)]
+
+
+def _getIpAndMac(ifname):
+ ip, mac = _getIpAddr(ifname), _getMacAddr(ifname)
+ return ip, mac
+
+
+def _exec_ogcommand(ogcmd):
+ """
+ Loads OpenGnsys environment variables, executes the command and returns the result
+ """
+ ret = subprocess.check_output(ogcmd, shell=True)
+ return ret
+
+
+def getComputerName():
+ """
+ Returns computer name, with no domain
+ """
+ return socket.gethostname().split('.')[0]
+
+
+def getNetworkInfo():
+ """
+ Obtains a list of network interfaces
+ :return: A "generator" of elements, that are dict-as-object, with this elements:
+ name: Name of the interface
+ mac: mac of the interface
+ ip: ip of the interface
+ """
+ for ifname in _getInterfaces():
+ ip, mac = _getIpAndMac(ifname)
+ if mac != '00:00:00:00:00:00': # Skips local interfaces
+ yield utils.Bunch(name=ifname, mac=mac, ip=ip)
+
+
+def getDomainName():
+ return ''
+
+
+def get_oglive_version():
+ """
+ Returns ogLive Kernel version and architecture
+ :return: kernel version
+ """
+ kv = platform.os.uname()
+ return kv[2] + ', ' + kv[4]
+
+
+def reboot():
+ """
+ Simple reboot using OpenGnsys script
+ """
+ # Workaround for dummy thread
+ if six.PY3 is False:
+ import threading
+ threading._DummyThread._Thread__stop = lambda x: 42
+
+ _exec_ogcommand('/opt/opengnsys/scripts/reboot')
+
+
+def poweroff():
+ """
+ Simple power off using OpenGnsys script
+ """
+ # Workaround for dummy thread
+ if six.PY3 is False:
+ import threading
+ threading._DummyThread._Thread__stop = lambda x: 42
+
+ _exec_ogcommand('/opt/opengnsys/scripts/poweroff')
+
+
+def get_configuration():
+ """
+ Returns client's configuration
+ Warning: this operation may take some time
+ :return:
+ """
+ try:
+ _exec_ogcommand('/opt/opengnsys/interfaceAdm/getConfiguration')
+ # Returns content of configuration file
+ cfgdata = open('/tmp/getconfig', 'r').read().strip()
+ except IOError:
+ cfgdata = ''
+ return cfgdata
+
+
+def exec_command(cmd):
+ """
+ Executing a shell command
+ :param cmd:
+ :return: object with components:
+ output: standard output
+ error: error output
+ exit: exit code
+ """
+ proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (out, err) = proc.communicate()
+ stat = proc.returncode
+ return stat, out, err
+
+
+def get_hardware():
+ """
+ Returns client's hardware list
+ :return:
+ """
+ try:
+ filepath = _exec_ogcommand('/opt/opengnsys/scripts/listHardwareInfo').strip()
+ # Returns content of configuration file, skipping the header line and newline characters
+ with open(filepath, 'r') as f:
+ harddata = map(str.strip, f.readlines()[1:])
+ except IOError:
+ harddata = ''
+ return harddata
+
+
+def get_software(disk, part):
+ """
+ Returns software list installed on an operating system
+ :param disk:
+ :param part:
+ :return:
+ """
+ try:
+ filepath = _exec_ogcommand('/opt/opengnsys/scripts/listSoftwareInfo {} {}'.format(disk, part)).strip()
+ # Returns content of configuration file, skipping the header line and newline characters
+ with open(filepath, 'r') as f:
+ softdata = map(str.strip, f.readlines())
+ except IOError:
+ softdata = ''
+ return softdata
diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/operations.py b/admin/Sources/Clients/ogagent/src/opengnsys/operations.py
index dcfa40cb..a81d0c0d 100644
--- a/admin/Sources/Clients/ogagent/src/opengnsys/operations.py
+++ b/admin/Sources/Clients/ogagent/src/opengnsys/operations.py
@@ -26,25 +26,32 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-'''
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
+"""
+@author: Ramón M. Gómez, ramongomez at us dot es
+"""
# pylint: disable=unused-wildcard-import,wildcard-import
from __future__ import unicode_literals
import sys
+import os
+
# Importing platform operations and getting operating system data.
if sys.platform == 'win32':
from .windows.operations import * # @UnusedWildImport
- osType = 'Windows'
- osVersion = getWindowsVersion()
+ os_type = 'Windows'
+ os_version = getWindowsVersion()
else:
if sys.platform == 'darwin':
from .macos.operations import * # @UnusedWildImport
- osType = 'MacOS'
- osVersion = getMacosVersion().replace(',','')
+ os_type = 'MacOS'
+ os_version = getMacosVersion().replace(',', '')
else:
- from .linux.operations import * # @UnusedWildImport
- osType = 'Linux'
- osVersion = getLinuxVersion().replace(',','')
+ if os.path.exists('/scripts/oginit'):
+ from .oglive.operations import * # @UnusedWildImport
+ os_type = 'ogLive'
+ os_version = get_oglive_version().replace(',', '')
+ else:
+ from .linux.operations import * # @UnusedWildImport
+ os_type = 'Linux'
+ os_version = getLinuxVersion().replace(',', '')
diff --git a/admin/Sources/Clients/ogagent/src/setup.py b/admin/Sources/Clients/ogagent/src/setup.py
index 15254f4f..617d5186 100644
--- a/admin/Sources/Clients/ogagent/src/setup.py
+++ b/admin/Sources/Clients/ogagent/src/setup.py
@@ -139,5 +139,5 @@ setup(
description='OpenGnsys Agent',
author='Adolfo Gomez',
author_email='agomez@virtualcable.es',
- zipfile='OGAgent.zip',
+ zipfile='OGAgent.zip', requires=['six']
)
diff --git a/admin/WebConsole/rest/ogagent.php b/admin/WebConsole/rest/ogagent.php
index be62a8d0..3e78da0e 100644
--- a/admin/WebConsole/rest/ogagent.php
+++ b/admin/WebConsole/rest/ogagent.php
@@ -271,4 +271,39 @@ EOD;
}
);
+// Processing command results (TESTING).
+$app->post('/ogagent/command_done',
+ // 'validateClient',
+ function() use ($app) {
+ global $cmd;
+
+ try {
+ // Reading parameters.
+ $input = json_decode($app->request()->getBody());
+ $client = htmlspecialchars($input->client);
+ $id = htmlspecialchars($input->trace);
+ $status = htmlspecialchars($input->status);
+ $output = htmlspecialchars($input->output);
+ $error = htmlspecialchars($input->error);
+ $client = $_SERVER['REMOTE_ADDR'];
+ // Check sender agent type.
+ if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT'])) or $client !== $_SERVER['REMOTE_ADDR']) {
+ throw new Exception("Bad OGAgent: client=$client, sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
+ }
+ // TODO: truncating outputs.
+ if ($status == 0) {
+ writeLog($app->request()->getResourceUri().": Operation OK: client=$client, id=$id, output=$output");
+ } else {
+ writeLog($app->request()->getResourceUri().": Operation ERROR: client=$client, id=$id, status=$status, error=$error");
+ }
+ $response = "";
+ jsonResponse(200, $response);
+ } catch (Exception $e) {
+ // Communication error.
+ $response["message"] = $e->getMessage();
+ writeLog($app->request()->getResourceUri().": ERROR: ".$response["message"]);
+ jsonResponse(400, $response);
+ }
+ }
+);
diff --git a/installer/vagrant/Vagrantfile-ogagent-vbox b/installer/vagrant/Vagrantfile-ogagent-vbox
index 1bf48faa..31760d65 100644
--- a/installer/vagrant/Vagrantfile-ogagent-vbox
+++ b/installer/vagrant/Vagrantfile-ogagent-vbox
@@ -21,7 +21,7 @@ localectl set-x11-keymap ${LANG%_*}
# Update repositories.
dnf install -y http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
# Install main dependencies.
-dnf install -y gcc-c++ debhelper dpkg-dev pyqt4-devel rpm-build subversion samba-winbind wine.i686 mingw32-wine-gecko wine-mono cabextract xar
+dnf install -y gcc-c++ perl-Digest-SHA debhelper dpkg-dev pyqt4-devel rpm-build subversion samba-winbind wine.i686 mingw32-wine-gecko wine-mono cabextract xar
setsebool -P wine_mmap_zero_ignore=on mmap_low_allowed=on
# Install desktop (XFCE) and GUI utils.
dnf install -y @xfce-desktop-environment firefox VirtualBox-guest kmod-VirtualBox akmod-VirtualBox akmods