Compare commits
No commits in common. "master" and "branch-v1" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,2 @@
|
|||||||
*.sh
|
*.sh
|
||||||
*.tar.*
|
*.tar.*
|
||||||
*.rpm
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
use esmith::Build::CreateLinks qw(:all);
|
|
||||||
use File::Basename;
|
|
||||||
use File::Path;
|
|
||||||
|
|
||||||
|
|
||||||
$event = "doraemon-reboot";
|
|
||||||
event_actions($event, 'doraemon-reboot' => 50);
|
|
||||||
|
|
||||||
$event = "doraemon-shutdown";
|
|
||||||
event_actions($event, 'doraemon-shutdown' => 50);
|
|
||||||
|
|
||||||
$event = "doraemon-wake";
|
|
||||||
event_actions($event, 'doraemon-wake' => 50);
|
|
1
defaults/access
Normal file
1
defaults/access
Normal file
@ -0,0 +1 @@
|
|||||||
|
private
|
16
doraemon.ini
Normal file
16
doraemon.ini
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[Daemon]
|
||||||
|
Database = /var/lib/doraemon/doraemon.db
|
||||||
|
LogFile = /var/log/doraemon.log
|
||||||
|
PIDFile = /var/run/doraemon.pid
|
||||||
|
BindAddress = 0.0.0.0
|
||||||
|
Port = 3000
|
||||||
|
|
||||||
|
[NameSettings]
|
||||||
|
Base = lab
|
||||||
|
Role = client
|
||||||
|
Digits = 2
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Domain = /etc/domain.yml
|
||||||
|
MgmtKey = /home/amgmt/.ssh/id_rsa.pub
|
||||||
|
VaultPassFile = /home/amgmt/.ansible/vault.txt
|
6
doraemon.logrotate
Normal file
6
doraemon.logrotate
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/var/log/doraemon.log {
|
||||||
|
daily
|
||||||
|
rotate 15
|
||||||
|
compress
|
||||||
|
missingok
|
||||||
|
}
|
234
doraemon.py
Normal file
234
doraemon.py
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Helps a client to join domain and maintain itself."""
|
||||||
|
__author__ = 'BgLUG'
|
||||||
|
__email__ = 'info@bglug.it'
|
||||||
|
|
||||||
|
from contextlib import contextmanager, closing
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
from sqlite3 import connect
|
||||||
|
from bottle import Bottle, request
|
||||||
|
from json import dumps
|
||||||
|
from ConfigParser import ConfigParser
|
||||||
|
from Crypto.Hash import MD5
|
||||||
|
from Crypto.Cipher import AES
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
|
||||||
|
class MyApp:
|
||||||
|
def __init__(self, configfile = '/etc/mac2hostname.ini'):
|
||||||
|
if not os.path.isfile(configfile):
|
||||||
|
print "Cannot find main file, %s. Exiting." % configfile
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Loads configurations
|
||||||
|
config = ConfigParser()
|
||||||
|
config.read(configfile)
|
||||||
|
# Populates private properties with configuration
|
||||||
|
self.__dbfile = config.get('Daemon', 'Database') if config.has_option('Daemon', 'Database') else '/var/lib/doraemon/doraemon.db'
|
||||||
|
self.__logdir = config.get('Daemon', 'LogFile') if config.has_option('Daemon', 'LogFile') else '/var/log/doraemon.log'
|
||||||
|
self.__pidfile = config.get('Daemon', 'PIDFile') if config.has_option('Daemon', 'PIDFile') else '/var/run/doraemon.pid'
|
||||||
|
self.__bindaddress = config.get('Daemon', 'BindAddress') if config.has_option('Daemon', 'BindAddress') else '127.0.0.1'
|
||||||
|
self.__port = config.getint('Daemon', 'Port') if config.has_option('Daemon',
|
||||||
|
'Port') else 8080
|
||||||
|
self.__defaultbase = config.get('NameSettings', 'Base') if config.has_option('NameSettings', 'Base') else 'client'
|
||||||
|
self.__defaultrole = config.get('NameSettings', 'Role') if config.has_option('NameSettings', 'Role') else 'client'
|
||||||
|
self.__namedigits = config.get('NameSettings', 'Digits') if config.has_option('NameSettings', 'Digits') else '2'
|
||||||
|
self.__domainfile = config.get('Files', 'Domain') if config.has_option('Files', 'Domain') else None
|
||||||
|
self.__mgmtfile = config.get('Files', 'MgmtKey') if config.has_option('Files', 'MgmtKey') else None
|
||||||
|
self.__vaultpassfile = config.get('Files', 'VaultPassFile') if config.has_option('Files', 'VaultPassFile') else None
|
||||||
|
self.__app = Bottle()
|
||||||
|
# Applies routes
|
||||||
|
self.__route()
|
||||||
|
# Assures table creation
|
||||||
|
self.__init_tables()
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def __getcursor(self):
|
||||||
|
with connect(self.__dbfile) as connection:
|
||||||
|
with closing(connection.cursor()) as cursor:
|
||||||
|
yield cursor
|
||||||
|
|
||||||
|
# Private methods
|
||||||
|
def __route(self):
|
||||||
|
self.__app.get('/mac2hostname', callback=self.mac2hostname)
|
||||||
|
self.__app.get('/whatsmyhostname', callback=self.whatsmyhostname)
|
||||||
|
self.__app.get('/hosts', callback=self.hosts)
|
||||||
|
self.__app.get('/domain', callback=self.domain)
|
||||||
|
self.__app.get('/mgmtkey', callback=self.mgmtkey)
|
||||||
|
self.__app.get('/vaultpass', callback=self.vaultpass)
|
||||||
|
self.__app.get('/ansible_list', callback=self.ansible_list)
|
||||||
|
self.__app.get('/ansible_host', callback=self.ansible_host)
|
||||||
|
self.__app.get('/epoptes-srv', callback=self.epoptes_srv)
|
||||||
|
|
||||||
|
def __init_tables(self):
|
||||||
|
with self.__getcursor() as cursor:
|
||||||
|
cursor.execute('CREATE TABLE IF NOT EXISTS client (id INT PRIMARY KEY,'
|
||||||
|
'hostname TEXT NOT NULL UNIQUE, mac TEXT UNIQUE, role TEXT)')
|
||||||
|
cursor.execute('CREATE INDEX IF NOT EXISTS idxmac ON client(mac)')
|
||||||
|
|
||||||
|
def __getmac(self, ip):
|
||||||
|
Popen(['ping', '-c1', '-t2', ip], stdout=PIPE).communicate()
|
||||||
|
arp = Popen(['arp', '-n', ip], stdout=PIPE).communicate()[0]
|
||||||
|
return re.search(r'(([\da-fA-F]{1,2}\:){5}[\da-fA-F]{1,2})', arp).group(1).lower()
|
||||||
|
|
||||||
|
def __normalizemac(self, mac):
|
||||||
|
return ':'.join(x.zfill(2) for x in mac.split('_')).lower()
|
||||||
|
|
||||||
|
def __gethostname(self, mac, base = None, role = None):
|
||||||
|
if base == None:
|
||||||
|
base = self.__defaultbase
|
||||||
|
if role == None:
|
||||||
|
role = self.__defaultrole
|
||||||
|
|
||||||
|
with self.__getcursor() as cursor:
|
||||||
|
(newid,) = cursor.execute('SELECT COALESCE(MAX(id) + 1, 1) FROM client').fetchone()
|
||||||
|
# Constucts the hostname format
|
||||||
|
formatstring = '%s-%0' + self.__namedigits + 'd'
|
||||||
|
data = (newid, formatstring % (base, newid), mac, role)
|
||||||
|
# Since MAC is Unique, this fails with the same MAC address
|
||||||
|
cursor.execute('INSERT OR IGNORE INTO client VALUES (?, ?, ?, ?)', data)
|
||||||
|
(hostname,) = cursor.execute('SELECT hostname FROM client WHERE mac = "%s"' % mac).fetchone()
|
||||||
|
return hostname
|
||||||
|
|
||||||
|
# This should be used only after registration of the client
|
||||||
|
# (whatsmyhostname)
|
||||||
|
def __getrole(self):
|
||||||
|
macaddress = self.__normalizemac(self.__getmac(request['REMOTE_ADDR']))
|
||||||
|
hostname = self.__gethostname(macaddress)
|
||||||
|
|
||||||
|
with self.__getcursor() as cursor:
|
||||||
|
(role,) = cursor.execute("SELECT role FROM client WHERE hostname = '%s' AND mac = '%s'" % (hostname, macaddress)).fetchone()
|
||||||
|
return role
|
||||||
|
|
||||||
|
# Variables returned to the client
|
||||||
|
def __rolevars(self, role=None):
|
||||||
|
retval = {'role': role, 'addpkg': [], 'delpkg': []}
|
||||||
|
try:
|
||||||
|
db = Popen(['/sbin/e-smith/db', 'roles', 'getjson'], stdout=PIPE).communicate()[0]
|
||||||
|
for data in json.loads(db):
|
||||||
|
if data['name'] == role:
|
||||||
|
retval['addpkg'] = re.split(r'[\s,;]+', data['props']['Addpkg'])
|
||||||
|
retval['delpkg'] = re.split(r'[\s,;]+', data['props']['Delpkg'])
|
||||||
|
continue
|
||||||
|
except: pass
|
||||||
|
return retval
|
||||||
|
|
||||||
|
# Instance methods AKA routes
|
||||||
|
def mac2hostname(self):
|
||||||
|
# Ensure required parameters have been passed
|
||||||
|
if not request.query.mac:
|
||||||
|
return "Usage: GET /mac2hostname?mac=XX_XX_XX_XX_XX_XX[&base=YYY][&role=ZZZ]"
|
||||||
|
# Sets up variables for possible parameters
|
||||||
|
mac = self.__normalizemac(request.query.mac)
|
||||||
|
base = request.query.base or self.__defaultbase
|
||||||
|
role = request.query.role or self.__defaultrole
|
||||||
|
return self.__gethostname(mac, base, role)
|
||||||
|
|
||||||
|
def whatsmyhostname(self):
|
||||||
|
# No required parameters
|
||||||
|
ip = request.query.ip or request['REMOTE_ADDR']
|
||||||
|
base = request.query.base or self.__defaultbase
|
||||||
|
role = request.query.role or self.__defaultrole
|
||||||
|
return self.__gethostname(self.__getmac(ip), base, role)
|
||||||
|
|
||||||
|
def hosts(self):
|
||||||
|
# Default where clause: no where specifications
|
||||||
|
where = ''
|
||||||
|
# If a role parameter is passed, list the hosts for that role
|
||||||
|
if request.query.role:
|
||||||
|
where = "WHERE role = '%s'" % request.query.role
|
||||||
|
with self.__getcursor() as cursor:
|
||||||
|
return dumps([dict((meta[0], data)
|
||||||
|
for meta, data in zip(cursor.description, row))
|
||||||
|
for row in cursor.execute('SELECT role, hostname, mac FROM client '
|
||||||
|
+ where + 'ORDER BY role ASC, hostname ASC')], indent=4)
|
||||||
|
|
||||||
|
def domain(self):
|
||||||
|
with open(self.__domainfile, 'r') as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
def mgmtkey(self):
|
||||||
|
with open(self.__mgmtfile, 'r') as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
def vaultpass(self):
|
||||||
|
with open(self.__vaultpassfile, 'r') as f:
|
||||||
|
ip = request.query.ip or request['REMOTE_ADDR']
|
||||||
|
base = request.query.base or self.__defaultbase
|
||||||
|
role = request.query.role or self.__defaultrole
|
||||||
|
hostname = self.__gethostname(self.__getmac(ip), base, role)
|
||||||
|
# Encryption key
|
||||||
|
key = MD5.new(hostname).digest()
|
||||||
|
# Secret
|
||||||
|
secret = f.read().strip()
|
||||||
|
# Creating a secret that is multiple of 16 in length
|
||||||
|
i = 16 - (len(secret) % 16)
|
||||||
|
lengthy_secret = secret + i * 'x'
|
||||||
|
cipher = AES.new(key, AES.MODE_ECB)
|
||||||
|
crypted = cipher.encrypt(lengthy_secret)
|
||||||
|
# Encode in base64 because of unicode strings
|
||||||
|
return base64.b64encode(crypted)
|
||||||
|
|
||||||
|
def ansible_list(self):
|
||||||
|
# Faking calls
|
||||||
|
if request.query.role:
|
||||||
|
role = request.query.role
|
||||||
|
else:
|
||||||
|
role = self.__getrole()
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'localhost': {
|
||||||
|
'hosts': [ 'localhost' ],
|
||||||
|
'vars': {
|
||||||
|
'ansible_connection': 'local'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'_meta': {
|
||||||
|
'hostvars': {
|
||||||
|
'localhost': self.__rolevars(role)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dumps(result)
|
||||||
|
|
||||||
|
def ansible_host(self):
|
||||||
|
# Ignoring 'host' parameter, since it should always be 'localhost'.
|
||||||
|
# Instead, for testing purposes, if asked for a role, use it
|
||||||
|
if request.query.role:
|
||||||
|
role = request.query.role
|
||||||
|
else:
|
||||||
|
role = self.__getrole()
|
||||||
|
return dumps(self.__rolevars(role))
|
||||||
|
|
||||||
|
def epoptes_srv(self):
|
||||||
|
hostname = None
|
||||||
|
try:
|
||||||
|
with self.__getcursor() as cursor:
|
||||||
|
(hostname,) = cursor.execute('SELECT hostname FROM client WHERE role = \'docenti\' ORDER BY id DESC LIMIT 1').fetchone()
|
||||||
|
except TypeError:
|
||||||
|
return 'none'
|
||||||
|
|
||||||
|
return hostname
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
# Opens up a PID file
|
||||||
|
pid = os.getpid()
|
||||||
|
pidfile = open(self.__pidfile, 'w')
|
||||||
|
pidfile.write('%s' % pid)
|
||||||
|
pidfile.close()
|
||||||
|
|
||||||
|
# Runs Bottle, at last.
|
||||||
|
self.__app.run(host=self.__bindaddress, port=self.__port)
|
||||||
|
|
||||||
|
# Main body
|
||||||
|
if __name__ == '__main__':
|
||||||
|
cfgfile = '/etc/doraemon.ini'
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
cfgfile = sys.argv[1]
|
||||||
|
app = MyApp(cfgfile)
|
||||||
|
app.start()
|
172
doraemon.spec
172
doraemon.spec
@ -1,165 +1,85 @@
|
|||||||
Summary: Helps client to join domain and maintain itself
|
Summary: Helps client to join domain and maintain itself
|
||||||
Name: doraemon
|
Name: doraemon
|
||||||
Version: 2.0.4
|
Version: 1.2.1
|
||||||
Release: 1.ns6
|
Release: 2.ns6
|
||||||
URL: https://github.com/bglug-it/doraemon/
|
URL: https://github.com/bglug-it/doraemon/
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
Packager: Paolo Asperti <paolo@asperti.com>
|
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
BuildRoot: %{_tmppath}/%{name}-root
|
BuildRoot: %{_tmppath}/%{name}-root
|
||||||
BuildRequires: nethserver-devtools > 1.0.1
|
Requires: python python-bottle python-crypto2.6 nethserver-base
|
||||||
BuildRequires: hunspell-en
|
Requires(post): chkconfig nethserver-base
|
||||||
Requires: httpd, php, sudo, php-xml, php-mcrypt
|
Requires(preun): chkconfig initscripts nethserver-base
|
||||||
Requires: nethserver-base, nethserver-php
|
Source0: doraemon-1.2.1.tar.gz
|
||||||
Requires: net-tools
|
|
||||||
Requires: upstart
|
|
||||||
Source0: %{name}-%{version}.tar.gz
|
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Helps client on a domain network to get information for its maintenance.
|
Helps client on a domain network to get information for its maintenance.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup
|
%setup -q
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%{makedocs}
|
|
||||||
perl createlinks.pl
|
|
||||||
|
|
||||||
%install
|
%install
|
||||||
rm -Rf $RPM_BUILD_ROOT
|
rm -rf %{buildroot}
|
||||||
(cd root ; find . -depth -print | cpio -dump %{buildroot})
|
install -d %{buildroot}
|
||||||
rm -f %{name}-%{version}-%{release}-filelist
|
install -d -m 755 %{buildroot}%{_sysconfdir}
|
||||||
%{genfilelist} %{buildroot} > %{name}-%{version}-%{release}-filelist
|
install -m 644 doraemon.ini %{buildroot}%{_sysconfdir}/%{name}.ini
|
||||||
mkdir -p %{buildroot}%{_localstatedir}/log/doraemon
|
# Installo il servizio
|
||||||
mkdir -p %{buildroot}%{_localstatedir}/cache/doraemon
|
install -d -m 755 %{buildroot}%{_initrddir}
|
||||||
|
install -m 755 initrd %{buildroot}%{_initrddir}/%{name}
|
||||||
|
# Installo lo script vero e proprio
|
||||||
%pre
|
install -d -m 755 %{buildroot}%{_bindir}
|
||||||
#if [ "$1" = 1 ]; then
|
install -m 755 doraemon.py %{buildroot}%{_bindir}/%{name}.py
|
||||||
# #installation
|
# Cartella del database
|
||||||
#fi
|
install -d %{buildroot}%{_sharedstatedir}/%{name}
|
||||||
if [ "$1" = 2 ]; then
|
# File per il rotate
|
||||||
#upgrade
|
install -d %{buildroot}%{_sysconfdir}/logrotate.d
|
||||||
/sbin/service %{name} stop >/dev/null 2>&1 || :
|
install -m 644 doraemon.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
|
||||||
/sbin/stop %{name} >/dev/null 2>&1 || :
|
# File di Nethserver
|
||||||
DATABASE=/var/lib/doraemon/doraemon.db
|
install -d %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}
|
||||||
INI=/etc/doraemon.ini
|
install -m 644 type %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/type
|
||||||
if [ -f $INI ]; then
|
install -m 644 status %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/status
|
||||||
DATABASE=$(awk -F "=" '/Database/ {print $2}' $INI)
|
install -m 644 access %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/access
|
||||||
PORT=$(awk -F "=" '/Port/ {print $2}' $INI)
|
install -m 644 TCPPort %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/TCPPort
|
||||||
BASE=$(awk -F "=" '/Base/ {print $2}' $INI)
|
|
||||||
ROLE=$(awk -F "=" '/Role/ {print $2}' $INI)
|
|
||||||
DIGITS=$(awk -F "=" '/Digits/ {print $2}' $INI)
|
|
||||||
DOMAIN=$(awk -F "=" '/Domain/ {print $2}' $INI)
|
|
||||||
MGMTKEY=$(awk -F "=" '/MgmtKey/ {print $2}' $INI)
|
|
||||||
VAULTPASSFILE=$(awk -F "=" '/VaultPassFile/ {print $2}' $INI)
|
|
||||||
rm $INI
|
|
||||||
/sbin/e-smith/db configuration set %{name} service \
|
|
||||||
status enabled \
|
|
||||||
TCPPort $PORT \
|
|
||||||
access private \
|
|
||||||
DefaultRole $ROLE \
|
|
||||||
DomainFile $DOMAIN \
|
|
||||||
ManagementKeyFile $MGMTKEY \
|
|
||||||
NamingBase $BASE \
|
|
||||||
NamingDigits $DIGITS \
|
|
||||||
VaultPassFile $VAULTPASSFILE
|
|
||||||
else
|
|
||||||
/sbin/e-smith/db configuration set %{name} service \
|
|
||||||
status enabled \
|
|
||||||
TCPPort 3000 \
|
|
||||||
access private \
|
|
||||||
DefaultRole client \
|
|
||||||
DomainFile /etc/domain.yml \
|
|
||||||
ManagementKeyFile /home/amgmt/.ssh/id_rsa.pub \
|
|
||||||
NamingBase lab \
|
|
||||||
NamingDigits 2 \
|
|
||||||
VaultPassFile /home/amgmt/.ansible/vault.txt
|
|
||||||
fi
|
|
||||||
if [ -f $DATABASE ]; then
|
|
||||||
sqlite3 -separator " " $DATABASE \
|
|
||||||
"select * from client" | while read id hostname mac role; do
|
|
||||||
/sbin/e-smith/db hosts set $hostname local \
|
|
||||||
MacAddress $mac Role $role
|
|
||||||
done
|
|
||||||
rm $DATABASE
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
%post
|
%post
|
||||||
/etc/e-smith/events/actions/initialize-default-databases
|
|
||||||
[ -e /usr/sbin/doraemon ] && [ ! -L /usr/sbin/doraemon ] && rm /usr/sbin/doraemon
|
|
||||||
[ ! -L /usr/sbin/doraemon ] && ln -s httpd /usr/sbin/doraemon
|
|
||||||
if [ "$1" = 1 ]; then
|
if [ "$1" = 1 ]; then
|
||||||
#installation
|
/sbin/chkconfig --add %{name}
|
||||||
/sbin/e-smith/db configuration set %{name} service status enabled TCPPort 3000 access private DefaultRole client DomainFile /etc/domain.yml ManagementKeyFile /home/amgmt/.ssh/id_rsa.pub NamingBase lab NamingDigits 2 VaultPassFile /home/amgmt/.ansible/vault.txt
|
/sbin/service %{name} start >/dev/null 2>&1
|
||||||
/sbin/e-smith/expand-template /etc/sudoers
|
/sbin/e-smith/db configuration set %{name} service status enabled TCPPort 3000 access private
|
||||||
/sbin/e-smith/expand-template /etc/httpd/doraemon/httpd.conf
|
|
||||||
/sbin/start %{name} >/dev/null 2>&1 || :
|
|
||||||
/sbin/e-smith/signal-event runlevel-adjust
|
/sbin/e-smith/signal-event runlevel-adjust
|
||||||
/sbin/e-smith/signal-event firewall-adjust
|
/sbin/e-smith/signal-event firewall-adjust
|
||||||
fi
|
fi
|
||||||
if [ "$1" = 2 ]; then
|
|
||||||
#upgrade
|
|
||||||
# TODO: this won't be needed in the next version
|
|
||||||
/sbin/e-smith/expand-template /etc/sudoers
|
|
||||||
/sbin/e-smith/expand-template /etc/httpd/doraemon/httpd.conf
|
|
||||||
/sbin/start %{name} >/dev/null 2>&1 || :
|
|
||||||
/sbin/e-smith/signal-event runlevel-adjust
|
|
||||||
/sbin/e-smith/signal-event firewall-adjust
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
%preun
|
%preun
|
||||||
#if [ "$1" = 1 ]; then
|
|
||||||
# #upgrade
|
|
||||||
#fi
|
|
||||||
if [ "$1" = 0 ]; then
|
if [ "$1" = 0 ]; then
|
||||||
#uninstallation
|
|
||||||
/sbin/stop %{name} >/dev/null 2>&1 || :
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
%postun
|
|
||||||
#if [ "$1" = 1 ]; then
|
|
||||||
# #upgrade
|
|
||||||
#fi
|
|
||||||
if [ "$1" = 0 ]; then
|
|
||||||
#uninstallation
|
|
||||||
/sbin/e-smith/db configuration delete %{name}
|
/sbin/e-smith/db configuration delete %{name}
|
||||||
/sbin/e-smith/expand-template /etc/sudoers
|
/sbin/service %{name} stop >/dev/null 2>&1
|
||||||
|
chkconfig --del %{name}
|
||||||
/sbin/e-smith/signal-event runlevel-adjust
|
/sbin/e-smith/signal-event runlevel-adjust
|
||||||
/sbin/e-smith/signal-event firewall-adjust
|
/sbin/e-smith/signal-event firewall-adjust
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
rm -rf %{buildroot}
|
rm -rf %{buildroot}
|
||||||
|
|
||||||
%files -f %{name}-%{version}-%{release}-filelist
|
%files
|
||||||
%defattr(0644,root,root,755)
|
%defattr(644,root,root,755)
|
||||||
%doc README.md LICENSE.txt
|
%doc README.md LICENSE
|
||||||
%attr(0644,srvmgr,srvmgr) %ghost %{_localstatedir}/log/doraemon/access_log
|
%config(noreplace) %{_sysconfdir}/%{name}.ini
|
||||||
%attr(0644,srvmgr,srvmgr) %ghost %{_localstatedir}/log/doraemon/error_log
|
%attr(755,-,-) %{_initrddir}/%{name}
|
||||||
|
%attr(755,-,-) %{_bindir}/%{name}.py
|
||||||
|
|
||||||
|
%dir %attr(755,-,-) %{_sharedstatedir}/%{name}
|
||||||
|
%{_sysconfdir}/logrotate.d/%{name}
|
||||||
|
%dir %attr(755,-,-) %{_sysconfdir}/e-smith/db/configuration/defaults/%{name}
|
||||||
|
%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/status
|
||||||
|
%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/type
|
||||||
|
%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/access
|
||||||
|
%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/TCPPort
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Sun Jun 17 2018 Emiliano Vavassori <syntaxerrormmm-AT-gmail.com> - 2.0.4-1
|
|
||||||
- FIX: Doraemon doesn't start after installation
|
|
||||||
|
|
||||||
* Sun Jun 17 2018 Emiliano Vavassori <syntaxerrormmm-AT-gmail.com> - 2.0.3-1
|
|
||||||
- FIX: whatsmyhostname correctly parse role variable
|
|
||||||
- Minor aesthetic syntax fixes
|
|
||||||
|
|
||||||
* Sun Oct 8 2017 Paolo Asperti <paolo@asperti.com> - 2.0.2-1
|
|
||||||
- FIX: bug in WOL
|
|
||||||
- FIX: small language typos
|
|
||||||
|
|
||||||
* Wed Nov 9 2016 Paolo Asperti <paolo@asperti.com> - 2.0.1-1
|
|
||||||
- PHP porting
|
|
||||||
- Added a basic UI
|
|
||||||
|
|
||||||
* Tue Oct 27 2015 Emiliano Vavassori <syntaxerrormmm-AT-gmail.com> - 1.2.1-2.ns6
|
* Tue Oct 27 2015 Emiliano Vavassori <syntaxerrormmm-AT-gmail.com> - 1.2.1-2.ns6
|
||||||
- Packing corrections to rpm to fix upgrading issue
|
- Packing corrections to rpm to fix upgrading issue
|
||||||
|
|
||||||
|
79
initrd
Normal file
79
initrd
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# chkconfig: 2345 20 80
|
||||||
|
# description: Manage assignation of hostnames for clients
|
||||||
|
# pidfile: /var/run/doraemon.pid
|
||||||
|
# config: /etc/doraemon.ini
|
||||||
|
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: doraemon
|
||||||
|
# Required-Start: $remote_fs $syslog
|
||||||
|
# Required-Stop: $remote_fs $syslog
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Helps client to join the domain and maintain itself
|
||||||
|
# Description: Helps client to join the domain and maintain itself
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
# Change the next 3 lines to suit where you install your script and what you want to call it
|
||||||
|
DAEMON=/usr/bin/doraemon.py
|
||||||
|
DAEMON_NAME=doraemon
|
||||||
|
|
||||||
|
# Add any command line options for your daemon here
|
||||||
|
DAEMON_OPTS=""
|
||||||
|
|
||||||
|
# This next line determines what user the script runs as.
|
||||||
|
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
|
||||||
|
#DAEMON_USER=mac2hostname
|
||||||
|
#DAEMON_GROUP=mac2hostname
|
||||||
|
|
||||||
|
# The process ID of the script when it runs is stored here:
|
||||||
|
LOGFILE=/var/log/$DAEMON_NAME.log
|
||||||
|
PIDFILE=/var/run/$DAEMON_NAME.pid
|
||||||
|
lockfile=/var/lock/subsys/$DAEMON_NAME
|
||||||
|
|
||||||
|
. /etc/rc.d/init.d/functions
|
||||||
|
. /etc/sysconfig/network
|
||||||
|
|
||||||
|
[ "$NETWORKING" = "no" ] && exit 0
|
||||||
|
|
||||||
|
do_start () {
|
||||||
|
echo -n $"Starting $DAEMON_NAME: "
|
||||||
|
daemon --pidfile=$PIDFILE "python $DAEMON >>$LOGFILE 2>/dev/null &"
|
||||||
|
RETVAL=$?
|
||||||
|
echo
|
||||||
|
[ $RETVAL -eq 0 ] && touch $lockfile
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
do_stop () {
|
||||||
|
echo -n $"Stopping $DAEMON_NAME: "
|
||||||
|
killproc -p $PIDFILE python
|
||||||
|
RETVAL=$?
|
||||||
|
echo
|
||||||
|
[ $RETVAL -eq 0 ] && rm -f $lockfile
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
|
||||||
|
start|stop)
|
||||||
|
do_${1}
|
||||||
|
;;
|
||||||
|
|
||||||
|
restart|reload|force-reload)
|
||||||
|
do_stop
|
||||||
|
do_start
|
||||||
|
;;
|
||||||
|
|
||||||
|
status)
|
||||||
|
status -p $PIDFILE python
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
exit 0
|
@ -1 +0,0 @@
|
|||||||
client
|
|
@ -1 +0,0 @@
|
|||||||
/etc/domain.yml
|
|
@ -1 +0,0 @@
|
|||||||
/home/amgmt/.ssh/id_rsa.pub
|
|
@ -1 +0,0 @@
|
|||||||
lab
|
|
@ -1 +0,0 @@
|
|||||||
/home/amgmt/.ansible/vault.txt
|
|
@ -1 +0,0 @@
|
|||||||
public
|
|
@ -1,34 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
package esmith;
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Errno;
|
|
||||||
use esmith::DB::db;
|
|
||||||
use IO::File;
|
|
||||||
use English;
|
|
||||||
|
|
||||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
|
||||||
|
|
||||||
my $event = $ARGV[0];
|
|
||||||
|
|
||||||
defined $ARGV[1] || die "No host specified";
|
|
||||||
my $host = $ARGV[1];
|
|
||||||
|
|
||||||
reboot_host($host);
|
|
||||||
|
|
||||||
exit 0;
|
|
||||||
|
|
||||||
sub reboot_host
|
|
||||||
{
|
|
||||||
my ($hostName) = @_;
|
|
||||||
#------------------------------------------------------------
|
|
||||||
# Reboot the host
|
|
||||||
#------------------------------------------------------------
|
|
||||||
|
|
||||||
my $h = $db_hosts->get($hostName) or die "No host record for $hostName";
|
|
||||||
|
|
||||||
system("/usr/bin/sudo -u amgmt /usr/bin/ssh -o StrictHostKeyChecking=no amgmt\@$hostName /usr/bin/sudo /sbin/reboot") == 0
|
|
||||||
or die "Error rebooting $hostName";
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
package esmith;
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Errno;
|
|
||||||
use esmith::DB::db;
|
|
||||||
use IO::File;
|
|
||||||
use English;
|
|
||||||
|
|
||||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
|
||||||
|
|
||||||
my @items = $db_hosts->get_all('local');
|
|
||||||
foreach my $item (@items) {
|
|
||||||
my $hostName = $item->key;
|
|
||||||
system("/usr/bin/sudo -u amgmt /usr/bin/ssh -o StrictHostKeyChecking=no amgmt\@$hostName /usr/bin/sudo /sbin/reboot &") == 0
|
|
||||||
or die "Error rebooting $hostName";
|
|
||||||
}
|
|
||||||
|
|
||||||
exit 0;
|
|
@ -1,34 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
package esmith;
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Errno;
|
|
||||||
use esmith::DB::db;
|
|
||||||
use IO::File;
|
|
||||||
use English;
|
|
||||||
|
|
||||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
|
||||||
|
|
||||||
my $event = $ARGV[0];
|
|
||||||
|
|
||||||
defined $ARGV[1] || die "No host specified";
|
|
||||||
my $host = $ARGV[1];
|
|
||||||
|
|
||||||
shutdown_host($host);
|
|
||||||
|
|
||||||
exit 0;
|
|
||||||
|
|
||||||
sub shutdown_host
|
|
||||||
{
|
|
||||||
my ($hostName) = @_;
|
|
||||||
#------------------------------------------------------------
|
|
||||||
# Shutdown the host
|
|
||||||
#------------------------------------------------------------
|
|
||||||
|
|
||||||
my $h = $db_hosts->get($hostName) or die "No host record for $hostName";
|
|
||||||
|
|
||||||
system("/usr/bin/sudo -u amgmt /usr/bin/ssh -o StrictHostKeyChecking=no amgmt\@$hostName /usr/bin/sudo /sbin/poweroff") == 0
|
|
||||||
or die "Error shutting down $hostName";
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
package esmith;
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Errno;
|
|
||||||
use esmith::DB::db;
|
|
||||||
use IO::File;
|
|
||||||
use English;
|
|
||||||
|
|
||||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
|
||||||
|
|
||||||
my @items = $db_hosts->get_all('local');
|
|
||||||
foreach my $item (@items) {
|
|
||||||
my $hostName = $item->key;
|
|
||||||
system("/usr/bin/sudo -u amgmt /usr/bin/ssh -o StrictHostKeyChecking=no amgmt\@$hostName /usr/bin/sudo /sbin/poweroff &") == 0
|
|
||||||
or die "Error shutting down $hostName";
|
|
||||||
}
|
|
||||||
|
|
||||||
exit 0;
|
|
@ -1,35 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
package esmith;
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Errno;
|
|
||||||
use esmith::DB::db;
|
|
||||||
use IO::File;
|
|
||||||
use English;
|
|
||||||
|
|
||||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
|
||||||
|
|
||||||
my $event = $ARGV[0];
|
|
||||||
|
|
||||||
defined $ARGV[1] || die "No host specified";
|
|
||||||
my $host = $ARGV[1];
|
|
||||||
|
|
||||||
wake_host($host);
|
|
||||||
|
|
||||||
exit 0;
|
|
||||||
|
|
||||||
sub wake_host
|
|
||||||
{
|
|
||||||
my ($hostName) = @_;
|
|
||||||
#------------------------------------------------------------
|
|
||||||
# Wake up the host
|
|
||||||
#------------------------------------------------------------
|
|
||||||
|
|
||||||
my @h = $db_hosts->get($hostName) or die "No host record for $hostName";
|
|
||||||
my $client = $h[0];
|
|
||||||
my $mac = $client->prop('MacAddress');
|
|
||||||
system("/sbin/ether-wake -b -i lan0 $mac") == 0
|
|
||||||
or die "Error waking up $hostName";
|
|
||||||
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
package esmith;
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Errno;
|
|
||||||
use esmith::DB::db;
|
|
||||||
use IO::File;
|
|
||||||
use English;
|
|
||||||
|
|
||||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
|
||||||
|
|
||||||
my @items = $db_hosts->get_all('local');
|
|
||||||
foreach my $item (@items) {
|
|
||||||
my $hostName = $item->key;
|
|
||||||
my $mac = $item->prop('MacAddress');
|
|
||||||
system("/sbin/ether-wake -b -i lan0 $mac &") == 0
|
|
||||||
or die "Error waking up $hostName";
|
|
||||||
}
|
|
||||||
|
|
||||||
exit 0;
|
|
@ -1 +0,0 @@
|
|||||||
../actions/doraemon-reboot-all
|
|
@ -1 +0,0 @@
|
|||||||
../actions/doraemon-reboot
|
|
@ -1 +0,0 @@
|
|||||||
../actions/doraemon-shutdown-all
|
|
@ -1 +0,0 @@
|
|||||||
../actions/doraemon-shutdown
|
|
@ -1 +0,0 @@
|
|||||||
../actions/doraemon-wake-all
|
|
@ -1 +0,0 @@
|
|||||||
../actions/doraemon-wake
|
|
@ -1,3 +0,0 @@
|
|||||||
TEMPLATE_PATH='upstart-job'
|
|
||||||
OUTPUT_FILENAME='/etc/init/doraemon.conf'
|
|
||||||
MORE_DATA={ name => 'doraemon', description => 'Apache instance that runs the doraemon service', author => 'Paolo Asperti <paolo@asperti.com>', daemon_bin => '/usr/sbin/doraemon', daemon_args => '-f /etc/httpd/doraemon/httpd.conf', respawn => 1, 'expect' => 'fork', stop_on => 'stopping network', start_on => 'started network' }
|
|
@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
#
|
|
||||||
# 00template_defaults
|
|
||||||
#
|
|
||||||
|
|
||||||
$localAccess = '';
|
|
||||||
$port = ${'doraemon'}{TCPPort} || "3000";
|
|
||||||
|
|
||||||
"";
|
|
||||||
}
|
|
@ -1,127 +0,0 @@
|
|||||||
{
|
|
||||||
|
|
||||||
$OUT .= <<HERE;
|
|
||||||
Listen $port
|
|
||||||
HostnameLookups off
|
|
||||||
|
|
||||||
ServerAdmin root@$DomainName
|
|
||||||
ServerRoot /etc/httpd
|
|
||||||
ServerTokens ProductOnly
|
|
||||||
|
|
||||||
User srvmgr
|
|
||||||
Group srvmgr
|
|
||||||
|
|
||||||
ErrorLog /var/log/doraemon/error_log
|
|
||||||
LogLevel warn
|
|
||||||
HERE
|
|
||||||
|
|
||||||
foreach (qw(
|
|
||||||
env
|
|
||||||
log_config
|
|
||||||
mime
|
|
||||||
negotiation
|
|
||||||
include
|
|
||||||
autoindex
|
|
||||||
dir
|
|
||||||
alias
|
|
||||||
rewrite
|
|
||||||
access
|
|
||||||
authz_host
|
|
||||||
expires
|
|
||||||
headers
|
|
||||||
setenvif
|
|
||||||
ssl
|
|
||||||
))
|
|
||||||
{
|
|
||||||
next unless -f "/usr/lib/httpd/modules/mod_${_}.so" ||
|
|
||||||
-f "/usr/lib64/httpd/modules/mod_${_}.so";
|
|
||||||
$OUT .= "LoadModule ${_}_module modules/mod_${_}.so\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$OUT .= <<HERE;
|
|
||||||
PidFile /var/run/doraemon.pid
|
|
||||||
ScoreBoardFile /var/run/doraemon.scoreboard
|
|
||||||
UseCanonicalName off
|
|
||||||
LogFormat "%h %l %u %t \\"%r\\" %>s %b" common
|
|
||||||
LogFormat "%{User-agent}i" agent
|
|
||||||
|
|
||||||
CustomLog /var/log/doraemon/access_log common
|
|
||||||
|
|
||||||
KeepAlive On
|
|
||||||
MaxKeepAliveRequests 100
|
|
||||||
KeepAliveTimeout 15
|
|
||||||
|
|
||||||
MaxClients 150
|
|
||||||
MaxRequestsPerChild 100
|
|
||||||
|
|
||||||
MinSpareServers 1
|
|
||||||
MaxSpareServers 5
|
|
||||||
StartServers 1
|
|
||||||
Timeout 300
|
|
||||||
|
|
||||||
DefaultIcon /icons/unknown.gif
|
|
||||||
DirectoryIndex index.htm index.html index.shtml index.cgi
|
|
||||||
IndexOptions FancyIndexing VersionSort NameWidth=*
|
|
||||||
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
|
|
||||||
AccessFileName .htaccess
|
|
||||||
|
|
||||||
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
|
|
||||||
AddIconByType (TXT,/icons/text.gif) text/*
|
|
||||||
AddIconByType (IMG,/icons/image2.gif) image/*
|
|
||||||
AddIconByType (SND,/icons/sound2.gif) audio/*
|
|
||||||
AddIconByType (VID,/icons/movie.gif) video/*
|
|
||||||
DefaultType text/plain
|
|
||||||
TypesConfig /etc/mime.types
|
|
||||||
|
|
||||||
AddEncoding x-compress Z
|
|
||||||
AddEncoding x-gzip gz
|
|
||||||
|
|
||||||
AddIcon /icons/binary.gif .bin .exe
|
|
||||||
AddIcon /icons/binhex.gif .hqx
|
|
||||||
AddIcon /icons/tar.gif .tar
|
|
||||||
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
|
|
||||||
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
|
|
||||||
AddIcon /icons/a.gif .ps .ai .eps
|
|
||||||
AddIcon /icons/layout.gif .html .shtml .htm .pdf
|
|
||||||
AddIcon /icons/text.gif .txt
|
|
||||||
AddIcon /icons/c.gif .c
|
|
||||||
AddIcon /icons/p.gif .pl .py
|
|
||||||
AddIcon /icons/f.gif .for
|
|
||||||
AddIcon /icons/dvi.gif .dvi
|
|
||||||
AddIcon /icons/uuencoded.gif .uu
|
|
||||||
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
|
|
||||||
AddIcon /icons/tex.gif .tex
|
|
||||||
AddIcon /icons/bomb.gif core
|
|
||||||
|
|
||||||
AddIcon /icons/back.gif ..
|
|
||||||
AddIcon /icons/hand.right.gif README
|
|
||||||
AddIcon /icons/folder.gif ^^DIRECTORY^^
|
|
||||||
AddIcon /icons/blank.gif ^^BLANKICON^^
|
|
||||||
|
|
||||||
AddLanguage en .en
|
|
||||||
AddLanguage fr .fr
|
|
||||||
AddLanguage de .de
|
|
||||||
AddLanguage da .da
|
|
||||||
AddLanguage el .el
|
|
||||||
AddLanguage it .it
|
|
||||||
|
|
||||||
LanguagePriority en it de fr
|
|
||||||
|
|
||||||
AddType text/html .shtml
|
|
||||||
AddType application/x-pkcs7-crl .crl
|
|
||||||
|
|
||||||
AddType application/x-x509-ca-cert .crt
|
|
||||||
|
|
||||||
BrowserMatch "Mozilla/2" nokeepalive
|
|
||||||
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
|
|
||||||
BrowserMatch "RealPlayer 4\.0" force-response-1.0
|
|
||||||
BrowserMatch "Java/1\.0" force-response-1.0
|
|
||||||
BrowserMatch "JDK/1\.0" force-response-1.0
|
|
||||||
|
|
||||||
AddHandler cgi-script .cgi
|
|
||||||
AddHandler server-parsed .shtml
|
|
||||||
AddHandler imap-file map
|
|
||||||
|
|
||||||
HERE
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
# First, we configure the "default" to be a very restrictive set of
|
|
||||||
# permissions.
|
|
||||||
|
|
||||||
<Directory />
|
|
||||||
Options None
|
|
||||||
AllowOverride None
|
|
||||||
order deny,allow
|
|
||||||
deny from all
|
|
||||||
allow from none
|
|
||||||
</Directory>
|
|
||||||
|
|
||||||
<Directory /var/www/icons>
|
|
||||||
Allow from all
|
|
||||||
</Directory>
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
|||||||
|
|
||||||
DocumentRoot /usr/share/doraemon
|
|
||||||
Alias /icons/ /var/www/icons/
|
|
||||||
|
|
||||||
<Directory /usr/share/doraemon/>
|
|
||||||
Options +Indexes
|
|
||||||
Order Deny,Allow
|
|
||||||
Deny from all
|
|
||||||
Allow from { $localAccess || 'all' }
|
|
||||||
AddType application/x-httpd-php .php
|
|
||||||
Options +FollowSymlinks
|
|
||||||
RewriteEngine on
|
|
||||||
RewriteBase /
|
|
||||||
RewriteRule ^(js/|fonts/|css/|images/|icons/|.+\.php) - [PT,L]
|
|
||||||
RewriteRule ^favicon.ico$ images/favicon.ico [L]
|
|
||||||
RewriteRule ^(.*)$ index.php/$1 [L]
|
|
||||||
php_value session.save_path /var/cache/doraemon
|
|
||||||
php_flag magic_quotes_gpc off
|
|
||||||
</Directory>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
Include conf.d/php.conf
|
|
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
$OUT = 'srvmgr ALL=NOPASSWD: /bin/cat ';
|
|
||||||
|
|
||||||
use esmith::ConfigDB;
|
|
||||||
my $confdb = esmith::ConfigDB->open;
|
|
||||||
my $backup = $confdb->get('doraemon') or die "No doraemon db entry found\n";
|
|
||||||
my $VaultPassFile = $backup->prop('VaultPassFile') || '/home/amgmt/.ansible/vault.txt';
|
|
||||||
my $ManagementKeyFile = $backup->prop('ManagementKeyFile') || '/home/amgmt/.ssh/id_rsa.pub';
|
|
||||||
my $DomainFile = $backup->prop('DomainFile') || '/etc/domain.yml';
|
|
||||||
|
|
||||||
$OUT = 'srvmgr ALL=NOPASSWD: /bin/cat ' . $VaultPassFile . '
|
|
||||||
srvmgr ALL=NOPASSWD: /bin/cat ' . $ManagementKeyFile .'
|
|
||||||
srvmgr ALL=NOPASSWD: /bin/cat ' . $DomainFile;
|
|
||||||
|
|
||||||
}
|
|
@ -1,162 +0,0 @@
|
|||||||
# ================= DO NOT MODIFY THIS FILE =================
|
|
||||||
#
|
|
||||||
# Manual changes will be lost when this file is regenerated.
|
|
||||||
#
|
|
||||||
# Please read the developer's guide, which is available
|
|
||||||
# at https://dev.nethesis.it/projects/nethserver/wiki/NethServer
|
|
||||||
# original work from http://www.contribs.org/development/
|
|
||||||
#
|
|
||||||
# Copyright (C) 2013 Nethesis S.r.l.
|
|
||||||
# http://www.nethesis.it - support@nethesis.it
|
|
||||||
#
|
|
||||||
Listen 3000
|
|
||||||
HostnameLookups off
|
|
||||||
|
|
||||||
ServerAdmin root
|
|
||||||
ServerRoot /etc/httpd
|
|
||||||
ServerTokens ProductOnly
|
|
||||||
|
|
||||||
User srvmgr
|
|
||||||
Group srvmgr
|
|
||||||
|
|
||||||
ErrorLog /var/log/doraemon/error_log
|
|
||||||
LogLevel warn
|
|
||||||
LoadModule env_module modules/mod_env.so
|
|
||||||
LoadModule log_config_module modules/mod_log_config.so
|
|
||||||
LoadModule mime_module modules/mod_mime.so
|
|
||||||
LoadModule negotiation_module modules/mod_negotiation.so
|
|
||||||
LoadModule include_module modules/mod_include.so
|
|
||||||
LoadModule autoindex_module modules/mod_autoindex.so
|
|
||||||
LoadModule dir_module modules/mod_dir.so
|
|
||||||
LoadModule alias_module modules/mod_alias.so
|
|
||||||
LoadModule rewrite_module modules/mod_rewrite.so
|
|
||||||
LoadModule authz_host_module modules/mod_authz_host.so
|
|
||||||
LoadModule expires_module modules/mod_expires.so
|
|
||||||
LoadModule headers_module modules/mod_headers.so
|
|
||||||
LoadModule setenvif_module modules/mod_setenvif.so
|
|
||||||
LoadModule ssl_module modules/mod_ssl.so
|
|
||||||
PidFile /var/run/doraemon.pid
|
|
||||||
ScoreBoardFile /var/run/doraemon.scoreboard
|
|
||||||
UseCanonicalName off
|
|
||||||
LogFormat "%h %l %u %t \"%r\" %>s %b" common
|
|
||||||
LogFormat "%{User-agent}i" agent
|
|
||||||
|
|
||||||
CustomLog /var/log/doraemon/access_log common
|
|
||||||
|
|
||||||
KeepAlive On
|
|
||||||
MaxKeepAliveRequests 100
|
|
||||||
KeepAliveTimeout 15
|
|
||||||
|
|
||||||
MaxClients 150
|
|
||||||
MaxRequestsPerChild 100
|
|
||||||
|
|
||||||
MinSpareServers 1
|
|
||||||
MaxSpareServers 5
|
|
||||||
StartServers 1
|
|
||||||
Timeout 300
|
|
||||||
|
|
||||||
DefaultIcon /icons/unknown.gif
|
|
||||||
DirectoryIndex index.htm index.html index.shtml index.cgi
|
|
||||||
IndexOptions FancyIndexing VersionSort NameWidth=*
|
|
||||||
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
|
|
||||||
AccessFileName .htaccess
|
|
||||||
|
|
||||||
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
|
|
||||||
AddIconByType (TXT,/icons/text.gif) text/*
|
|
||||||
AddIconByType (IMG,/icons/image2.gif) image/*
|
|
||||||
AddIconByType (SND,/icons/sound2.gif) audio/*
|
|
||||||
AddIconByType (VID,/icons/movie.gif) video/*
|
|
||||||
DefaultType text/plain
|
|
||||||
TypesConfig /etc/mime.types
|
|
||||||
|
|
||||||
AddEncoding x-compress Z
|
|
||||||
AddEncoding x-gzip gz
|
|
||||||
|
|
||||||
AddIcon /icons/binary.gif .bin .exe
|
|
||||||
AddIcon /icons/binhex.gif .hqx
|
|
||||||
AddIcon /icons/tar.gif .tar
|
|
||||||
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
|
|
||||||
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
|
|
||||||
AddIcon /icons/a.gif .ps .ai .eps
|
|
||||||
AddIcon /icons/layout.gif .html .shtml .htm .pdf
|
|
||||||
AddIcon /icons/text.gif .txt
|
|
||||||
AddIcon /icons/c.gif .c
|
|
||||||
AddIcon /icons/p.gif .pl .py
|
|
||||||
AddIcon /icons/f.gif .for
|
|
||||||
AddIcon /icons/dvi.gif .dvi
|
|
||||||
AddIcon /icons/uuencoded.gif .uu
|
|
||||||
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
|
|
||||||
AddIcon /icons/tex.gif .tex
|
|
||||||
AddIcon /icons/bomb.gif core
|
|
||||||
|
|
||||||
AddIcon /icons/back.gif ..
|
|
||||||
AddIcon /icons/hand.right.gif README
|
|
||||||
AddIcon /icons/folder.gif ^^DIRECTORY^^
|
|
||||||
AddIcon /icons/blank.gif ^^BLANKICON^^
|
|
||||||
|
|
||||||
AddLanguage en .en
|
|
||||||
AddLanguage fr .fr
|
|
||||||
AddLanguage de .de
|
|
||||||
AddLanguage da .da
|
|
||||||
AddLanguage el .el
|
|
||||||
AddLanguage it .it
|
|
||||||
|
|
||||||
LanguagePriority en it de fr
|
|
||||||
|
|
||||||
AddType text/html .shtml
|
|
||||||
AddType application/x-pkcs7-crl .crl
|
|
||||||
|
|
||||||
AddType application/x-x509-ca-cert .crt
|
|
||||||
|
|
||||||
BrowserMatch "Mozilla/2" nokeepalive
|
|
||||||
BrowserMatch "MSIE 4.0b2;" nokeepalive downgrade-1.0 force-response-1.0
|
|
||||||
BrowserMatch "RealPlayer 4.0" force-response-1.0
|
|
||||||
BrowserMatch "Java/1.0" force-response-1.0
|
|
||||||
BrowserMatch "JDK/1.0" force-response-1.0
|
|
||||||
|
|
||||||
AddHandler cgi-script .cgi
|
|
||||||
AddHandler server-parsed .shtml
|
|
||||||
AddHandler imap-file map
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# First, we configure the "default" to be a very restrictive set of
|
|
||||||
# permissions.
|
|
||||||
|
|
||||||
<Directory />
|
|
||||||
Options None
|
|
||||||
AllowOverride None
|
|
||||||
order deny,allow
|
|
||||||
deny from all
|
|
||||||
allow from none
|
|
||||||
</Directory>
|
|
||||||
|
|
||||||
<Directory /var/www/icons>
|
|
||||||
Allow from all
|
|
||||||
</Directory>
|
|
||||||
|
|
||||||
|
|
||||||
DocumentRoot /usr/share/doraemon
|
|
||||||
Alias /icons/ /var/www/icons/
|
|
||||||
|
|
||||||
<Directory /usr/share/doraemon/>
|
|
||||||
Options +Indexes
|
|
||||||
Order Deny,Allow
|
|
||||||
Deny from all
|
|
||||||
Allow from all
|
|
||||||
AddType application/x-httpd-php .php
|
|
||||||
Options +FollowSymlinks
|
|
||||||
RewriteEngine on
|
|
||||||
RewriteBase /
|
|
||||||
RewriteRule ^(js/|fonts/|css/|images/|icons/|.+\.php) - [PT,L]
|
|
||||||
RewriteRule ^favicon.ico$ images/favicon.ico [L]
|
|
||||||
RewriteRule ^(.*)$ index.php/$1 [L]
|
|
||||||
php_value session.save_path /var/cache/doraemon
|
|
||||||
php_flag magic_quotes_gpc off
|
|
||||||
</Directory>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Include conf.d/php.conf
|
|
@ -1,12 +0,0 @@
|
|||||||
#
|
|
||||||
# doraemon-reload task
|
|
||||||
#
|
|
||||||
# Signals an Apache graceful restart for doraemon instance
|
|
||||||
#
|
|
||||||
|
|
||||||
# service job, runs asynchronously
|
|
||||||
|
|
||||||
script
|
|
||||||
sleep 5
|
|
||||||
exec /usr/sbin/doraemon -f /etc/httpd/doraemon/httpd.conf -k graceful
|
|
||||||
end script
|
|
@ -1,42 +0,0 @@
|
|||||||
# ================= DO NOT MODIFY THIS FILE =================
|
|
||||||
#
|
|
||||||
# Manual changes will be lost when this file is regenerated.
|
|
||||||
#
|
|
||||||
# Please read the developer's guide, which is available
|
|
||||||
# at https://dev.nethesis.it/projects/nethserver/wiki/NethServer
|
|
||||||
# original work from http://www.contribs.org/development/
|
|
||||||
#
|
|
||||||
# Copyright (C) 2013 Nethesis S.r.l.
|
|
||||||
# http://www.nethesis.it - support@nethesis.it
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# 10base doraemon - Apache instance that runs the doraemon service
|
|
||||||
#
|
|
||||||
|
|
||||||
description "Apache instance that runs the doraemon service"
|
|
||||||
author "Paolo Asperti <paolo@asperti.com>"
|
|
||||||
respawn
|
|
||||||
respawn limit 10 5
|
|
||||||
expect fork
|
|
||||||
start on started network
|
|
||||||
stop on stopping network
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# 20pre_start
|
|
||||||
#
|
|
||||||
pre-start script
|
|
||||||
STAT=`/sbin/e-smith/config getprop doraemon status`
|
|
||||||
if test "x$STAT" = "xenabled" \
|
|
||||||
-a -f "/etc/e-smith/db/configuration/defaults/doraemon/status" \
|
|
||||||
-a -x /usr/sbin/doraemon; then
|
|
||||||
exit 0;
|
|
||||||
fi
|
|
||||||
stop; exit 0;
|
|
||||||
end script
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# 30script
|
|
||||||
#
|
|
||||||
exec /usr/sbin/doraemon -f /etc/httpd/doraemon/httpd.conf
|
|
@ -1,9 +0,0 @@
|
|||||||
/var/log/doraemon/*log {
|
|
||||||
missingok
|
|
||||||
notifempty
|
|
||||||
sharedscripts
|
|
||||||
delaycompress
|
|
||||||
postrotate
|
|
||||||
/sbin/reload doraemon > /dev/null 2>/dev/null || true
|
|
||||||
endscript
|
|
||||||
}
|
|
@ -1,391 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2011 Nethesis S.r.l.
|
|
||||||
*
|
|
||||||
* This script is part of NethServer.
|
|
||||||
*
|
|
||||||
* NethServer is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* NethServer 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 NethServer. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read and write parameters into SME DB
|
|
||||||
*
|
|
||||||
* Ths class implements an interface to SME database executing the command /sbin/e-smith/db with sudo.
|
|
||||||
* The class needs /etc/sudoers configurazione. In the sudoers file you must have something like this:
|
|
||||||
* <code>
|
|
||||||
* Cmnd_Alias SME = /sbin/e-smith/db, /sbin/e-smith/signal-event
|
|
||||||
* www ALL=NOPASSWD: SME
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author Giacomo Sanchietti <giacomo.sanchietti@nethesis.it>
|
|
||||||
* @author Davide Principi <davide.principi@nethesis.it>
|
|
||||||
* @since 1.0
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
class EsmithDatabase
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var SME DB database command
|
|
||||||
* */
|
|
||||||
private $command = "/usr/bin/sudo /sbin/e-smith/db";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var $db Database name, it's translated into the db file path. For example: /home/e-smith/db/testdb
|
|
||||||
* */
|
|
||||||
private $db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This static class variable shares a socket connection to smwingsd
|
|
||||||
*
|
|
||||||
* @var resource
|
|
||||||
*/
|
|
||||||
private static $socket;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct an object to access a SME Configuration database file
|
|
||||||
* with $user's privileges.
|
|
||||||
*
|
|
||||||
* @param string $database Database name
|
|
||||||
*/
|
|
||||||
public function __construct($database)
|
|
||||||
{
|
|
||||||
if ( ! $database)
|
|
||||||
sprintf("%s: You must provide a valid database name.", get_class($this));
|
|
||||||
|
|
||||||
$this->db = $database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAll($type = NULL)
|
|
||||||
{
|
|
||||||
$output = "";
|
|
||||||
|
|
||||||
$ret = $this->dbRead('getjson', array(), $output);
|
|
||||||
if ($ret !== 0) {
|
|
||||||
sprintf("%s: internal database command failed!", __CLASS__);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = json_decode($output, TRUE);
|
|
||||||
if ( ! is_array($data)) {
|
|
||||||
sprintf("%s: unexpected json string `%s`", __CLASS__, substr($output, 0, 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = array();
|
|
||||||
|
|
||||||
foreach ($data as $item) {
|
|
||||||
// Apply type check filter:
|
|
||||||
if (isset($type) && $type !== $item['type']) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$props = isset($item['props']) ? $item['props'] : array();
|
|
||||||
$result[$item['name']] = array_merge($props, array('type' => $item['type']));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllByProp($propName = NULL, $propValue = NULL)
|
|
||||||
{
|
|
||||||
$output = "";
|
|
||||||
|
|
||||||
$ret = $this->dbRead('getjson', array(), $output);
|
|
||||||
if ($ret !== 0) {
|
|
||||||
sprintf("%s: internal database command failed!", __CLASS__);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = json_decode($output, TRUE);
|
|
||||||
if ( ! is_array($data)) {
|
|
||||||
sprintf("%s: unexpected json string `%s`", __CLASS__, substr($output, 0, 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = array();
|
|
||||||
|
|
||||||
foreach ($data as $item) {
|
|
||||||
$item['props']['type'] = $item['type'];
|
|
||||||
$item['props']['name'] = $item['name'];
|
|
||||||
|
|
||||||
if (isset($propName) && isset($propValue)) {
|
|
||||||
if (isset($item['props'][$propName]) && $propValue == $item['props'][$propName]) {
|
|
||||||
$result[$item['name']] = $item['props'];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result[$item['name']] = $item['props'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getKey($key)
|
|
||||||
{
|
|
||||||
$output = '';
|
|
||||||
|
|
||||||
$ret = $this->dbRead('getjson', array($key), $output);
|
|
||||||
if ($ret !== 0) {
|
|
||||||
sprintf("%s: internal database command failed", __CLASS__);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = json_decode($output, TRUE);
|
|
||||||
|
|
||||||
if ($data === 1) {
|
|
||||||
// Key has not been found
|
|
||||||
return array();
|
|
||||||
} elseif ( ! is_array($data)) {
|
|
||||||
sprintf("%s: unexpected json string `%s`", __CLASS__, substr($output, 0, 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['props']['type'] = $data['type'];
|
|
||||||
$data['props']['name'] = $data['name'];
|
|
||||||
return $data['props'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getKeyValue($key)
|
|
||||||
{
|
|
||||||
$output = '';
|
|
||||||
|
|
||||||
$ret = $this->dbRead('getjson', array($key), $output);
|
|
||||||
if ($ret !== 0) {
|
|
||||||
sprintf("%s: internal database command failed", __CLASS__);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = json_decode($output, TRUE);
|
|
||||||
|
|
||||||
if ($data === 1) {
|
|
||||||
// Key has not been found
|
|
||||||
return array();
|
|
||||||
} elseif ( ! is_array($data)) {
|
|
||||||
sprintf("%s: unexpected json string `%s`", __CLASS__, substr($output, 0, 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data['type'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setKey($key, $type, $props)
|
|
||||||
{
|
|
||||||
$output = NULL;
|
|
||||||
$ret = $this->dbExec('set', $this->prepareArguments($key, $type, $props), $output);
|
|
||||||
return ($ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteKey($key)
|
|
||||||
{
|
|
||||||
$output = NULL;
|
|
||||||
$output = NULL;
|
|
||||||
$ret = $this->dbExec('delete', $this->prepareArguments($key), $output);
|
|
||||||
return ($ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the type of a key
|
|
||||||
* Act like: /sbin/e-smith/db dbfile gettype key
|
|
||||||
*
|
|
||||||
* @param string $key the key to retrieve
|
|
||||||
* @access public
|
|
||||||
* @return string the type of the key
|
|
||||||
*/
|
|
||||||
public function getType($key)
|
|
||||||
{
|
|
||||||
$output = NULL;
|
|
||||||
$ret = $this->dbRead('gettype', array($key), $output);
|
|
||||||
return trim($output);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the type of a key
|
|
||||||
* Act like: /sbin/e-smith/db dbfile settype key type
|
|
||||||
*
|
|
||||||
* @param string $key the key to change
|
|
||||||
* @param string $type the new type
|
|
||||||
* @access public
|
|
||||||
* @return bool true on success, FALSE otherwise
|
|
||||||
*/
|
|
||||||
public function setType($key, $type)
|
|
||||||
{
|
|
||||||
$output = NULL;
|
|
||||||
$ret = $this->dbExec('settype', $this->prepareArguments($key, $type), $output);
|
|
||||||
return ($ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProp($key, $prop)
|
|
||||||
{
|
|
||||||
$output = NULL;
|
|
||||||
$ret = $this->dbRead('getprop', array($key, $prop), $output);
|
|
||||||
return trim($output);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setProp($key, $props)
|
|
||||||
{
|
|
||||||
$output = NULL;
|
|
||||||
$ret = $this->dbExec('setprop', $this->prepareArguments($key, $props), $output);
|
|
||||||
return ($ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delProp($key, $props)
|
|
||||||
{
|
|
||||||
$output = NULL;
|
|
||||||
$ret = $this->dbExec('delprop', array_merge(array($key), array_values($props)), $output);
|
|
||||||
return ($ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the db command
|
|
||||||
* @param string $command The command to invoke
|
|
||||||
* @param array $args The command arguments
|
|
||||||
* @param string &$output The output from the command process
|
|
||||||
* @return int The command exit code
|
|
||||||
*/
|
|
||||||
private function dbExec($command, $args, &$output)
|
|
||||||
{
|
|
||||||
// prepend the database name and command
|
|
||||||
array_unshift($args, $this->db, $command);
|
|
||||||
$exitCode = 0;
|
|
||||||
$oArr = array();
|
|
||||||
exec($this->command . ' ' . implode(' ', array_map('escapeshellarg', $args)), $oArr, $exitCode);
|
|
||||||
$output = implode("\n", $oArr);
|
|
||||||
return $exitCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read db data from memory cache daemon
|
|
||||||
* @param string $command The command to invoke
|
|
||||||
* @param array $args The command arguments
|
|
||||||
* @param string &$output The output from the read socket
|
|
||||||
* @return int The command exit code
|
|
||||||
*/
|
|
||||||
private function dbRead($command, $args, &$output)
|
|
||||||
{
|
|
||||||
if ( ! isset(self::$socket) ) {
|
|
||||||
$socketPath = '/var/run/smwingsd.sock';
|
|
||||||
$errno = 0;
|
|
||||||
$errstr = '';
|
|
||||||
self::$socket = fsockopen('unix://' . $socketPath, -1, $errno, $errstr);
|
|
||||||
if( ! is_resource(self::$socket)) {
|
|
||||||
sprintf("Invalid socket (%d): %s. Fall back to exec().", $errno, $errstr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! is_resource(self::$socket)) {
|
|
||||||
return $this->dbExec($command, call_user_func_array(array($this, 'prepareArguments'), $args), $output);
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepend the database name and command
|
|
||||||
array_unshift($args, $this->db, $command);
|
|
||||||
|
|
||||||
$ret = $this->sendMessage(self::$socket, 0x10, $args);
|
|
||||||
if ( ! $ret ) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
$ret = $this->recvMessage(self::$socket);
|
|
||||||
if ( ! $ret ) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if ($command === 'getjson') {
|
|
||||||
$output = $ret;
|
|
||||||
} else {
|
|
||||||
$output = json_decode($ret, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function sendMessage($socket, $type, $args = array())
|
|
||||||
{
|
|
||||||
$payload = json_encode($args);
|
|
||||||
$data = pack('CN', (int) $type, strlen($payload)) . $payload;
|
|
||||||
$written = fwrite($socket, $data);
|
|
||||||
if ($written !== strlen($data)) {
|
|
||||||
echo 'Socket write error';
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function recvMessage($socket)
|
|
||||||
{
|
|
||||||
$buf = $this->safeRead($socket, 5);
|
|
||||||
if ($buf === FALSE) {
|
|
||||||
echo 'Socket read error';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$header = unpack('Ctype/Nsize', $buf);
|
|
||||||
if ( ! is_array($header)) {
|
|
||||||
echo 'Invalid message header';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$message = $this->safeRead($socket, $header['size']);
|
|
||||||
if ($message === FALSE) {
|
|
||||||
echo 'Socket read error';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($header['type'] & 0x02) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $message;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function safeRead($socket, $size)
|
|
||||||
{
|
|
||||||
$buffer = "";
|
|
||||||
$count = 0;
|
|
||||||
while($count < $size) {
|
|
||||||
if(feof($socket)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
$chunk = fread($socket, $size - $count);
|
|
||||||
$count += strlen($chunk);
|
|
||||||
if($chunk === FALSE) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
$buffer .= $chunk;
|
|
||||||
}
|
|
||||||
return $buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Take arbitrary arguments and flattenize to an array
|
|
||||||
*
|
|
||||||
* @param mixed $_
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function prepareArguments()
|
|
||||||
{
|
|
||||||
$args = array();
|
|
||||||
|
|
||||||
foreach (func_get_args() as $arg) {
|
|
||||||
if (is_array($arg)) {
|
|
||||||
foreach ($arg as $propName => $propValue) {
|
|
||||||
$args[] = $propName;
|
|
||||||
$args[] = $propValue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$args[] = (String) $arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $args;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,261 +0,0 @@
|
|||||||
<?php
|
|
||||||
include_once("EsmithDatabase.php");
|
|
||||||
define('CONFIG_KEY', 'doraemon');
|
|
||||||
|
|
||||||
$hosts_db = new EsmithDatabase('hosts');
|
|
||||||
$roles_db = new EsmithDatabase('roles');
|
|
||||||
$config_db = new EsmithDatabase('configuration');
|
|
||||||
|
|
||||||
$uri = $_SERVER['REQUEST_URI'];
|
|
||||||
// add leading '/' to uri string, works if $uri is empty
|
|
||||||
$uri = (substr($uri, 0, 1) == '/') ? $uri : '/' . $uri;
|
|
||||||
$pos = strpos($uri, '?');
|
|
||||||
if (false !== $pos) {
|
|
||||||
$route = substr($uri, 0, (int) $pos);
|
|
||||||
} else {
|
|
||||||
$route = $uri;
|
|
||||||
}
|
|
||||||
// remove trailing '/'
|
|
||||||
$route = rtrim($route, '/');
|
|
||||||
|
|
||||||
$query_string = $_SERVER['QUERY_STRING'];
|
|
||||||
$get_params = array();
|
|
||||||
parse_str($query_string, $get_params);
|
|
||||||
|
|
||||||
// determine internal function name (all lowercase, dash2underscore, named ROUTE_routename )
|
|
||||||
$function = preg_replace(':\-:', '_', strtolower($route));
|
|
||||||
$function = preg_replace(':^/:', 'ROUTE_', $function);
|
|
||||||
|
|
||||||
if (function_exists($function)) {
|
|
||||||
$function();
|
|
||||||
} else {
|
|
||||||
die('Go away.');
|
|
||||||
}
|
|
||||||
|
|
||||||
function varsForRole($role, $json=true) {
|
|
||||||
global $roles_db;
|
|
||||||
$result = $roles_db->getKey($role);
|
|
||||||
$return = array('role'=>$role,'delpkg'=>'','addpkg'=>'');
|
|
||||||
if (is_array($result)) {
|
|
||||||
if (is_string($result['Addpkg']))
|
|
||||||
$return['addpkg'] = preg_split("/[\s,]+/", $result['Addpkg']);
|
|
||||||
if (is_string($result['Delpkg']))
|
|
||||||
$return['delpkg'] = preg_split("/[\s,]+/", $result['Delpkg']);
|
|
||||||
}
|
|
||||||
if ($json) {
|
|
||||||
return json_encode($return);
|
|
||||||
} else {
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getClient($mac=false) {
|
|
||||||
global $hosts_db;
|
|
||||||
if (!$mac) {
|
|
||||||
$mac = getClientMac();
|
|
||||||
if (!$mac)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$hosts = $hosts_db->getAllByProp('MacAddress',$mac);
|
|
||||||
if (count($hosts)>0) {
|
|
||||||
return array_pop($hosts);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getClientMac($ip=false) {
|
|
||||||
if (false === $ip) {
|
|
||||||
$ip = $_SERVER['REMOTE_ADDR'];
|
|
||||||
}
|
|
||||||
$result = pingHost($ip,1);
|
|
||||||
if (!$result)
|
|
||||||
return false;
|
|
||||||
$macAddr=false;
|
|
||||||
$arptable=`arp -n $ip`;
|
|
||||||
$lines=explode("\n", $arptable);
|
|
||||||
foreach($lines as $line) {
|
|
||||||
$cols=preg_split('/\s+/', trim($line));
|
|
||||||
if ($cols[0]==$ip)
|
|
||||||
{
|
|
||||||
return $cols[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function newHostname($mac, $base, $role) {
|
|
||||||
global $config_db, $hosts_db;
|
|
||||||
if(!preg_match('/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/', $mac)) {
|
|
||||||
echo "invalid mac address";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($client=getClient($mac)) {
|
|
||||||
echo $client['name'];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$domainName = (string)$config_db->getKeyValue('DomainName');
|
|
||||||
$digits = $config_db->getProp(CONFIG_KEY,'NamingDigits');
|
|
||||||
$formatstring = '%s-%0'.$digits.'d';
|
|
||||||
$nr=0;
|
|
||||||
$hostname = '';
|
|
||||||
do {
|
|
||||||
$nr++;
|
|
||||||
$hostname = sprintf($formatstring, $base, $nr);
|
|
||||||
# TODO: we'll use the hostname in future, maybe
|
|
||||||
# if (trim($domainName) != '') {
|
|
||||||
# $hostname .= '.' . $domainName;
|
|
||||||
# }
|
|
||||||
} while ($hosts_db->getKey($hostname));
|
|
||||||
|
|
||||||
$hosts_db->setKey($hostname, 'local', array(
|
|
||||||
'MacAddress' => $mac,
|
|
||||||
'Role' => $role,
|
|
||||||
'Description' => ''
|
|
||||||
));
|
|
||||||
|
|
||||||
echo $hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
function pingHost($host, $timeout=1) {
|
|
||||||
$pingresult = exec("/bin/ping -c 1 -t 2 -W $timeout $host", $output, $retvar);
|
|
||||||
return (0 == $retvar);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ROUTE_domain() {
|
|
||||||
global $config_db;
|
|
||||||
$theFile = $config_db->getProp(CONFIG_KEY,'DomainFile');
|
|
||||||
passthru("/usr/bin/sudo /bin/cat $theFile");
|
|
||||||
}
|
|
||||||
|
|
||||||
function ROUTE_mgmtkey() {
|
|
||||||
global $config_db;
|
|
||||||
$theFile = $config_db->getProp(CONFIG_KEY,'ManagementKeyFile');
|
|
||||||
passthru("/usr/bin/sudo /bin/cat $theFile");
|
|
||||||
}
|
|
||||||
|
|
||||||
function ROUTE_epoptes_srv() {
|
|
||||||
global $hosts_db;
|
|
||||||
$hosts = $hosts_db->getAllByProp('Role','docenti');
|
|
||||||
ksort($hosts);
|
|
||||||
if (count($hosts) == 0) {
|
|
||||||
echo 'none';
|
|
||||||
} else {
|
|
||||||
$host = array_pop($hosts);
|
|
||||||
echo $host['name'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ROUTE_ansible_host() {
|
|
||||||
global $get_params;
|
|
||||||
if (isset($get_params['role'])) {
|
|
||||||
$role = $get_params['role'];
|
|
||||||
} elseif ($client = getClient()) {
|
|
||||||
$role = $client['Role'];
|
|
||||||
} else {
|
|
||||||
$role = 'unknown';
|
|
||||||
}
|
|
||||||
echo varsForRole($role);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ROUTE_hosts() {
|
|
||||||
global $hosts_db, $get_params;
|
|
||||||
if (isset($get_params['role'])) {
|
|
||||||
$items = $hosts_db->getAllByProp('Role', $get_params['role']);
|
|
||||||
} else {
|
|
||||||
$items = $hosts_db->getAll('local');
|
|
||||||
}
|
|
||||||
$results=array();
|
|
||||||
foreach ($items as $name=>$item) {
|
|
||||||
$results[]=array(
|
|
||||||
'mac'=>$item['MacAddress'],
|
|
||||||
'hostname'=>$name,
|
|
||||||
'role'=>$item['Role']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
echo json_encode($results);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ROUTE_ansible_list() {
|
|
||||||
global $get_params;
|
|
||||||
if (isset($get_params['role'])) {
|
|
||||||
$role = $get_params['role'];
|
|
||||||
} elseif ($client = getClient()) {
|
|
||||||
$role = $client['Role'];
|
|
||||||
} else {
|
|
||||||
$role = 'unknown';
|
|
||||||
}
|
|
||||||
$vars = varsForRole($role, false);
|
|
||||||
echo json_encode(array(
|
|
||||||
'localhost'=>array(
|
|
||||||
'hosts'=>array('localhost'),
|
|
||||||
'vars'=>array('ansible_connection'=>'local')
|
|
||||||
),
|
|
||||||
'_meta'=> array('hostvars'=>array('localhost'=>$vars))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
function ROUTE_vaultpass() {
|
|
||||||
global $config_db;
|
|
||||||
$theFile = $config_db->getProp(CONFIG_KEY,'VaultPassFile');
|
|
||||||
$oArr = array();
|
|
||||||
exec('/usr/bin/sudo /bin/cat ' . $theFile, $oArr, $exitCode);
|
|
||||||
$content = trim(implode("\n", $oArr));
|
|
||||||
if (false === $content) {
|
|
||||||
echo 'no file';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!$client = getClient()) {
|
|
||||||
echo 'no client';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$key = md5($client['name'], true);
|
|
||||||
$padlenght = 16 - (strlen($content) % 16);
|
|
||||||
$content_padded = $content . str_repeat('x', $padlenght);
|
|
||||||
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $content_padded, MCRYPT_MODE_ECB);
|
|
||||||
echo base64_encode($ciphertext);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ROUTE_whatsmyhostname() {
|
|
||||||
global $config_db, $get_params;
|
|
||||||
if (isset($get_params['role'])) {
|
|
||||||
$role = $get_params['role'];
|
|
||||||
} else {
|
|
||||||
$role = $config_db->getProp(CONFIG_KEY,'DefaultRole');
|
|
||||||
}
|
|
||||||
if (isset($get_params['base'])) {
|
|
||||||
$base = $get_params['base'];
|
|
||||||
} else {
|
|
||||||
$base = $config_db->getProp(CONFIG_KEY,'NamingBase');
|
|
||||||
}
|
|
||||||
$mac = getClientMac();
|
|
||||||
if (!$mac) {
|
|
||||||
echo 'no-mac-address';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
newHostname($mac, $base, $role);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ROUTE_mac2hostname() {
|
|
||||||
global $config_db, $get_params;
|
|
||||||
if (isset($get_params['mac'])) {
|
|
||||||
$mac = $get_params['mac'];
|
|
||||||
} else {
|
|
||||||
echo 'Usage: GET /mac2hostname?mac=XX_XX_XX_XX_XX_XX[&base=YYY][&role=ZZZ]';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (isset($get_params['role'])) {
|
|
||||||
$role = $get_params['role'];
|
|
||||||
} else {
|
|
||||||
$role = $config_db->getProp(CONFIG_KEY,'DefaultRole');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($get_params['base'])) {
|
|
||||||
$base = $get_params['base'];
|
|
||||||
} else {
|
|
||||||
$base = $config_db->getProp(CONFIG_KEY,'NamingBase');
|
|
||||||
}
|
|
||||||
|
|
||||||
newHostname($mac, $base, $role);
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/* /usr/share/nethesis/NethServer/Language/en/NethServer_Module_Doraemon.php */
|
|
||||||
|
|
||||||
$L['Doraemon_Title'] = 'Doraemon';
|
|
||||||
$L['hostname_label'] = 'Hostname';
|
|
||||||
$L['MacAddress_label'] = 'MAC Address';
|
|
||||||
$L['shutdown_label'] = 'Shutdown';
|
|
||||||
$L['reboot_label'] = 'Reboot';
|
|
||||||
$L['wake_label'] = 'Wake Up';
|
|
||||||
$L['shutdown-all_label'] = 'Shutdown all';
|
|
||||||
$L['reboot-all_label'] = 'Reboot all';
|
|
||||||
$L['wake-all_label'] = 'Wake Up all';
|
|
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/* /usr/share/nethesis/NethServer/Language/en/NethServer_Module_Doraemon_Hosts.php */
|
|
||||||
|
|
||||||
$L['Hosts_Title'] = 'Hosts';
|
|
||||||
$L['Create_Host_Header'] = 'Create a new host';
|
|
||||||
$L['Update_Host_Header'] = 'Update host "${0}"';
|
|
||||||
$L['Role_label'] = 'Role';
|
|
||||||
$L['Key_label'] = 'Hostname';
|
|
@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/* /usr/share/nethesis/NethServer/Language/it/NethServer_Module_Doraemon.php */
|
|
||||||
|
|
||||||
$L['Doraemon_Title'] = 'Doraemon';
|
|
||||||
$L['hostname_label'] = 'Hostname';
|
|
||||||
$L['MacAddress_label'] = 'MAC Address';
|
|
||||||
$L['shutdown_label'] = 'Spegni';
|
|
||||||
$L['reboot_label'] = 'Riavvia';
|
|
||||||
$L['wake_label'] = 'Accendi';
|
|
||||||
$L['shutdown-all_label'] = 'Spegni tutti';
|
|
||||||
$L['reboot-all_label'] = 'Riavvia tutti';
|
|
||||||
$L['wake-all_label'] = 'Accendi tutti';
|
|
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/* /usr/share/nethesis/NethServer/Language/it/NethServer_Module_Doraemon_Hosts.php */
|
|
||||||
|
|
||||||
$L['Hosts_Title'] = 'Hosts';
|
|
||||||
$L['Create_Host_Header'] = 'Crea un nuovo host';
|
|
||||||
$L['Update_Host_Header'] = 'Modifica il nome host "${0}"';
|
|
||||||
$L['Role_label'] = 'Ruolo';
|
|
||||||
$L['Key_label'] = 'Hostname';
|
|
@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace NethServer\Module;
|
|
||||||
|
|
||||||
class Doraemon extends \Nethgui\Controller\TabsController
|
|
||||||
{
|
|
||||||
protected function initializeAttributes(\Nethgui\Module\ModuleAttributesInterface $base)
|
|
||||||
{
|
|
||||||
return \Nethgui\Module\SimpleModuleAttributesProvider::extendModuleAttributes($base, 'Configuration', 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function initialize()
|
|
||||||
{
|
|
||||||
parent::initialize();
|
|
||||||
$this->loadChildrenDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace NethServer\Module\Doraemon;
|
|
||||||
|
|
||||||
|
|
||||||
class Hosts extends \Nethgui\Controller\TableController
|
|
||||||
{
|
|
||||||
|
|
||||||
public function initialize()
|
|
||||||
{
|
|
||||||
$columns = array(
|
|
||||||
'Key',
|
|
||||||
'MacAddress',
|
|
||||||
'Role',
|
|
||||||
'Actions',
|
|
||||||
);
|
|
||||||
|
|
||||||
$this
|
|
||||||
->setTableAdapter($this->getPlatform()->getTableAdapter('hosts', 'local'))
|
|
||||||
->setColumns($columns)
|
|
||||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\Modify('update'))
|
|
||||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\TogglePower('wake'))
|
|
||||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\TogglePower('reboot'))
|
|
||||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\TogglePower('shutdown'))
|
|
||||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\Modify('delete'))
|
|
||||||
->addTableAction(new \NethServer\Module\Doraemon\Hosts\Modify('create'))
|
|
||||||
->addTableAction(new \NethServer\Module\Doraemon\Hosts\TogglePowerAll('wake-all'))
|
|
||||||
->addTableAction(new \NethServer\Module\Doraemon\Hosts\TogglePowerAll('reboot-all'))
|
|
||||||
->addTableAction(new \NethServer\Module\Doraemon\Hosts\TogglePowerAll('shutdown-all'))
|
|
||||||
->addTableAction(new \Nethgui\Controller\Table\Help('Help'))
|
|
||||||
;
|
|
||||||
|
|
||||||
parent::initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace NethServer\Module\Doraemon\Hosts;
|
|
||||||
|
|
||||||
use Nethgui\System\PlatformInterface as Validate;
|
|
||||||
|
|
||||||
|
|
||||||
class Modify extends \Nethgui\Controller\Table\Modify
|
|
||||||
{
|
|
||||||
|
|
||||||
public function initialize()
|
|
||||||
{
|
|
||||||
$parameterSchema = array(
|
|
||||||
// was: Validate::HOSTNAME_FQDN, but we need hostname
|
|
||||||
array('hostname', Validate::HOSTNAME_SIMPLE, \Nethgui\Controller\Table\Modify::KEY),
|
|
||||||
array('MacAddress', Validate::MACADDRESS, \Nethgui\Controller\Table\Modify::FIELD),
|
|
||||||
array('Role', Validate::ANYTHING, \Nethgui\Controller\Table\Modify::FIELD),
|
|
||||||
// array('Role', Validate::ROLES_COLLECTION ??? TODO!!!, \Nethgui\Controller\Table\Modify::FIELD),
|
|
||||||
);
|
|
||||||
$this->setSchema($parameterSchema);
|
|
||||||
parent::initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function validate(\Nethgui\Controller\ValidationReportInterface $report)
|
|
||||||
{
|
|
||||||
if ($this->getIdentifier() === 'delete') {
|
|
||||||
$v = $this->createValidator()->platform('host-delete');
|
|
||||||
if ( ! $v->evaluate($this->parameters['hostname'])) {
|
|
||||||
$report->addValidationError($this, 'Key', $v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent::validate($report);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function onParametersSaved($parameters)
|
|
||||||
{
|
|
||||||
$actionName = $this->getIdentifier();
|
|
||||||
if ($actionName === 'update') {
|
|
||||||
$actionName = 'modify';
|
|
||||||
}
|
|
||||||
$this->getPlatform()->signalEvent(sprintf('host-%s &', $actionName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function prepareView(\Nethgui\View\ViewInterface $view)
|
|
||||||
{
|
|
||||||
parent::prepareView($view);
|
|
||||||
$templates = array(
|
|
||||||
'create' => 'NethServer\Template\Doraemon\Hosts',
|
|
||||||
'update' => 'NethServer\Template\Doraemon\Hosts',
|
|
||||||
'delete' => 'Nethgui\Template\Table\Delete',
|
|
||||||
);
|
|
||||||
$view->setTemplate($templates[$this->getIdentifier()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace NethServer\Module\Doraemon\Hosts;
|
|
||||||
|
|
||||||
use Nethgui\System\PlatformInterface as Validate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle host power status
|
|
||||||
*
|
|
||||||
* Fires events
|
|
||||||
* - doraemon-wake
|
|
||||||
* - doraemon-reboot
|
|
||||||
* - doraemon-shutdown
|
|
||||||
*/
|
|
||||||
class TogglePower extends \Nethgui\Controller\Table\AbstractAction
|
|
||||||
{
|
|
||||||
|
|
||||||
public function __construct($identifier = NULL)
|
|
||||||
{
|
|
||||||
if ($identifier !== 'wake' && $identifier !== 'reboot' && $identifier !== 'shutdown') {
|
|
||||||
throw new \InvalidArgumentException(sprintf('%s: module identifier must be one of "wake" or "reboot" or "shutdown".', get_class($this)), 1325579395);
|
|
||||||
}
|
|
||||||
parent::__construct($identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function bind(\Nethgui\Controller\RequestInterface $request)
|
|
||||||
{
|
|
||||||
$this->declareParameter('hostname', Validate::HOSTNAME_SIMPLE);
|
|
||||||
|
|
||||||
parent::bind($request);
|
|
||||||
$hostname = \Nethgui\array_end($request->getPath());
|
|
||||||
|
|
||||||
if ( ! $hostname) {
|
|
||||||
throw new \Nethgui\Exception\HttpException('Not found', 404, 1322148400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->parameters['hostname'] = $hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function process()
|
|
||||||
{
|
|
||||||
if ( ! $this->getRequest()->isMutation()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->getPlatform()->signalEvent(sprintf('doraemon-%s@post', $this->getIdentifier()), array($this->parameters['hostname']));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace NethServer\Module\Doraemon\Hosts;
|
|
||||||
|
|
||||||
use Nethgui\System\PlatformInterface as Validate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle host power status
|
|
||||||
*
|
|
||||||
* Fires events
|
|
||||||
* - doraemon-wake-all
|
|
||||||
* - doraemon-reboot-all
|
|
||||||
* - doraemon-shutdown-all
|
|
||||||
*/
|
|
||||||
class TogglePowerAll extends \Nethgui\Controller\Table\AbstractAction
|
|
||||||
{
|
|
||||||
|
|
||||||
public function __construct($identifier = NULL)
|
|
||||||
{
|
|
||||||
if ($identifier !== 'wake-all' && $identifier !== 'reboot-all' && $identifier !== 'shutdown-all') {
|
|
||||||
throw new \InvalidArgumentException(sprintf('%s: module identifier must be one of "wake-all" or "reboot-all" or "shutdown-all".', get_class($this)), 1325579395);
|
|
||||||
}
|
|
||||||
parent::__construct($identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function process()
|
|
||||||
{
|
|
||||||
if ( ! $this->getRequest()->isMutation()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->getPlatform()->signalEvent(sprintf('doraemon-%s@post', $this->getIdentifier()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* @var $view \Nethgui\Renderer\Xhtml */
|
|
||||||
|
|
||||||
if ($view->getModule()->getIdentifier() == 'update') {
|
|
||||||
// disable updating of hostname
|
|
||||||
// the hostname is the key of the db item, if you change it, bad things happens
|
|
||||||
$keyFlags = $view::STATE_DISABLED;
|
|
||||||
$template = 'Update_Host_Header';
|
|
||||||
} else {
|
|
||||||
$keyFlags = 0;
|
|
||||||
$template = 'Create_Host_Header';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $view->header('hostname')->setAttribute('template', $T($template));
|
|
||||||
|
|
||||||
echo $view->panel()
|
|
||||||
->insert($view->textInput('hostname', $keyFlags))
|
|
||||||
->insert($view->textInput('MacAddress'))
|
|
||||||
->insert($view->textInput('Role'))
|
|
||||||
;
|
|
||||||
|
|
||||||
echo $view->buttonList($view::BUTTON_SUBMIT | $view::BUTTON_CANCEL | $view::BUTTON_HELP);
|
|
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
$view->requireFlag($view::INSET_DIALOG);
|
|
||||||
|
|
||||||
if ($view->getModule()->getIdentifier() == 'shutdown') {
|
|
||||||
$headerText = $T('Shutdown host `${0}`');
|
|
||||||
$panelText = $T('Proceed with host `${0}` shutdown?');
|
|
||||||
} elseif ($view->getModule()->getIdentifier() == 'reboot') {
|
|
||||||
$headerText = $T('Reboot host `${0}`');
|
|
||||||
$panelText = $T('Proceed with host `${0}` reboot?');
|
|
||||||
} else {
|
|
||||||
$headerText = $T('Wakeup host `${0}`');
|
|
||||||
$panelText = $T('Proceed with host `${0}` wakeup?');
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $view->panel()
|
|
||||||
->insert($view->header('hostname')->setAttribute('template', $headerText))
|
|
||||||
->insert($view->textLabel('hostname')->setAttribute('template', $panelText))
|
|
||||||
;
|
|
||||||
|
|
||||||
echo $view->buttonList()
|
|
||||||
->insert($view->button('Yes', $view::BUTTON_SUBMIT))
|
|
||||||
->insert($view->button('No', $view::BUTTON_CANCEL)->setAttribute('value', $view['Cancel']))
|
|
||||||
;
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
$view->requireFlag($view::INSET_DIALOG);
|
|
||||||
|
|
||||||
if ($view->getModule()->getIdentifier() == 'shutdown-all') {
|
|
||||||
$headerText = $T('Shutdown all hosts');
|
|
||||||
$panelText = $T('Proceed with all hosts shutdown?');
|
|
||||||
} elseif ($view->getModule()->getIdentifier() == 'reboot-all') {
|
|
||||||
$headerText = $T('Reboot all hosts');
|
|
||||||
$panelText = $T('Proceed with all hosts reboot?');
|
|
||||||
} else {
|
|
||||||
$headerText = $T('Wakeup all hosts');
|
|
||||||
$panelText = $T('Proceed with all hosts wakeup?');
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $view->header()->setAttribute('template', $headerText);
|
|
||||||
// TODO: add a text label here
|
|
||||||
// echo $view->textLabel()->setAttribute('template', $panelText);
|
|
||||||
echo $view->buttonList()
|
|
||||||
->insert($view->button('Yes', $view::BUTTON_SUBMIT))
|
|
||||||
->insert($view->button('No', $view::BUTTON_CANCEL)->setAttribute('value', $view['Cancel']))
|
|
||||||
;
|
|
Loading…
x
Reference in New Issue
Block a user