Initial commit
This commit is contained in:
19
LICENSE
Normal file
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright 2020 Sergei Fedosoff <eleksir@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
15
README
Normal file
15
README
Normal file
@@ -0,0 +1,15 @@
|
||||
svc - runit sv replacement utility.
|
||||
|
||||
Svc was created because of there is no mean to manage services, running under
|
||||
runsvdir from user. Despite of docs runit native utility disregard environment
|
||||
variable SVDIR when looking for service, so all services MUST be in /service
|
||||
dir which is not user writable.
|
||||
|
||||
Also sv is unable to list, enable, disable and restart services.
|
||||
|
||||
There is sample config file for user services, it is located in doc/examples.
|
||||
It should be placed in ~/.local/etc directory of non-root user.
|
||||
|
||||
For system-wide services there is no config file required.
|
||||
|
||||
Requirements: perl, perl-JSON-PP (both already supplied with slackware linux)
|
||||
6
TODO
Normal file
6
TODO
Normal file
@@ -0,0 +1,6 @@
|
||||
There is some thing that are not critical, but should be done, eventually.
|
||||
|
||||
|
||||
1. Regard SVDIR environment variable, to be more good than original sv utility.
|
||||
|
||||
2. Think about XDG compliance for user config.
|
||||
6
doc/examples/svc.json
Normal file
6
doc/examples/svc.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"mode": "user",
|
||||
"dir": "/.local/etc/services",
|
||||
"servicedir": "/.local/etc/service.d",
|
||||
"timeout": 3
|
||||
}
|
||||
37
doc/man/runit-svc.1
Normal file
37
doc/man/runit-svc.1
Normal file
@@ -0,0 +1,37 @@
|
||||
.TH "SVC" "1" "24 February 2020"
|
||||
.SH "NAME"
|
||||
runit-svc \- sv replacement tool for runit
|
||||
.SH "SYNOPSIS"
|
||||
.B svc
|
||||
SERVICE_NAME start|stop|restart|status|enable|disable
|
||||
.br
|
||||
.B svc
|
||||
list [--all]
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
Manipulates system or user runit-services.
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
\fBsvc list\fR
|
||||
Show enabled services list for system or user
|
||||
.TP
|
||||
\fBsvc list \-\-all\fR
|
||||
Show all services for system or user
|
||||
.TP
|
||||
\fBsvc SERVICE_NAME start|stop|restart|status\fR
|
||||
Starts, stops, restarts, show status of service
|
||||
.TP
|
||||
\fBsvc SERVICE_NAME disable\fR
|
||||
Disables service. Note that service will be stopped immediately after disabling.
|
||||
.TP
|
||||
\fBsvc SERVICE_NAME enable\fR
|
||||
Enables service. Note that service will be started immediately after enabling.
|
||||
.TP
|
||||
.SH "AUTHOR"
|
||||
.TP
|
||||
Sergei Fedosoff <eleksir@gmail.com> aka eleksir <eleksir@exs-elm.ru>
|
||||
.SH "COPYRIGHT"
|
||||
Copyright \*R 2020 Sergei Fedosoff. License 2 clause BSD:
|
||||
https://directory.fsf.org/wiki?title=License:FreeBSD
|
||||
.SH "SEE ALSO"
|
||||
.B sv (1).
|
||||
69
doc/slackbuild/runit-svc.SlackBuild
Normal file
69
doc/slackbuild/runit-svc.SlackBuild
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Slackware build script for runit-svc
|
||||
|
||||
# Copyright 2020 Sergei Fedosoff <eleksir@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use of this script, with or without modification, is
|
||||
# permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of this script must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
PRGNAM=runit-svc
|
||||
VERSION=${VERSION:-0.1}
|
||||
BUILD=${BUILD:-1}
|
||||
TAG=${TAG:-_EXs}
|
||||
|
||||
if [ -z "$ARCH" ]; then
|
||||
case "$( uname -m )" in
|
||||
i?86) ARCH=i586 ;;
|
||||
arm*) ARCH=arm ;;
|
||||
*) ARCH=$( uname -m ) ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
CWD=$(pwd)
|
||||
TMP=${TMP:-/tmp/EXs}
|
||||
PKG=${PKG:-$TMP/package-$PRGNAM}
|
||||
OUTPUT=${OUTPUT:-/tmp}
|
||||
|
||||
set -e
|
||||
|
||||
rm -rf $PKG
|
||||
mkdir -p $TMP $PKG $OUTPUT
|
||||
cd $TMP
|
||||
rm -rf $PRGNAM-$VERSION
|
||||
tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
|
||||
cd $PRGNAM-$VERSION
|
||||
chown -R root:root .
|
||||
|
||||
install -Dpm 0755 src/runit-svc $PKG/usr/bin/runit-svc
|
||||
ln -s /usr/bin/runit-svc $PKG/usr/bin/svc
|
||||
mkdir -p $PKG/usr/man/man1
|
||||
gzip -9c doc/man/runit-svc.1 > $PKG/usr/man/man1/svc.1.gz
|
||||
gzip -9c doc/man/runit-svc.1 > $PKG/usr/man/man1/runit-svc.1.gz
|
||||
install -Dpm 0644 doc/examples/svc.json $PKG/usr/doc/$PRGNAM-$VERSION/examples/svc.json
|
||||
install -Dpm 0644 README $PKG/usr/doc/$PRGNAM-$VERSION/README
|
||||
install -Dpm 0644 LICENSE $PKG/usr/doc/$PRGNAM-$VERSION/LICENSE
|
||||
install -Dpm 0644 AUTHORS $PKG/usr/doc/$PRGNAM-$VERSION/AUTHORS
|
||||
|
||||
install -Dpm 0644 $CWD/$PRGNAM.SlackBuild $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
|
||||
|
||||
install -Dpm 0644 $CWD/slack-desc $PKG/install/slack-desc
|
||||
install -Dpm 0644 $CWD/slack-required $PKG/install/slack-required
|
||||
|
||||
cd $PKG
|
||||
/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz}
|
||||
19
doc/slackbuild/slack-desc
Normal file
19
doc/slackbuild/slack-desc
Normal file
@@ -0,0 +1,19 @@
|
||||
# HOW TO EDIT THIS FILE:
|
||||
# The "handy ruler" below makes it easier to edit a package description.
|
||||
# Line up the first '|' above the ':' following the base package name, and
|
||||
# the '|' on the right side marks the last column you can put a character in.
|
||||
# You must make exactly 11 lines for the formatting to be correct. It's also
|
||||
# customary to leave one space after the ':' except on otherwise blank lines.
|
||||
|
||||
|-----handy-ruler------------------------------------------------------|
|
||||
runit-svc: runit-svc (runit sv utility replacement)
|
||||
runit-svc:
|
||||
runit-svc:
|
||||
runit-svc:
|
||||
runit-svc:
|
||||
runit-svc:
|
||||
runit-svc:
|
||||
runit-svc:
|
||||
runit-svc: Homepage: https://github.com/eleksir/runit-svc
|
||||
runit-svc:
|
||||
runit-svc:
|
||||
2
doc/slackbuild/slack-required
Normal file
2
doc/slackbuild/slack-required
Normal file
@@ -0,0 +1,2 @@
|
||||
runit
|
||||
perl
|
||||
161
src/runit-svc
Normal file
161
src/runit-svc
Normal file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# runit sv utility ignores evironment variable SVDIR
|
||||
# and unable to list services, fully relying to user this knowlege
|
||||
|
||||
use strict;
|
||||
use warnings "all";
|
||||
use JSON::PP;
|
||||
|
||||
sub help;
|
||||
sub ctrl ($);
|
||||
sub status;
|
||||
|
||||
my $c;
|
||||
|
||||
if ($>) {
|
||||
# looks like we run in user-mode, so manage user services
|
||||
die "\$HOME is not set\n" unless (defined($ENV{HOME}));
|
||||
die "$ENV{HOME} does not exist\n" unless (-d $ENV{HOME});
|
||||
|
||||
my $sep = $/;
|
||||
$/ = '';
|
||||
|
||||
# TODO: actually, to be the most XDG-compatible, we should put config to $ENV{HOME}/.config/svc/svc.json
|
||||
open (CONF, "$ENV{HOME}/.local/etc/svc.json") or die "No config at $ENV{HOME}/.local/etc/svc.json\n";
|
||||
$c = <CONF>;
|
||||
close CONF;
|
||||
$/ = $sep;
|
||||
|
||||
$c = decode_json($c);
|
||||
$c->{dir} = sprintf("%s%s", $ENV{HOME}, $c->{dir});
|
||||
$c->{servicedir} = sprintf("%s%s", $ENV{HOME}, $c->{servicedir});
|
||||
} else {
|
||||
# looks like we run with root privileges, manage system services
|
||||
$c->{mode} = "system";
|
||||
$c->{dir} = "/etc/service";
|
||||
|
||||
if (-d "/etc/service.d") {
|
||||
$c->{servicedir} = "/etc/service.d";
|
||||
} else {
|
||||
|
||||
# guideline of runit suggest to use /service directory, also sv utility expects services placed there by default
|
||||
$c->{servicedir} = "/service";
|
||||
}
|
||||
|
||||
$c->{timeout} = 3;
|
||||
}
|
||||
|
||||
die "No such directory $c->{dir}\n" unless (-d $c->{dir});
|
||||
chdir $c->{dir};
|
||||
|
||||
unless (defined($ARGV[0])) {
|
||||
help;
|
||||
} else {
|
||||
if ($ARGV[0] ne 'list') {
|
||||
help unless (defined($ARGV[1]));
|
||||
}
|
||||
}
|
||||
|
||||
if ($ARGV[0] eq 'list') {
|
||||
my $d;
|
||||
|
||||
if (defined($ARGV[1]) && $ARGV[1] eq '--all') {
|
||||
$d = $c->{servicedir};
|
||||
} else {
|
||||
$d = $c->{dir};
|
||||
}
|
||||
|
||||
opendir(D, $d) or die "Unable to list services, no such directory $d\n";
|
||||
print join("\n", sort (grep {!/^\.{1,2}$/} readdir(D))) . "\n";
|
||||
closedir D;
|
||||
} elsif ($ARGV[1] eq 'disable') {
|
||||
my $d = "$c->{dir}/$ARGV[0]";
|
||||
|
||||
if (-l $d) {
|
||||
unlink ("$d") or die "Unable to disable $ARGV[0]\n";
|
||||
} else {
|
||||
die "No such service $ARGV[0]\n";
|
||||
}
|
||||
} elsif ($ARGV[1] eq 'enable') {
|
||||
my $d = "$c->{dir}/$ARGV[0]";
|
||||
|
||||
if (-l $d) {
|
||||
die "Service $ARGV[0] already enabled\n";
|
||||
} else {
|
||||
my $svcdir = "$c->{servicedir}/$ARGV[0]";
|
||||
|
||||
if (-d $svcdir) {
|
||||
symlink ($svcdir, $d) or die "Unable to enable service $ARGV[0]\n";
|
||||
} else {
|
||||
die "No such service $ARGV[0]\n";
|
||||
}
|
||||
}
|
||||
} elsif ((-l "./$ARGV[0]") || (-d "./$ARGV[0]")) {
|
||||
chdir "./$ARGV[0]";
|
||||
die "Is service running?\n" unless (-d './supervise');
|
||||
chdir './supervise';
|
||||
|
||||
if ($ARGV[1] eq 'start') {
|
||||
die "Service $ARGV[0] already running.\n" if (status() eq 'run');
|
||||
ctrl('u');
|
||||
} elsif ($ARGV[1] eq 'restart') {
|
||||
die "Service $ARGV[0] already stopped.\n" if (status() eq 'down');
|
||||
ctrl('d');
|
||||
|
||||
for (my $cnt = 0; $cnt < $c->{timeout}; $cnt++) {
|
||||
if (status() eq 'down') {
|
||||
last;
|
||||
}
|
||||
|
||||
sleep 1;
|
||||
}
|
||||
|
||||
ctrl('k') if (status() ne 'down');
|
||||
sleep 1;
|
||||
ctrl('u');
|
||||
} elsif ($ARGV[1] eq 'stop') {
|
||||
die "Service $ARGV[0] already stopped.\n" if (status() eq 'down');
|
||||
ctrl('d');
|
||||
|
||||
for (my $cnt = 0; $cnt < $c->{timeout}; $cnt++) {
|
||||
if (status() eq 'down') {
|
||||
last;
|
||||
}
|
||||
|
||||
sleep 1;
|
||||
}
|
||||
|
||||
ctrl('k') if (status() ne 'down');
|
||||
sleep 1;
|
||||
} elsif ($ARGV[1] eq 'status') {
|
||||
print status() . "\n";
|
||||
}
|
||||
} else {
|
||||
die "No such service.\n";
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
sub help {
|
||||
print "Usage $0 SERVICE [start|stop|restart|status|enable|disable]\n";
|
||||
print " $0 list [--all]\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
sub ctrl ($) {
|
||||
my $command = shift;
|
||||
open (C, ">", "control") or die "Unable to write to control socket\n";
|
||||
print C $command;
|
||||
close C;
|
||||
}
|
||||
|
||||
sub status {
|
||||
open (S, "stat") or die "Unable to read status.\n";
|
||||
my $status = <S>;
|
||||
chomp $status;
|
||||
close S;
|
||||
return $status;
|
||||
}
|
||||
|
||||
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
||||
Reference in New Issue
Block a user