1

Initial commit

This commit is contained in:
eleksir
2020-02-24 16:28:05 +03:00
commit 040bd1324e
11 changed files with 336 additions and 0 deletions

1
AUTHORS Normal file
View File

@@ -0,0 +1 @@
Sergei Fedosoff <eleksir@gmail.com>

1
COPYING Symbolic link
View File

@@ -0,0 +1 @@
LICENSE

19
LICENSE Normal file
View 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
View 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
View 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
View 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
View 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).

View 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
View 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:

View File

@@ -0,0 +1,2 @@
runit
perl

161
src/runit-svc Normal file
View 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: