From dbb905c9786eb4686ebc85d8e5aad1f481591448 Mon Sep 17 00:00:00 2001 From: Paul Eggleton Date: Mon, 11 Feb 2013 10:16:25 +0000 Subject: ajenti: add new recipe Add new recipe for the Ajenti web administration interface. This was developed and tested with assistance from Kevin Strasser Signed-off-by: Paul Eggleton --- .../0001-setup.py-remove-extra-data-files.patch | 33 ++++++ ...stat-fix-disk-usage-check-to-work-with-bu.patch | 29 +++++ ...-plugins-sysload-fix-to-work-with-busybox.patch | 47 ++++++++ .../ajenti/0005-plugins-power-fix-shutdown.patch | 31 ++++++ ...ervices-add-basic-sysvinit-implementation.patch | 119 +++++++++++++++++++++ ...vices-replace-s_upstart-with-s_init-in-MO.patch | 23 ++++ .../ajenti/distributor-logo-openembedded.png | Bin 0 -> 2165 bytes .../ajenti/distro-detection-openembedded.patch | 42 ++++++++ .../recipes-webadmin/ajenti/ajenti_git.bb | 80 ++++++++++++++ 9 files changed, 404 insertions(+) create mode 100644 meta-webserver/recipes-webadmin/ajenti/ajenti/0001-setup.py-remove-extra-data-files.patch create mode 100644 meta-webserver/recipes-webadmin/ajenti/ajenti/0002-plugins-hddstat-fix-disk-usage-check-to-work-with-bu.patch create mode 100644 meta-webserver/recipes-webadmin/ajenti/ajenti/0003-plugins-sysload-fix-to-work-with-busybox.patch create mode 100644 meta-webserver/recipes-webadmin/ajenti/ajenti/0005-plugins-power-fix-shutdown.patch create mode 100644 meta-webserver/recipes-webadmin/ajenti/ajenti/0006-plugins-services-add-basic-sysvinit-implementation.patch create mode 100644 meta-webserver/recipes-webadmin/ajenti/ajenti/0007-plugins-services-replace-s_upstart-with-s_init-in-MO.patch create mode 100644 meta-webserver/recipes-webadmin/ajenti/ajenti/distributor-logo-openembedded.png create mode 100644 meta-webserver/recipes-webadmin/ajenti/ajenti/distro-detection-openembedded.patch create mode 100644 meta-webserver/recipes-webadmin/ajenti/ajenti_git.bb (limited to 'meta-webserver') diff --git a/meta-webserver/recipes-webadmin/ajenti/ajenti/0001-setup.py-remove-extra-data-files.patch b/meta-webserver/recipes-webadmin/ajenti/ajenti/0001-setup.py-remove-extra-data-files.patch new file mode 100644 index 0000000000..11d7a9292a --- /dev/null +++ b/meta-webserver/recipes-webadmin/ajenti/ajenti/0001-setup.py-remove-extra-data-files.patch @@ -0,0 +1,33 @@ +From 37bf4c471f23140e00fe87dde6f7c3cf38933c22 Mon Sep 17 00:00:00 2001 +From: Paul Eggleton +Date: Mon, 12 Mar 2012 02:01:48 +0000 +Subject: [PATCH] setup.py: remove extra data files + +Don't install files using setup.py, since this fails due to absolute +paths and we can easily install these within the recipe instead. + +Upstream-Status: Inappropriate [config] + +Signed-off-by: Paul Eggleton +--- + setup.py | 6 ------ + 1 files changed, 0 insertions(+), 6 deletions(-) + +diff --git a/setup.py b/setup.py +index 8daea4c..11e3acb 100755 +--- a/setup.py ++++ b/setup.py +@@ -18,10 +18,4 @@ setup( + packages = find_packages(), + package_data={'': ['files/*.*', 'files/*/*.*', 'files/*/*/*.*', 'templates/*.*', 'widgets/*.*', 'layout/*.*']}, + scripts=['ajenti-panel', 'ajenti-pkg'], +- data_files=[ +- ('/etc/ajenti', ['packaging/files/ajenti.conf']), +- ('/etc/ajenti/users', ['packaging/files/admin.conf']), +- ('/etc/init.d', ['packaging/files/ajenti']), +- ('/var/lib/ajenti/plugins', ['packaging/files/.placeholder']), +- ], + ) +-- +1.7.5.4 + diff --git a/meta-webserver/recipes-webadmin/ajenti/ajenti/0002-plugins-hddstat-fix-disk-usage-check-to-work-with-bu.patch b/meta-webserver/recipes-webadmin/ajenti/ajenti/0002-plugins-hddstat-fix-disk-usage-check-to-work-with-bu.patch new file mode 100644 index 0000000000..48c255dbb1 --- /dev/null +++ b/meta-webserver/recipes-webadmin/ajenti/ajenti/0002-plugins-hddstat-fix-disk-usage-check-to-work-with-bu.patch @@ -0,0 +1,29 @@ +From cde811cfffba48c148b60fb1083fe8fd409b8b24 Mon Sep 17 00:00:00 2001 +From: Paul Eggleton +Date: Tue, 13 Mar 2012 01:52:34 +0000 +Subject: [PATCH 1/2] plugins/hddstat: fix disk usage check to work with + busybox + +busybox df does not have --total, so fake it using awk. + +Signed-off-by: Paul Eggleton +--- + plugins/hddstat/usage.py | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/plugins/hddstat/usage.py b/plugins/hddstat/usage.py +index 3c84181..cf5f037 100644 +--- a/plugins/hddstat/usage.py ++++ b/plugins/hddstat/usage.py +@@ -7,7 +7,7 @@ class DiskUsageMeter(LinearMeter): + transform = 'percent' + + def get_usage(self): +- u = int(shell('df --total | grep total').split().pop().strip('%')) ++ u = int(round(float(shell("df -P | awk 'NR > 1 {total+=$3+$4 ; used+=$3} END { print used/total*100}'").strip()))) + return u + + def get_value(self): +-- +1.7.4.4 + diff --git a/meta-webserver/recipes-webadmin/ajenti/ajenti/0003-plugins-sysload-fix-to-work-with-busybox.patch b/meta-webserver/recipes-webadmin/ajenti/ajenti/0003-plugins-sysload-fix-to-work-with-busybox.patch new file mode 100644 index 0000000000..1efec9b927 --- /dev/null +++ b/meta-webserver/recipes-webadmin/ajenti/ajenti/0003-plugins-sysload-fix-to-work-with-busybox.patch @@ -0,0 +1,47 @@ +From 552c46fb22fe336175c42612c33ceb0828ddd6aa Mon Sep 17 00:00:00 2001 +From: Paul Eggleton +Date: Tue, 13 Mar 2012 01:54:09 +0000 +Subject: [PATCH 2/2] plugins/sysload: fix to work with busybox + +The busybox free command does not support -b, so specify -k (which is +also ignored, but will help if real "free" is being used) and multiply +kb values by 1024. + +Signed-off-by: Paul Eggleton +--- + plugins/sysload/ss_linux.py | 18 +++++++++++------- + 1 files changed, 11 insertions(+), 7 deletions(-) + +diff --git a/plugins/sysload/ss_linux.py b/plugins/sysload/ss_linux.py +index cab7708..be60c53 100644 +--- a/plugins/sysload/ss_linux.py ++++ b/plugins/sysload/ss_linux.py +@@ -11,14 +11,18 @@ class LinuxSysStat(Plugin): + return open('/proc/loadavg', 'r').read().split()[0:3] + + def get_ram(self): +- s = shell('free -b | grep Mem').split()[1:] +- t = int(s[0]) +- u = int(s[1]) +- b = int(s[4]) +- c = int(s[5]) ++ # busybox free doesn't support -b ++ s = shell('free -k | grep Mem').split()[1:] ++ t = int(s[0]) * 1024 ++ u = int(s[1]) * 1024 ++ b = int(s[4]) * 1024 ++ if len(s) > 5: ++ c = int(s[5]) * 1024 ++ else: ++ c = 0 + u -= c + b; + return (u, t) + + def get_swap(self): +- s = shell('free -b | grep Swap').split()[1:] +- return (int(s[1]), int(s[0])) ++ s = shell('free -k | grep Swap').split()[1:] ++ return (int(s[1]) * 1024, int(s[0]) * 1024) +-- +1.7.4.4 + diff --git a/meta-webserver/recipes-webadmin/ajenti/ajenti/0005-plugins-power-fix-shutdown.patch b/meta-webserver/recipes-webadmin/ajenti/ajenti/0005-plugins-power-fix-shutdown.patch new file mode 100644 index 0000000000..2934385b2d --- /dev/null +++ b/meta-webserver/recipes-webadmin/ajenti/ajenti/0005-plugins-power-fix-shutdown.patch @@ -0,0 +1,31 @@ +From acd997cf610f8e9b0dbea00d2f1184d256d1b85b Mon Sep 17 00:00:00 2001 +From: Paul Eggleton +Date: Sat, 17 Mar 2012 23:50:48 +0000 +Subject: [PATCH] plugins/power: fix shutdown + +Fix shutdown to use the -h option together with -P (which is required +for sysvinit shutdown.) + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton +--- + plugins/power/main.py | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/plugins/power/main.py b/plugins/power/main.py +index 0ab6337..069bde7 100755 +--- a/plugins/power/main.py ++++ b/plugins/power/main.py +@@ -57,7 +57,7 @@ class PowerPlugin(CategoryPlugin): + @event('button/click') + def on_aclick(self, event, params, vars=None): + if params[0] == 'shutdown': +- shell('shutdown -P now') ++ shell('shutdown -h -P now') + if params[0] == 'reboot': + shell('reboot') + +-- +1.7.5.4 + diff --git a/meta-webserver/recipes-webadmin/ajenti/ajenti/0006-plugins-services-add-basic-sysvinit-implementation.patch b/meta-webserver/recipes-webadmin/ajenti/ajenti/0006-plugins-services-add-basic-sysvinit-implementation.patch new file mode 100644 index 0000000000..651018e5a4 --- /dev/null +++ b/meta-webserver/recipes-webadmin/ajenti/ajenti/0006-plugins-services-add-basic-sysvinit-implementation.patch @@ -0,0 +1,119 @@ +From 57f949a7ab34812d8384bf41c05c3b25bdade92b Mon Sep 17 00:00:00 2001 +From: Paul Eggleton +Date: Sun, 18 Mar 2012 14:26:34 +0000 +Subject: [PATCH] plugins/services: add basic sysvinit implementation + +This allows operation on systems that don't have the "service" command. +The PID finding is a little hacky but mostly works. Note that this uses +psutil to detect whether the service is really running rather than just +assuming that it is if the pid file exists. + +Note: you need to remove s_upstart.py before this will work. + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton +--- + plugins/services/s_init.py | 90 ++++++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 90 insertions(+), 0 deletions(-) + create mode 100755 plugins/services/s_init.py + +diff --git a/plugins/services/s_init.py b/plugins/services/s_init.py +new file mode 100755 +index 0000000..6f38b0a +--- /dev/null ++++ b/plugins/services/s_init.py +@@ -0,0 +1,90 @@ ++# Basic sysvinit service backend implementation for Ajenti Services plugin ++# ++# Copyright (C) 2012 Intel Corporation ++# Author: Paul Eggleton ++# ++ ++import os ++import psutil ++ ++from ajenti.com import * ++from ajenti.utils import * ++from ajenti import apis ++from ajenti.api import * ++ ++def find_service_pid(service): ++ svcfile = os.path.join('/etc/init.d', service) ++ pidfile = '' ++ try: ++ svcf = open(svcfile) ++ except: ++ return None ++ while 1: ++ line = svcf.readline() ++ if not line: ++ break ++ if line.startswith('PID='): ++ pidfile = line.split('=')[1].strip("'\n\r \"") ++ break ++ svcf.close() ++ if not pidfile: ++ pf = '/var/run/%s.pid' % service ++ if os.path.exists(pf): ++ pidfile = pf ++ else: ++ pf = '/var/run/%sd.pid' % service ++ if os.path.exists(pf): ++ pidfile = pf ++ if pidfile: ++ pidf = open(pidfile) ++ pid = pidf.readline() ++ pidf.close ++ if pid: ++ pid = pid.strip() ++ pid = int(pid) ++ try: ++ p = psutil.Process(pid) ++ except: ++ pid = None ++ return pid ++ return None ++ ++ ++class UpstartServiceManager(Plugin): ++ implements(apis.services.IServiceManager) ++ platform = ['debian'] ++ ++ def list_all(self): ++ r = [] ++ ++ blacklist = 'functions mountall.sh save-rtc.sh umountnfs.sh populate-volatile.sh rcS bootlogd urandom halt sendsigs single bootmisc.sh sysfs.sh mountnfs.sh busybox-udhcpc devpts.sh banner.sh modutils.sh checkroot.sh networking umountfs udev rc hostname.sh fbsetup stop-bootlogd rmnologin.sh reboot hwclock.sh read-only-rootfs-hook.sh functions.initscripts syslog.busybox'.split() ++ ++ for f in os.listdir('/etc/init.d'): ++ if not f in blacklist: ++ svc = apis.services.Service() ++ svc.name = f ++ pid = find_service_pid(f) ++ if pid: ++ svc.status = 'running' ++ else: ++ svc.status = 'stopped' ++ r.append(svc) ++ ++ return sorted(r, key=lambda s: s.name) ++ ++ def get_status(self, name): ++ pid = find_service_pid(name) ++ if pid: ++ return 'running' ++ else: ++ return 'stopped' ++ ++ def start(self, name): ++ shell('/etc/init.d/%s start' % name) ++ ++ def stop(self, name): ++ shell('/etc/init.d/%s stop' % name) ++ ++ def restart(self, name): ++ shell('/etc/init.d/%s restart' % name) ++ +-- +1.7.5.4 + diff --git a/meta-webserver/recipes-webadmin/ajenti/ajenti/0007-plugins-services-replace-s_upstart-with-s_init-in-MO.patch b/meta-webserver/recipes-webadmin/ajenti/ajenti/0007-plugins-services-replace-s_upstart-with-s_init-in-MO.patch new file mode 100644 index 0000000000..7623e3f6e7 --- /dev/null +++ b/meta-webserver/recipes-webadmin/ajenti/ajenti/0007-plugins-services-replace-s_upstart-with-s_init-in-MO.patch @@ -0,0 +1,23 @@ +From 75b5109ceb4874c967daf6c1e8434e6093b1df79 Mon Sep 17 00:00:00 2001 +From: Kevin Strasser +Date: Mon, 29 Oct 2012 01:44:10 -0700 +Subject: [PATCH] plugins/services: replace s_upstart with s_init in MODULES + +Signed-off-by: Kevin Strasser +--- + plugins/services/__init__.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plugins/services/__init__.py b/plugins/services/__init__.py +index 6cf58e5..ced3300 100755 +--- a/plugins/services/__init__.py ++++ b/plugins/services/__init__.py +@@ -1,4 +1,4 @@ +-MODULES = ['api', 'main', 'meter', 'widget', 's_upstart', 's_arch', 's_bsd', 's_centos', 's_gentoo'] ++MODULES = ['api', 'main', 'meter', 'widget', 's_init', 's_arch', 's_bsd', 's_centos', 's_gentoo'] + + DEPS = [ + (['centos', 'fedora'], +-- +1.7.9.5 + diff --git a/meta-webserver/recipes-webadmin/ajenti/ajenti/distributor-logo-openembedded.png b/meta-webserver/recipes-webadmin/ajenti/ajenti/distributor-logo-openembedded.png new file mode 100644 index 0000000000..0aad9df90c Binary files /dev/null and b/meta-webserver/recipes-webadmin/ajenti/ajenti/distributor-logo-openembedded.png differ diff --git a/meta-webserver/recipes-webadmin/ajenti/ajenti/distro-detection-openembedded.patch b/meta-webserver/recipes-webadmin/ajenti/ajenti/distro-detection-openembedded.patch new file mode 100644 index 0000000000..9ef9bac74b --- /dev/null +++ b/meta-webserver/recipes-webadmin/ajenti/ajenti/distro-detection-openembedded.patch @@ -0,0 +1,42 @@ +From 5b3864f5ff76915887774fa78961616b6e7c1649 Mon Sep 17 00:00:00 2001 +From: Paul Eggleton +Date: Thu, 15 Mar 2012 03:25:36 +0000 +Subject: [PATCH] Hardcode distro detection + +Use "openembedded" as the distro identification string if none is able +to be detected. + +Upstream-Status: Inappropriate [config] + +Signed-off-by: Paul Eggleton +--- + ajenti/utils/utils.py | 6 +++++- + 1 files changed, 5 insertions(+), 1 deletions(-) + +diff --git a/ajenti/utils/utils.py b/ajenti/utils/utils.py +index c7e1463..98199c0 100755 +--- a/ajenti/utils/utils.py ++++ b/ajenti/utils/utils.py +@@ -41,6 +41,7 @@ def detect_platform(mapping=True): + platform_mapping = { + 'ubuntu': 'debian', + 'linuxmint': 'debian', ++ 'openembedded': 'debian', + } + + if platform.system() != 'Linux': +@@ -57,7 +58,10 @@ def detect_platform(mapping=True): + try: + dist = shell('strings -4 /etc/issue').split()[0] + except: +- dist = 'unknown' ++ dist = '' ++ ++ if dist == '': ++ dist = 'openembedded' + + res = dist.strip().lower() + if res in base_mapping: +-- +1.7.4.4 + diff --git a/meta-webserver/recipes-webadmin/ajenti/ajenti_git.bb b/meta-webserver/recipes-webadmin/ajenti/ajenti_git.bb new file mode 100644 index 0000000000..dc1508eba9 --- /dev/null +++ b/meta-webserver/recipes-webadmin/ajenti/ajenti_git.bb @@ -0,0 +1,80 @@ +SUMMARY = "Web-based system administration interface" +HOMEPAGE = "http://ajenti.org" +SECTION = "devel/python" +LICENSE = "LGPLv3" +LIC_FILES_CHKSUM = "file://LICENSE;md5=e6a600fd5e1d9cbde2d983680233ad02" + +DEPENDS += "python-pyopenssl python-lxml python-gevent python-greenlet \ + python-psutil python-imaging" + +PV = "0.6.2+git${SRCPV}" + +SRC_URI = "git://github.com/Eugeny/ajenti.git \ + file://0001-setup.py-remove-extra-data-files.patch \ + file://0002-plugins-hddstat-fix-disk-usage-check-to-work-with-bu.patch \ + file://0003-plugins-sysload-fix-to-work-with-busybox.patch \ + file://0005-plugins-power-fix-shutdown.patch \ + file://0006-plugins-services-add-basic-sysvinit-implementation.patch \ + file://0007-plugins-services-replace-s_upstart-with-s_init-in-MO.patch \ + ${DISTRO_FILES}" + +# Allow this to be customised easily +DISTRO_FILES = "file://distro-detection-openembedded.patch \ + file://distributor-logo-openembedded.png" + +# Corresponds to the 0.6.2 tag +SRCREV = "c08fb4da65923aebd09116750a1f43f13b98a51a" + +S = "${WORKDIR}/git" + +inherit setuptools update-rc.d + +do_configure_prepend() { + rm ajenti/plugins/dashboard/files/distributor-logo-*.png + cp ${WORKDIR}/distributor-logo-*.png ajenti/plugins/dashboard/files/ + rm plugins/services/s_upstart.py +} + +do_install_append() { + install -d ${D}${sysconfdir} + install -d ${D}${sysconfdir}/ajenti + install -m 0644 packaging/files/ajenti.conf ${D}${sysconfdir}/ajenti/ + install -d ${D}${sysconfdir}/ajenti/users + install -m 0644 packaging/files/admin.conf ${D}${sysconfdir}/ajenti/users/ + install -d ${D}${sysconfdir}/init.d + install -m 0755 packaging/files/ajenti ${D}${sysconfdir}/init.d/ + install -d ${D}${localstatedir} + install -d ${D}${localstatedir}/lib + install -d ${D}${localstatedir}/lib/ajenti + install -d ${D}${localstatedir}/lib/ajenti/plugins + install -m 0644 packaging/files/.placeholder ${D}${localstatedir}/lib/ajenti/plugins + + for plugin in plugins/* ; do + cp -r $plugin ${D}${localstatedir}/lib/ajenti/plugins/ + done +} + +INITSCRIPT_NAME = "ajenti" +INITSCRIPT_PARAMS = "start 99 2 3 4 5 . stop 20 0 1 6 ." + +python populate_packages_prepend() { + plugindir = d.expand('${localstatedir}/lib/ajenti/plugins') + do_split_packages(d, plugindir, '(^[^.]*$)', 'ajenti-plugin-%s', 'Ajenti plugin for %s', allow_dirs=True, prepend=False) +} + +PACKAGES_DYNAMIC = "ajenti-plugin-*" +FILES_${PN} += "${sysconfdir}/ajenti.conf \ + ${sysconfdir}/ajenti \ + ${sysconfdir}/init.d \ + ${localstatedir}/lib/ajenti/plugins/.placeholder" +RDEPENDS_${PN} += "python-re python-json python-logging python-subprocess \ + python-threading python-setuptools python-netclient \ + python-netserver python-shell python-syslog \ + python-pyopenssl python-lxml python-gevent python-greenlet" +RDEPENDS_${PN}-plugin-taskmgr += "python-psutil" +RDEPENDS_${PN}-plugin-services += "python-psutil" +RDEPENDS_${PN}-plugin-logs += "python-compression" +RDEPENDS_${PN}-plugin-terminal += "python-compression python-codecs python-math \ + python-terminal python-imaging" +RDEPENDS_${PN}-plugin-fm += "python-unixadmin" + -- cgit 1.2.3-korg