#750: Process to build OGAgent for ogLive package.
parent
63576194e5
commit
88d3c4642b
|
@ -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)
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd $(dirname "$0")
|
||||
top=`pwd`
|
||||
|
||||
[ -r ../src/VERSION ] && VERSION="$(cat ../src/VERSION)" || VERSION="1.1.0"
|
||||
RELEASE="1"
|
||||
|
||||
# Debian based
|
||||
dpkg-buildpackage -b -d
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
9
|
|
@ -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.
|
|
@ -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'.
|
|
@ -0,0 +1 @@
|
|||
readme.txt
|
|
@ -0,0 +1,2 @@
|
|||
/usr/share/OGAgent/cfg/ogagent.cfg /etc/ogagent/ogagent.cfg
|
||||
/usr/share/OGAgent/cfg/ogclient.cfg /etc/ogagent/ogclient.cfg
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
misc:Depends=
|
||||
misc:Pre-Depends=
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
3.0 (native)
|
|
@ -0,0 +1,3 @@
|
|||
OGAgent is the agent intended for OpengGnsys interaction.
|
||||
|
||||
Please, visit https://opengnsys.es for more information
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
FOLDER=/usr/share/OGAgent
|
||||
|
||||
cd $FOLDER
|
||||
python OGAgentUser.py $@
|
|
@ -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
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
FOLDER=/usr/share/OGAgent
|
||||
|
||||
cd $FOLDER
|
||||
python -m opengnsys.linux.OGAgentService $@
|
|
@ -155,11 +155,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):
|
||||
|
@ -171,11 +167,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():
|
||||
|
|
|
@ -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
|
|
@ -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().
|
||||
"""
|
|
@ -0,0 +1,230 @@
|
|||
# -*- 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 os
|
||||
import ctypes # @UnusedImport
|
||||
import ctypes.util
|
||||
import subprocess
|
||||
import struct
|
||||
import array
|
||||
import six
|
||||
from opengnsys import utils
|
||||
|
||||
|
||||
def checkLockedPartition(sync=False):
|
||||
'''
|
||||
Decorator to check if a partition is locked
|
||||
'''
|
||||
def outer(fnc):
|
||||
def wrapper(*args, **kwargs):
|
||||
partId = 'None'
|
||||
try:
|
||||
this, path, getParams, postParams = args # @UnusedVariable
|
||||
partId = postParams['disk'] + postParams['part']
|
||||
if this.locked.get(partId, False):
|
||||
this.locked[partId] = True
|
||||
fnc(*args, **kwargs)
|
||||
else:
|
||||
return 'partition locked'
|
||||
except Exception as e:
|
||||
this.locked[partId] = False
|
||||
return 'error {}'.format(e)
|
||||
finally:
|
||||
if sync is True:
|
||||
this.locked[partId] = False
|
||||
logger.debug('Lock status: {} {}'.format(fnc, this.locked))
|
||||
return wrapper
|
||||
return outer
|
||||
|
||||
|
||||
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(self, ogcmd):
|
||||
'''
|
||||
Loads OpenGnsys environment variables, executes the command and returns the result
|
||||
'''
|
||||
ret = subprocess.check_output('source /opt/opengnsys/etc/preinit/loadenviron.sh >/dev/null; {}'.format(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 getOgliveVersion():
|
||||
lv = platform.linux_distribution()
|
||||
return lv[0] + ', ' + lv[1]
|
||||
|
||||
|
||||
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', shell=True)
|
||||
|
||||
|
||||
def poweroff():
|
||||
'''
|
||||
Simple poweroff 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', shell=True)
|
||||
|
||||
|
||||
def logoff():
|
||||
pass
|
||||
|
||||
|
||||
def renameComputer(newName):
|
||||
pass
|
||||
|
||||
|
||||
def joinDomain(domain, ou, account, password, executeInOneStep=False):
|
||||
pass
|
||||
|
||||
|
||||
def changeUserPassword(user, oldPassword, newPassword):
|
||||
pass
|
||||
|
||||
|
||||
def diskconfig():
|
||||
'''
|
||||
Returns disk configuration.
|
||||
Warning: this operation may take some time.
|
||||
'''
|
||||
try:
|
||||
_exec_ogcommand('/opt/opengnsys/interfaceAdm/getConfiguration')
|
||||
# Returns content of configuration file.
|
||||
cfgdata = open('/tmp/getconfig', 'r').read()
|
||||
except IOError:
|
||||
cfgdata = ''
|
||||
return cfgdata
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Importing platform operations and getting operating system data.
|
||||
if sys.platform == 'win32':
|
||||
|
@ -45,6 +46,11 @@ else:
|
|||
os_type = 'MacOS'
|
||||
os_version = getMacosVersion().replace(',', '')
|
||||
else:
|
||||
from .linux.operations import * # @UnusedWildImport
|
||||
os_type = 'Linux'
|
||||
os_version = getLinuxVersion()
|
||||
if os.path.exists('/scripts/oginit'):
|
||||
from .oglive.operations import * # @UnusedWildImport
|
||||
osType = 'ogLive'
|
||||
os_version = getOgliveVersion().replace(',','')
|
||||
else:
|
||||
from .linux.operations import * # @UnusedWildImport
|
||||
os_type = 'Linux'
|
||||
os_version = getLinuxVersion()
|
||||
|
|
Loading…
Reference in New Issue