#750: Process to build OGAgent for ogLive package.
parent
2617b6d50f
commit
cf4de0c2d2
|
@ -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 $@
|
|
@ -152,11 +152,7 @@ def reboot(flags=0):
|
||||||
import threading
|
import threading
|
||||||
threading._DummyThread._Thread__stop = lambda x: 42
|
threading._DummyThread._Thread__stop = lambda x: 42
|
||||||
|
|
||||||
# Check for OpenGnsys Client or GNU/Linux distribution.
|
subprocess.call(['/sbin/reboot'])
|
||||||
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'])
|
|
||||||
|
|
||||||
|
|
||||||
def poweroff(flags=0):
|
def poweroff(flags=0):
|
||||||
|
@ -168,11 +164,7 @@ def poweroff(flags=0):
|
||||||
import threading
|
import threading
|
||||||
threading._DummyThread._Thread__stop = lambda x: 42
|
threading._DummyThread._Thread__stop = lambda x: 42
|
||||||
|
|
||||||
# Check for OpenGnsys Client or GNU/Linux distribution.
|
subprocess.call(['/sbin/poweroff'])
|
||||||
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'])
|
|
||||||
|
|
||||||
|
|
||||||
def logoff():
|
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
|
from __future__ import unicode_literals
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
# Importing platform operations and getting operating system data.
|
# Importing platform operations and getting operating system data.
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
|
@ -45,6 +46,11 @@ else:
|
||||||
os_type = 'MacOS'
|
os_type = 'MacOS'
|
||||||
os_version = getMacosVersion().replace(',', '')
|
os_version = getMacosVersion().replace(',', '')
|
||||||
else:
|
else:
|
||||||
from .linux.operations import * # @UnusedWildImport
|
if os.path.exists('/scripts/oginit'):
|
||||||
os_type = 'Linux'
|
from .oglive.operations import * # @UnusedWildImport
|
||||||
os_version = getLinuxVersion().replace(',', '')
|
osType = 'ogLive'
|
||||||
|
osVersion = getOgliveVersion().replace(',','')
|
||||||
|
else:
|
||||||
|
from .linux.operations import * # @UnusedWildImport
|
||||||
|
osType = 'Linux'
|
||||||
|
osVersion = getLinuxVersion().replace(',','')
|
||||||
|
|
Loading…
Reference in New Issue