RHEL 9 BETA update

- sync with rhel8

Resolves: rhbz#1908882
Resolves: rhbz#1942383
Resolves: rhbz#1946707
Resolves: rhbz#1946709
Resolves: rhbz#1981278

Signed-off-by: Radovan Sroka <rsroka@redhat.com>
This commit is contained in:
Radovan Sroka 2021-07-19 17:02:57 +02:00
parent e027d0334f
commit ac2373ab95
No known key found for this signature in database
GPG Key ID: F5778AD785E3581F
51 changed files with 313 additions and 7168 deletions

View File

@ -1,11 +0,0 @@
--- sudo-1.6.7p5/install-sh.strip 2005-07-21 14:28:25.000000000 +0200
+++ sudo-1.6.7p5/install-sh 2005-07-21 14:29:18.000000000 +0200
@@ -138,7 +138,7 @@
fi
;;
X-s)
- STRIPIT=true
+ #STRIPIT=true
;;
X--)
shift

View File

@ -0,0 +1,74 @@
From 73006fb25f0ebc35bc46b8f20036d40fcbb6de53 Mon Sep 17 00:00:00 2001
From: Radovan Sroka <rsroka@redhat.com>
Date: Thu, 1 Apr 2021 21:42:03 +0200
Subject: [PATCH] Removed depricated security_context_t
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
---
src/selinux.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/selinux.c b/src/selinux.c
index a2f73f8d0..c2f50aafb 100644
--- a/src/selinux.c
+++ b/src/selinux.c
@@ -58,10 +58,10 @@
#include "sudo_exec.h"
static struct selinux_state {
- security_context_t old_context;
- security_context_t new_context;
- security_context_t tty_con_raw;
- security_context_t new_tty_con_raw;
+ char * old_context;
+ char * new_context;
+ char * tty_con_raw;
+ char * new_tty_con_raw;
const char *ttyn;
int ttyfd;
int enforcing;
@@ -69,8 +69,8 @@ static struct selinux_state {
#ifdef HAVE_LINUX_AUDIT
static int
-audit_role_change(const security_context_t old_context,
- const security_context_t new_context, const char *ttyn, int result)
+audit_role_change(const char * old_context,
+ const char * new_context, const char *ttyn, int result)
{
int au_fd, rc = -1;
char *message;
@@ -111,7 +111,7 @@ int
selinux_restore_tty(void)
{
int ret = -1;
- security_context_t chk_tty_con_raw = NULL;
+ char * chk_tty_con_raw = NULL;
debug_decl(selinux_restore_tty, SUDO_DEBUG_SELINUX);
if (se_state.ttyfd == -1 || se_state.new_tty_con_raw == NULL) {
@@ -166,8 +166,8 @@ selinux_restore_tty(void)
static int
relabel_tty(const char *ttyn, int ptyfd)
{
- security_context_t tty_con = NULL;
- security_context_t new_tty_con = NULL;
+ char * tty_con = NULL;
+ char * new_tty_con = NULL;
struct stat sb;
int fd;
debug_decl(relabel_tty, SUDO_DEBUG_SELINUX);
@@ -308,10 +308,10 @@ relabel_tty(const char *ttyn, int ptyfd)
* Returns a new security context based on the old context and the
* specified role and type.
*/
-security_context_t
-get_exec_context(security_context_t old_context, const char *role, const char *type)
+char *
+get_exec_context(char * old_context, const char *role, const char *type)
{
- security_context_t new_context = NULL;
+ char * new_context = NULL;
context_t context = NULL;
char *typebuf = NULL;
debug_decl(get_exec_context, SUDO_DEBUG_SELINUX);

View File

@ -0,0 +1,51 @@
From 613a8053dbc3ab43cf0cdaf09f207ffdb0b40e08 Mon Sep 17 00:00:00 2001
From: Radovan Sroka <rsroka@redhat.com>
Date: Wed, 7 Apr 2021 14:43:40 +0200
Subject: [PATCH] Fixed bad condition for sesh args
In selinux_edit_copy_tfiles() when there is only one file and the open()
fails then number of arguments is lower than expected.
Sudo should return error with or without "Defaults !sudoedit_checkdir" set.
This was found with regression testing of CVE-2021-23240.
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
---
src/sudo_edit.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/sudo_edit.c b/src/sudo_edit.c
index 41fc61c3a..15c75d8c4 100644
--- a/src/sudo_edit.c
+++ b/src/sudo_edit.c
@@ -529,6 +529,8 @@ selinux_edit_copy_tfiles(struct command_details *command_details,
if (nfiles < 1)
debug_return_int(0);
+ const int check_dir = ISSET(command_details->flags, CD_SUDOEDIT_CHECKDIR);
+
/* Construct common args for sesh */
sesh_nargs = 5 + (nfiles * 2) + 1;
sesh_args = sesh_ap = reallocarray(NULL, sesh_nargs, sizeof(char *));
@@ -538,7 +540,7 @@ selinux_edit_copy_tfiles(struct command_details *command_details,
}
*sesh_ap++ = "sesh";
*sesh_ap++ = "-e";
- if (ISSET(command_details->flags, CD_SUDOEDIT_CHECKDIR)) {
+ if (check_dir) {
if ((user_str = selinux_fmt_sudo_user()) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
@@ -581,7 +583,11 @@ selinux_edit_copy_tfiles(struct command_details *command_details,
if (tfd != -1)
close(tfd);
- if (sesh_ap - sesh_args > 3) {
+ /*
+ * check dir adds two more args to the array
+ */
+ if ((!check_dir && sesh_ap - sesh_args > 3)
+ || (check_dir && sesh_ap - sesh_args > 5)) {
/* Run sesh -e 1 <t1> <o1> ... <tn> <on> */
error = selinux_run_helper(command_details->cred.uid, command_details->cred.gid,
command_details->cred.ngroups, command_details->cred.groups, sesh_args,

View File

@ -0,0 +1,19 @@
diff -up ./plugins/sudoers/audit.c.undefined ./plugins/sudoers/audit.c
--- ./plugins/sudoers/audit.c.undefined 2021-07-12 14:59:53.472306208 +0200
+++ ./plugins/sudoers/audit.c 2021-07-12 15:00:45.620620369 +0200
@@ -197,7 +197,6 @@ sudoers_audit_open(unsigned int version,
debug_return_int(ret);
}
-#ifdef SUDOERS_LOG_CLIENT
static void
audit_to_eventlog(struct eventlog *evlog, char * const command_info[],
char * const run_argv[], char * const run_envp[])
@@ -244,6 +243,7 @@ audit_to_eventlog(struct eventlog *evlog
debug_return;
}
+#ifdef SUDOERS_LOG_CLIENT
static bool
log_server_accept(char * const command_info[], char * const run_argv[],
char * const run_envp[])

25
sudo-conf.patch Normal file
View File

@ -0,0 +1,25 @@
diff -up ./examples/sudo.conf.in.fix ./examples/sudo.conf.in
--- ./examples/sudo.conf.in.fix 2021-07-09 16:29:45.854347994 +0200
+++ ./examples/sudo.conf.in 2021-07-09 16:31:01.144410540 +0200
@@ -11,9 +11,9 @@
# The plugin_options are optional.
#
# The sudoers plugin is used by default if no Plugin lines are present.
-#Plugin sudoers_policy sudoers.so
-#Plugin sudoers_io sudoers.so
-#Plugin sudoers_audit sudoers.so
+Plugin sudoers_policy sudoers.so
+Plugin sudoers_io sudoers.so
+Plugin sudoers_audit sudoers.so
#
# Sudo askpass:
@@ -78,7 +78,7 @@
# To aid in debugging sudo problems, you may wish to enable core
# dumps by setting "disable_coredump" to false.
#
-#Set disable_coredump false
+Set disable_coredump false
#
# User groups:

86
sudo-ldap.conf Normal file
View File

@ -0,0 +1,86 @@
## BINDDN DN
## The BINDDN parameter specifies the identity, in the form of a Dis
## tinguished Name (DN), to use when performing LDAP operations. If
## not specified, LDAP operations are performed with an anonymous
## identity. By default, most LDAP servers will allow anonymous
## access.
##
#binddn uid=sudo,cn=sysaccounts,cn=etc,dc=example,dc=com
## BINDPW secret
## The BINDPW parameter specifies the password to use when performing
## LDAP operations. This is typically used in conjunction with the
## BINDDN parameter.
##
#bindpw secret
## SSL start_tls
## If the SSL parameter is set to start_tls, the LDAP server connec
## tion is initiated normally and TLS encryption is begun before the
## bind credentials are sent. This has the advantage of not requiring
## a dedicated port for encrypted communications. This parameter is
## only supported by LDAP servers that honor the start_tls extension,
## such as the OpenLDAP and Tivoli Directory servers.
##
#ssl start_tls
## TLS_CACERTFILE file name
## The path to a certificate authority bundle which contains the cer
## tificates for all the Certificate Authorities the client knows to
## be valid, e.g. /etc/ssl/ca-bundle.pem. This option is only sup
## ported by the OpenLDAP libraries. Netscape-derived LDAP libraries
## use the same certificate database for CA and client certificates
## (see TLS_CERT).
##
#tls_cacertfile /path/to/CA.crt
## TLS_CHECKPEER on/true/yes/off/false/no
## If enabled, TLS_CHECKPEER will cause the LDAP server's TLS certifi
## cated to be verified. If the server's TLS certificate cannot be
## verified (usually because it is signed by an unknown certificate
## authority), sudo will be unable to connect to it. If TLS_CHECKPEER
## is disabled, no check is made. Note that disabling the check cre
## ates an opportunity for man-in-the-middle attacks since the
## server's identity will not be authenticated. If possible, the CA's
## certificate should be installed locally so it can be verified.
## This option is not supported by the Tivoli Directory Server LDAP
## libraries.
#tls_checkpeer yes
##
## URI ldap[s]://[hostname[:port]] ...
## Specifies a whitespace-delimited list of one or more
## URIs describing the LDAP server(s) to connect to.
##
#uri ldap://ldapserver
##
## SUDOERS_BASE base
## The base DN to use when performing sudo LDAP queries.
## Multiple SUDOERS_BASE lines may be specified, in which
## case they are queried in the order specified.
##
#sudoers_base ou=SUDOers,dc=example,dc=com
##
## BIND_TIMELIMIT seconds
## The BIND_TIMELIMIT parameter specifies the amount of
## time to wait while trying to connect to an LDAP server.
##
#bind_timelimit 30
##
## TIMELIMIT seconds
## The TIMELIMIT parameter specifies the amount of time
## to wait for a response to an LDAP query.
##
#timelimit 30
##
## SUDOERS_DEBUG debug_level
## This sets the debug level for sudo LDAP queries. Debugging
## information is printed to the standard error. A value of 1
## results in a moderate amount of debugging information.
## A value of 2 shows the results of the matches themselves.
##
#sudoers_debug 1

View File

@ -1,11 +1,14 @@
Summary: Allows restricted root access for specified users
Name: sudo
Version: 1.9.5p2
Release: 4%{?dist}
Release: 5%{?dist}
License: ISC
URL: https://www.sudo.ws
Source0: %{url}/dist/%{name}-%{version}.tar.gz
Source1: sudoers
Source2: sudo-ldap.conf
Requires: pam
Recommends: vim-minimal
Recommends: %{name}-python-plugin%{?_isa} = %{version}-%{release}
@ -24,8 +27,10 @@ BuildRequires: sendmail
BuildRequires: gettext
BuildRequires: zlib-devel
# don't strip
Patch1: sudo-1.6.7p5-strip.patch
Patch1: sudo-conf.patch
Patch2: sudo-1.9.5-undefined-symbol.patch
Patch3: sudo-1.9.5-selinux-t.patch
Patch4: sudo-1.9.5-sesh-bad-condition.patch
%description
Sudo (superuser do) allows a system administrator to give certain
@ -46,17 +51,6 @@ Requires: %{name} = %{version}-%{release}
The %{name}-devel package contains header files developing sudo
plugins that use %{name}.
%package logsrvd
Summary: High-performance log server for %{name}
Requires: %{name} = %{version}-%{release}
BuildRequires: openssl-devel
%description logsrvd
%{name}-logsrvd is a high-performance log server that accepts event and I/O logs from sudo.
It can be used to implement centralized logging of sudo logs.
%package python-plugin
Summary: Python plugin for %{name}
Requires: %{name} = %{version}-%{release}
@ -69,7 +63,10 @@ BuildRequires: python3-devel
%prep
%setup -q
%patch1 -p1 -b .strip
%patch1 -p1 -b .sudo-conf
%patch2 -p1 -b .undefined
%patch3 -p1 -b .selinux-t
%patch4 -p1 -b .bad-cond
%build
# Remove bundled copy of zlib
@ -89,8 +86,10 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
--sbindir=%{_sbindir} \
--libdir=%{_libdir} \
--docdir=%{_pkgdocdir} \
--enable-openssl \
--disable-openssl \
--disable-root-mailer \
--disable-log-server \
--disable-log-client \
--with-logging=syslog \
--with-logfac=authpriv \
--with-pam \
@ -103,7 +102,7 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
--with-ldap-conf-file="%{_sysconfdir}/sudo-ldap.conf" \
--with-selinux \
--with-passprompt="[sudo] password for %p: " \
--enable-python \
--enable-python \
--with-linux-audit \
--with-sssd
# --without-kerb5 \
@ -115,6 +114,10 @@ make check
%install
rm -rf $RPM_BUILD_ROOT
# Update README.LDAP (#736653)
sed -i 's|/etc/ldap\.conf|%{_sysconfdir}/sudo-ldap.conf|g' README.LDAP
make install DESTDIR="$RPM_BUILD_ROOT" install_uid=`id -u` install_gid=`id -g` sudoers_uid=`id -u` sudoers_gid=`id -g`
chmod 755 $RPM_BUILD_ROOT%{_bindir}/* $RPM_BUILD_ROOT%{_sbindir}/*
@ -122,7 +125,18 @@ install -p -d -m 700 $RPM_BUILD_ROOT/var/db/sudo
install -p -d -m 700 $RPM_BUILD_ROOT/var/db/sudo/lectured
install -p -d -m 750 $RPM_BUILD_ROOT/etc/sudoers.d
install -p -c -m 0440 %{SOURCE1} $RPM_BUILD_ROOT/etc/sudoers
#add sudo to protected packages
install -p -c -m 0640 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sudo-ldap.conf
# create sudo-ldap.conf man
echo ".so man5/sudoers.ldap.5" > sudo-ldap.conf.5
gzip sudo-ldap.conf.5
install -p -c -m 0644 sudo-ldap.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/sudo-ldap.conf.5.gz
rm -f sudo-ldap.conf.5.gz
# we are not building sendlog so we don't need this
rm -rf $RPM_BUILD_ROOT/%{_mandir}/man8/sudo_sendlog.8
# add sudo to protected packages
install -p -d -m 755 $RPM_BUILD_ROOT/etc/dnf/protected.d/
touch sudo.conf
echo sudo > sudo.conf
@ -150,13 +164,12 @@ cat sudo.lang sudoers.lang > sudo_all.lang
rm sudo.lang sudoers.lang
mkdir -p $RPM_BUILD_ROOT/etc/pam.d
cat > $RPM_BUILD_ROOT/etc/pam.d/sudo << EOF
#%%PAM-1.0
auth include system-auth
account include system-auth
password include system-auth
session optional pam_keyinit.so revoke
session required pam_limits.so
session include system-auth
EOF
@ -169,68 +182,74 @@ session optional pam_keyinit.so force revoke
session include sudo
EOF
%files -f sudo_all.lang
%defattr(-,root,root)
%attr(0440,root,root) %config(noreplace) /etc/sudoers
%attr(0640,root,root) %config(noreplace) /etc/sudo.conf
%attr(0640,root,root) %config(noreplace) %{_sysconfdir}/sudo-ldap.conf
%attr(0750,root,root) %dir /etc/sudoers.d/
%config(noreplace) /etc/pam.d/sudo
%config(noreplace) /etc/pam.d/sudo-i
%attr(0644,root,root) %{_tmpfilesdir}/sudo.conf
%attr(0644,root,root) %config(noreplace) /etc/dnf/protected.d/sudo.conf
%attr(0640,root,root) %config(noreplace) /etc/sudo.conf
%attr(0644,root,root) /etc/dnf/protected.d/sudo.conf
%dir /var/db/sudo
%dir /var/db/sudo/lectured
%attr(4111,root,root) %{_bindir}/sudo
%{_bindir}/sudoedit
%{_bindir}/cvtsudoers
%attr(0111,root,root) %{_bindir}/sudoreplay
%attr(0755,root,root) %{_sbindir}/visudo
%{_bindir}/cvtsudoers
%dir %{_libexecdir}/sudo
%attr(0755,root,root) %{_libexecdir}/sudo/sesh
%attr(0644,root,root) %{_libexecdir}/sudo/sudo_noexec.so
%attr(0644,root,root) %{_libexecdir}/sudo/sudoers.so
%attr(0644,root,root) %{_libexecdir}/sudo/audit_json.so
%attr(0644,root,root) %{_libexecdir}/sudo/group_file.so
%attr(0644,root,root) %{_libexecdir}/sudo/sudoers.so
%attr(0644,root,root) %{_libexecdir}/sudo/sample_approval.so
%attr(0644,root,root) %{_libexecdir}/sudo/group_file.so
%attr(0644,root,root) %{_libexecdir}/sudo/system_group.so
%attr(0644,root,root) %{_libexecdir}/sudo/libsudo_util.so.?.?.?
%{_libexecdir}/sudo/libsudo_util.so.?
%{_libexecdir}/sudo/libsudo_util.so
%{_mandir}/man5/sudoers.5*
%{_mandir}/man5/sudoers.ldap.5*
%{_mandir}/man5/sudo-ldap.conf.5*
%{_mandir}/man5/sudo.conf.5*
%{_mandir}/man8/sudo.8*
%{_mandir}/man8/sudoedit.8*
%{_mandir}/man8/sudoreplay.8*
%{_mandir}/man8/visudo.8*
%{_mandir}/man1/cvtsudoers.1.gz
%{_mandir}/man5/sudoers_timestamp.5.gz
%{_mandir}/man1/cvtsudoers.1*
%{_mandir}/man5/sudoers_timestamp.5*
%dir %{_pkgdocdir}/
%{_pkgdocdir}/*
%{!?_licensedir:%global license %%doc}
%license doc/LICENSE
%exclude %{_pkgdocdir}/ChangeLog
# Make sure permissions are ok even if we're updating
%post
/bin/chmod 0440 /etc/sudoers || :
%files devel
%doc plugins/sample/sample_plugin.c
%{_includedir}/sudo_plugin.h
%{_mandir}/man8/sudo_plugin.8*
%files logsrvd
%attr(0640,root,root) %config(noreplace) /etc/sudo_logsrvd.conf
%attr(0755,root,root) %{_sbindir}/sudo_logsrvd
%attr(0755,root,root) %{_sbindir}/sudo_sendlog
%{_mandir}/man5/sudo_logsrv.proto.5.gz
%{_mandir}/man5/sudo_logsrvd.conf.5.gz
%{_mandir}/man8/sudo_logsrvd.8.gz
%{_mandir}/man8/sudo_sendlog.8.gz
%files python-plugin
%{_mandir}/man8/sudo_plugin_python.8.gz
%attr(0644,root,root) %{_libexecdir}/sudo/python_plugin.so
%changelog
* Fri Jul 09 2021 Radovan Sroka <rsroka@redhat.com> - 1.9.5p2-5
RHEL 9 BETA
- sync with rhel8 spec
Resolves: rhbz#1908882
Resolves: rhbz#1942383
Resolves: rhbz#1946707
Resolves: rhbz#1946709
Resolves: rhbz#1981278
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.9.5p2-4
- Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065

View File

@ -74,7 +74,7 @@ Defaults always_query_group_plugin
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
@ -85,7 +85,7 @@ Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY
#
# Defaults env_keep += "HOME"
Defaults secure_path = /usr/sbin:/usr/bin:/sbin:/bin
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple

View File

@ -1,71 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/sudo/Sanity/fully-qualified-hostnames
# Description: checks if sudo works correctly when FQDN is used in /etc/sudoers
# Author: Milos Malik <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2011 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/sudo/Sanity/fully-qualified-hostnames
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE ssh-sudo.exp
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
chmod a+x runtest.sh
chmod a+x ssh-sudo.exp
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Milos Malik <mmalik@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: checks if sudo works correctly when FQDN is used in /etc/sudoers" >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 10m" >> $(METADATA)
@echo "RunFor: sudo" >> $(METADATA)
@echo "Requires: sudo" >> $(METADATA)
@echo "Requires: sed" >> $(METADATA)
@echo "Requires: grep" >> $(METADATA)
@echo "Requires: mktemp" >> $(METADATA)
@echo "Requires: openssh-server" >> $(METADATA)
@echo "Requires: openssh-clients" >> $(METADATA)
@echo "Requires: expect" >> $(METADATA)
@echo "Requires: shadow-utils" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,3 +0,0 @@
PURPOSE of /CoreOS/sudo/Sanity/fully-qualified-hostnames
Description: checks if sudo works correctly when FQDN is used in /etc/sudoers
Author: Milos Malik <mmalik@redhat.com>

View File

@ -1,106 +0,0 @@
#!/bin/bash
# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/sudo/Sanity/fully-qualified-hostnames
# Description: checks if sudo works correctly when FQDN is used in /etc/sudoers
# Author: Milos Malik <mmalik@redhat.com>
# Edit: Ales "alich" Marecek <amarecek@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2011 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include rhts environment
. /usr/bin/rhts-environment.sh
. /usr/share/beakerlib/beakerlib.sh
PACKAGE="sudo"
USER_NAME="user${RANDOM}"
USER_SECRET="s3kr3T${RANDOM}"
CONFIG_FILE="/etc/sudoers"
OUTPUT_FILE="sudo.log"
rlJournalStart
rlPhaseStartSetup
rlAssertRpm ${PACKAGE}
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
rlRun "cp ssh-sudo.exp ${TmpDir}" 0 "Copying expect file"
rlRun "pushd $TmpDir"
OUTPUT_FILE="${TmpDir}/${OUTPUT_FILE}"
rlFileBackup ${CONFIG_FILE} ~/.ssh
id ${USER_NAME} && userdel -r ${USER_NAME}
rlRun "useradd ${USER_NAME}"
rlRun "echo ${USER_SECRET} | passwd --stdin ${USER_NAME}"
rlRun "sed -i 's/^.*requiretty.*$//' ${CONFIG_FILE}"
rlRun "sed -i 's/^.*lecture.*$//' ${CONFIG_FILE}"
rlRun "echo \"Defaults !requiretty, !lecture\" >> ${CONFIG_FILE}"
rlRun "echo \"${USER_NAME} ${HOSTNAME} = (root) `which id`\" >> ${CONFIG_FILE}"
rlRun "> ~/.ssh/known_hosts"
rlPhaseEnd
if rlIsRHEL 5; then
rlPhaseStartTest
rlRun "strings `which sudo` | grep fqdn"
rlPhaseEnd
fi
if echo ${HOSTNAME} | grep -q '^localhost'; then
rlPhaseStartTest
rlLogInfo "skipping fqdn option enabled tests, cannot run with local-only host name ${HOSTNAME}"
rlPhaseEnd
else
rlPhaseStartTest "fqdn option is enabled, command is valid"
rlRun "sed -i 's/^.*fqdn.*$//' ${CONFIG_FILE}"
rlRun "echo \"Defaults fqdn\" >> ${CONFIG_FILE}"
rlRun "./ssh-sudo.exp ${USER_NAME} ${USER_SECRET} localhost id 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "uid=0.*gid=0.*groups=0" ${OUTPUT_FILE}
rlPhaseEnd
rlPhaseStartTest "fqdn option is enabled, command is invalid"
rlRun "sed -i 's/^.*fqdn.*$//' ${CONFIG_FILE}"
rlRun "echo \"Defaults fqdn\" >> ${CONFIG_FILE}"
rlRun "./ssh-sudo.exp ${USER_NAME} ${USER_SECRET} localhost w 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "user.*is not allowed to execute" ${OUTPUT_FILE}
rlPhaseEnd
fi
rlPhaseStartTest "fqdn option is disabled, command is valid"
rlRun "sed -i 's/^.*fqdn.*$//' ${CONFIG_FILE}"
rlRun "echo \"Defaults !fqdn\" >> ${CONFIG_FILE}"
rlRun "./ssh-sudo.exp ${USER_NAME} ${USER_SECRET} localhost id 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "uid=0.*gid=0.*groups=0" ${OUTPUT_FILE}
rlPhaseEnd
rlPhaseStartTest "fqdn option is disabled, command is invalid"
rlRun "sed -i 's/^.*fqdn.*$//' ${CONFIG_FILE}"
rlRun "echo \"Defaults !fqdn\" >> ${CONFIG_FILE}"
rlRun "./ssh-sudo.exp ${USER_NAME} ${USER_SECRET} localhost w 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "user.*is not allowed to execute" ${OUTPUT_FILE}
rlPhaseEnd
rlPhaseStartCleanup
rlRun "userdel -rf ${USER_NAME}"
rlFileRestore
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View File

@ -1,20 +0,0 @@
#!/usr/bin/expect -f
# usage:
# ./ssh-sudo.exp username password hostname command
set username [lrange $argv 0 0]
set password [lrange $argv 1 1]
set hostname [lrange $argv 2 2]
set command [lrange $argv 3 3]
set timeout 5
spawn ssh -t $username@$hostname sudo $command
expect "*yes/no*" {
send -- "yes\r"
}
expect "*assword*" {
send -- "$password\r"
}
expect "*assword*" {
send -- "$password\r"
}
expect eof

View File

@ -1,68 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/sudo/Sanity/run-as
# Description: Test feature 'run as'. This means -u, -g options.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2017 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/sudo/Sanity/run-as
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Test feature 'run as'. This means -u, -g options." >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RunFor: sudo" >> $(METADATA)
@echo "Requires: sudo" >> $(METADATA)
@echo "RhtsRequires: library(distribution/tcf)" >> $(METADATA)
@echo "RhtsRequires: library(distribution/Cleanup)" >> $(METADATA)
@echo "RhtsRequires: library(distribution/testUser)" >> $(METADATA)
@echo "RhtsRequires: library(distribution/ConditionalPhases)" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
@echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,3 +0,0 @@
PURPOSE of /CoreOS/sudo/Sanity/run-as
Description: Test feature 'run as'. This means -u, -g options.
Author: Dalibor Pospisil <dapospis@redhat.com>

View File

@ -1,59 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/Cleanup
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/Cleanup
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Provides function to define cleanup stack which can do its work at any time of the test run." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "Provides: library(distribution/Cleanup)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,314 +0,0 @@
#!/bin/bash
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = Cleanup
# library-version = 9
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_Cleanup_LIB_VERSION=9
: <<'=cut'
=pod
=head1 NAME
BeakerLib library Cleanup
=head1 DESCRIPTION
This file contains functions which provides cleanup stack functionality.
=head1 USAGE
To use this functionality you need to import library distribution/Cleanup and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/Cleanup)" >> $(METADATA)
B<Code example>
rlJournalStart
rlPhaseStartSetup
rlImport 'distribution/Cleanup'
tmp=$(mktemp)
CleanupRegister "
rlLog 'Removing data'
rlRun \"rm -f ${tmp}\"
"
rlLog 'Creating some data'
rlRun "echo 'asdfalkjh' > $tmp"
CleanupRegister "
rlLog 'just something to demonstrate unregistering'
"
ID1=$CleanupRegisterID
CleanupUnregister $ID1
CleanupRegister "
rlLog 'just something to demonstrate partial cleanup'
"
ID2=$CleanupRegisterID
CleanupRegister "rlLog 'cleanup some more things'"
# cleanup everything upto ID2
CleanupDo $ID2
CleanupRegister --mark "
rlLog 'yet another something to demonstrate partial cleanup using internal ID saving'
"
CleanupRegister "rlLog 'cleanup some more things'"
# cleanup everything upto last mark
CleanupDo --mark
rlPhaseEnd
rlPhaseStartCleanup
CleanupDo
rlPhaseEnd
rlJournalPrintText
rlJournalEnd
=head1 FUNCTIONS
=cut
echo -n "loading library Cleanup v$__INTERNAL_Cleanup_LIB_VERSION... "
__INTERNAL_Cleanup_stack_file="$BEAKERLIB_DIR/Cleanup_stack"
touch "$__INTERNAL_Cleanup_stack_file"
chmod ug+rw "$__INTERNAL_Cleanup_stack_file"
# CleanupRegister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# CleanupRegister [--mark] CLEANUP_CODE
# --mark - also mark this position
CleanupRegister() {
local mark=0
[[ "$1" == "--mark" ]] && {
mark=1
shift
}
if ! CleanupGetStack; then
rlLogError "cannot continue, could not get cleanup stack"
return 1
fi
CleanupRegisterID="${RANDOM}$(date +"%s%N")"
echo -n "Registering cleanup ID=$CleanupRegisterID" >&2
if [[ $mark -eq 1 ]]; then
__INTERNAL_CleanupMark=( "$CleanupRegisterID" "${__INTERNAL_CleanupMark[@]}" )
echo -n " with mark" >&2
fi
echo " '$1'" >&2
rlLogDebug "prepending '$1'"
local ID_tag="# ID='$CleanupRegisterID'"
__INTERNAL_Cleanup_stack="$ID_tag
$1
$ID_tag
$__INTERNAL_Cleanup_stack"
if ! CleanupSetStack "$__INTERNAL_Cleanup_stack"; then
rlLogError "an error occured while registering the cleanup '$1'"
return 1
fi
return 0
}; # end of CleanupRegister }}}
# __INTERNAL_Cleanup_get_stack_part ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# 1: ID
# -ID - everything upto the ID
# 2: '' - return ID only
# 'rest' - return exact oposit
__INTERNAL_Cleanup_get_stack_part() {
rlLogDebug "__INTERNAL_Cleanup_get_stack_part(): $* begin"
local ID="$1"
local n='1 0 1'
local stack=''
[[ "${ID:0:1}" == "-" ]] && {
ID="${ID:1}"
n='0 0 1'
}
[[ "$2" == "rest" ]] && {
n="$(echo "${n//0/2}")"
n="$(echo "${n//1/0}")"
n="$(echo "${n//2/1}")"
}
n=($n)
[[ -n "$DEBUG" ]] && rlLogDebug "$(set | grep ^n=)"
local ID_tag="# ID='$ID'"
while IFS= read -r line; do
[[ "$line" == "$ID_tag" ]] && {
n=( "${n[@]:1}" )
continue
}
if [[ $n -eq 0 ]]; then
stack="$stack
$line"
fi
done < <(echo "$__INTERNAL_Cleanup_stack")
rlLogDebug "__INTERNAL_Cleanup_get_stack_part(): cleanup stack part is '${stack:1}'"
echo "${stack:1}"
rlLogDebug "__INTERNAL_Cleanup_get_stack_part(): $* end"
}; # end of __INTERNAL_Cleanup_get_stack_part }}}
# CleanupUnregister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupUnregister() {
local ID="$1"
rlLog "Unregistering cleanup ID='$ID'"
if ! CleanupGetStack; then
rlLogError "cannot continue, could not get cleanup stack"
return 1
fi
rlLogDebug "removing ID='$ID'"
if ! CleanupSetStack "$(__INTERNAL_Cleanup_get_stack_part "$ID" 'rest')"; then
rlLogError "an error occured while registering the cleanup '$1'"
return 1
fi
return 0
}; # end of CleanupUnregister }}}
# CleanupMark ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_CleanupMark=()
CleanupMark() {
echo -n "Setting cleanup mark" >&2
CleanupRegister --mark '' 2>/dev/null
local res=$?
echo " ID='$CleanupRegisterID'" >&2
return $res
}; # end of CleanupMark }}}
# CleanupDo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# 1: '' - cleanup all
# ID - cleanup ID only
# -ID - cleanup all upto ID, including
# mark - cleanup all unto last mark, including
CleanupDo() {
local ID="$1"
if ! CleanupGetStack; then
rlLogError "cannot continue, could not get cleanup stack"
return 1
fi
local res tmp newstack=''
tmp="$(mktemp)"
if [[ "$ID" == "mark" || "$ID" == "--mark" ]]; then
echo "execute cleanup upto mark='$__INTERNAL_CleanupMark'" >&2
__INTERNAL_Cleanup_get_stack_part "-$__INTERNAL_CleanupMark" | grep -v "^# ID='" > "$tmp"
newstack="$(__INTERNAL_Cleanup_get_stack_part "-$__INTERNAL_CleanupMark" 'rest')"
__INTERNAL_CleanupMark=("${__INTERNAL_CleanupMark[@]:1}")
elif [[ -n "$ID" ]]; then
echo "execute cleanup for ID='$ID'" >&2
__INTERNAL_Cleanup_get_stack_part "$ID" | grep -v "^# ID='" > "$tmp"
newstack="$(__INTERNAL_Cleanup_get_stack_part "$ID" 'rest')"
else
CleanupTrapUnhook
trap "echo 'temporarily blocking ctrl+c until cleanup is done' >&2" SIGINT
cat "$__INTERNAL_Cleanup_stack_file" | grep -v "^# ID='" > "$tmp"
echo "execute whole cleanup stack" >&2
fi
. "$tmp"
res=$?
[[ $res -ne 0 ]] && {
echo "cleanup code:" >&2
cat -n "$tmp" >&2
}
rm -f "$tmp"
echo "cleanup execution done" >&2
if [[ -z "$ID" ]]; then
trap - SIGINT
fi
if ! CleanupSetStack "$newstack"; then
rlLogError "an error occured while cleaning the stack"
return 1
fi
return $res
}; # end of CleanupDo }}}
# CleanupGetStack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupGetStack() {
rlLogDebug "getting cleanup stack"
if [[ -r "$__INTERNAL_Cleanup_stack_file" ]]; then
if __INTERNAL_Cleanup_stack="$(cat "$__INTERNAL_Cleanup_stack_file")"; then
rlLogDebug "cleanup stack is '$__INTERNAL_Cleanup_stack'"
return 0
fi
fi
rlLogError "could not load cleanup stack"
return 1
}; # end of CleanupGetStack }}}
# CleanupSetStack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupSetStack() {
rlLogDebug "setting cleanup stack to '$1'"
__INTERNAL_Cleanup_stack="$1"
if echo "$__INTERNAL_Cleanup_stack" > "$__INTERNAL_Cleanup_stack_file"; then
rlLogDebug "cleanup stack is now '$__INTERNAL_Cleanup_stack'"
return 0
fi
rlLogError "could not set cleanup stack"
return 1
}; # end of CleanupSetStack }}}
__INTERNAL_Cleanup_signals=''
__INTERNAL_Cleanup_trap_code='rlJournalStart; rlPhaseStartCleanup; CleanupDo; rlPhaseEnd; rlJournalPrintText; rlJournalEnd; exit'
# CleanupTrapHook ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupTrapHook() {
rlLog "register cleanup trap"
__INTERNAL_Cleanup_signals="${1:-"SIGHUP SIGINT SIGTERM EXIT"}"
eval "trap \"${__INTERNAL_Cleanup_trap_code}\" $__INTERNAL_Cleanup_signals"
}; # end of CleanupTrapHook }}}
# CleanupTrapUnhook ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupTrapUnhook() {
if [[ -n "$__INTERNAL_Cleanup_signals" ]]; then
rlLog "unregister cleanup trap"
eval trap - $__INTERNAL_Cleanup_signals
__INTERNAL_Cleanup_signals=''
fi
}; # end of CleanupTrapUnhook }}}
# CleanupLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupLibraryLoaded() {
CleanupTrapHook
}; # end of CleanupLibraryLoaded }}}
echo "done."
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut

View File

@ -1,59 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/ConditionalPhases
# Description: Implements conditional phases.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/ConditionalPhases
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Implements conditional phases." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "Provides: library(distribution/ConditionalPhases)" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,166 +0,0 @@
#!/bin/bash
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = ConditionalPhases
# library-version = 2
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_ConditionalPhases_LIB_VERSION=2
__INTERNAL_ConditionalPhases_LIB_NAME='distribution/ConditionalPhases'
: <<'=cut'
=pod
=head1 NAME
BeakerLib library distribution/condpahses
=head1 DESCRIPTION
Implements conditional phases to eficiently select test phases to be execute
using white and black lists.
To use this functionality you need to import library
distribution/ConditionalPhases and add following line to Makefile.
@echo "RhtsRequires: library(distribution/ConditionalPhases)" >> $(METADATA)
=head1 USAGE
=head2 Conditional phases
Each test phase can be conditionally skipped based on a bash regular expression
given in CONDITIONAL_PHASES_BL and/or CONDITIONAL_PHASES_WL variables.
=over
=item CONDITIONAL_PHASES_BL
It is a black list. If match phase name the respective phase should be skipped.
=item CONDITIONAL_PHASES_WL
It is a white list. If does B<not> match phase name the respective phase should
be skipped excluding phases contatning 'setup' or 'cleanup' in its name. Names
'setup' and 'cleanup' are matched case insenitively.
=back
Actual skipping has to be done in the test case itself by using return code of
functions I<rlPhaseStart>, I<rlPhaseStartSetup>, I<rlPhaseStartTest>, and
I<rlPhaseStartCleanup>.
Example:
rlPhaseStartTest "phase name" && {
...
rlPhaseEnd; }
Evaluation of the phase relevancy works as follows:
1. If CONDITIONAL_PHASES_BL is non-empty and matches phase name => return 2.
2. If phase name contains word 'setup' or 'cleanup' or CONDITIONAL_PHASES_WL
is empty => return 0.
3. If CONDITIONAL_PHASES_WL is non-empty and matches phase name => return 0
otherwise return 1.
Normaly Setup and Cleanup phases are not skipped unless hey are B<explicitly>
black-listed.
To make the test work properly with conditional phases it is necessary to
surround phase code with curly brackets and make it conditionally executed
based on rlPhaseStart* function's exit code the same way as it is demostrated in
the example above. To make the process easy you can use following command:
sed 's/rlPhaseStart[^{]*$/& \&\& {/;s/rlPhaseEnd[^}]*$/&; }/'
This code can be embedded in Makefile by modifying build target to following
form:
build: $(BUILT_FILES)
grep -Eq 'rlPhase(Start[^{]*|End[^}]*)$' runtest.sh && sed -i 's/rlPhaseStart[^{]*$/& \&\& {/;s/rlPhaseEnd[^}]*$/&; }/' testrun.sh
test -x runtest.sh || chmod a+x runtest.sh
=cut
#'
echo -n "loading library $__INTERNAL_ConditionalPhases_LIB_NAME v$__INTERNAL_ConditionalPhases_LIB_VERSION... "
# ConditionalPhasesLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
ConditionalPhasesLibraryLoaded() {
if [[ -n "$CONDITIONAL_PHASES_BL" || -n "$CONDITIONAL_PHASES_WL" ]]; then
__INTERNAL_ConditionalPhases_eval() {
# check phases black-list
[[ -n "$CONDITIONAL_PHASES_BL" && "$1" =~ $CONDITIONAL_PHASES_BL ]] && {
rlLogWarning "phase '$1' should be skipped as it is defined in \$CONDITIONAL_PHASES_BL='$CONDITIONAL_PHASES_BL'"
return 2
}
# always execute Setup, Cleanup and if no PHASES (white-list) specified
[[ "$1" =~ $(echo "\<[Ss][Ee][Tt][Uu][Pp]\>") || "$1" =~ $(echo "\<[Cc][Ll][Ee][Aa][Nn][Uu][Pp]\>") ]] && {
rlLogInfo "phase '$1' will be executed as 'setup' and 'cleanup' phases are allowed by default, these can be black-listed"
return 0
}
[[ -z "$CONDITIONAL_PHASES_WL" ]] && {
rlLogInfo "phase '$1' will be executed as there is no rule for it"
return 0
}
[[ "$1" =~ $CONDITIONAL_PHASES_WL ]] && {
rlLogInfo "phase '$1' will be executed as it is defined in \$CONDITIONAL_PHASES_WL='$CONDITIONAL_PHASES_WL'"
return 0
} || {
rlLogWarning "phase '$1' should be skipped as it is not defined in \$CONDITIONAL_PHASES_WL='$CONDITIONAL_PHASES_WL'"
return 1
}
}
rlLogInfo "replacing rlPhaseStart by modified function with conditional phases implemented"
:; rlPhaseStart() {
if [ "x$1" = "xFAIL" -o "x$1" = "xWARN" ] ; then
__INTERNAL_ConditionalPhases_eval "$2" && \
rljAddPhase "$1" "$2"
return $?
else
rlLogError "rlPhaseStart: Unknown phase type: $1"
return 1
fi
}
else
rlLogInfo "Neither CONDITIONAL_PHASES_WL nor CONDITIONAL_PHASES_BL is defined, not applying modifications"
fi
}; # end of ConditionalPhasesLibraryLoaded }}}
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut
echo 'done.'

View File

@ -1,48 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/Log
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/Log
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Provides yet another logging facility that does not rely on beakerlib while it can integrate with it." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RhtsRequires: library(distribution/opts)" >> $(METADATA)
@echo "Provides: library(distribution/Log)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,637 +0,0 @@
#!/bin/bash
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2013 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = Log
# library-version = 11
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_Log_LIB_VERSION=11
: <<'=cut'
=pod
=head1 NAME
BeakerLib library Log
=head1 DESCRIPTION
This library provide logging capability which does not rely on beakerlib so it
can be used standalone.
If it is used within beakerlib it automatically bypass all messages to the
beakerlib.
Also this library provide journaling feature so the summary can be printed out
at the end.
=head1 USAGE
To use this functionality you need to import library distribution/Log and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/Log)" >> $(METADATA)
=head1 FUNCTIONS
=cut
echo -n "loading library Log v$__INTERNAL_Log_LIB_VERSION... "
__INTERNAL_Log_prefix=''
__INTERNAL_Log_prefix2=''
__INTERNAL_Log_postfix=''
__INTERNAL_Log_default_level=3
__INTERNAL_Log_level=$__INTERNAL_Log_default_level
LogSetDebugLevel() {
if [[ -n "$1" ]]; then
if [[ "$1" =~ ^[0-9]+$ ]]; then
let __INTERNAL_Log_level=$__INTERNAL_Log_default_level+$1;
else
__INTERNAL_Log_level=255
fi
else
__INTERNAL_Log_level=$__INTERNAL_Log_default_level
fi
}
LogSetDebugLevel "$DEBUG"
let __INTERNAL_Log_level_LOG=0
let __INTERNAL_Log_level_FATAL=0
let __INTERNAL_Log_level_ERROR=1
let __INTERNAL_Log_level_WARNING=2
let __INTERNAL_Log_level_INFO=3
let __INTERNAL_Log_level_DEBUG=4
let __INTERNAL_Log_level_MORE=5
let __INTERNAL_Log_level_MORE_=$__INTERNAL_Log_level_MORE+1
let __INTERNAL_Log_level_MORE__=$__INTERNAL_Log_level_MORE_+1
let __INTERNAL_Log_level_MORE___=$__INTERNAL_Log_level_MORE__+1
# Log ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
Log() {
LogMore___ -f "begin '$*'"
local pri=$2 message="${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
if [[ -n "$pri" ]]; then
LogPrintMessage "$pri" "$message"
LogjAddMessage "$pri" "$message"
else
LogPrintMessage "$(date +%H:%M:%S)" "$message"
LogjAddMessage "INFO" "$message"
fi
LogMore___ -f "end"
return 0
}; # end of Log }}}
__INTERNAL_Log_condition() {
cat <<EOF
__INTERNAL_Log_level_do=$1
if [[ \$__INTERNAL_Log_level -ge \$__INTERNAL_Log_level_do ]]; then
[[ -z "$2" ]] && return 1
else
return 0
fi
EOF
}
# LogInfo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogInfo() {
__INTERNAL_LogPrio='INFO'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_INFO \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='INFO'
Log "$1" $__INTERNAL_LogPrio
LogMore___ -f "end"
return 0
}; # end of LogInfo }}}
# LogWarn ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogWarn() {
__INTERNAL_LogPrio='WARNING'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_WARNING \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='WARNING'
Log "$1" $__INTERNAL_LogPrio
LogMore___ -f "end"
return 0
}; # end of LogWarn }}}
# LogWarning ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogWarning() {
__INTERNAL_LogPrio='WARNING'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_WARNING \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='WARNING'
Log "$1" $__INTERNAL_LogPrio
LogMore___ -f "end"
return 0
}; # end of LogWarning }}}
# LogError ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogError() {
__INTERNAL_LogPrio='ERROR'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_ERROR \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='ERROR'
Log "$1" $__INTERNAL_LogPrio
LogMore___ -f "end"
return 0
}; # end of LogError }}}
# LogFatal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogFatal() {
__INTERNAL_LogPrio='FATAL'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_FATAL \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='FATAL'
Log "$1" $__INTERNAL_LogPrio
exit 255
LogMore___ -f "end"
}; # end of LogFatal }}}
# LogPASS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogPASS() {
LogMore___ -f "begin '$*'"
Log "$1" PASS
LogMore___ -f "end"
return 0
}
LogPass() {
LogPASS "$@"
}; # end of LogPASS }}}
# LogFAIL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogFAIL() {
LogMore___ -f "begin '$*'"
Log "$1" FAIL
LogMore___ -f "end"
return 0
}
LogFail() {
LogFAIL "$@"
}; # end of LogFAIL }}}
# LogDo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogDo() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
local tmp=${BASH_REMATCH[1]:-1}
pref="${FUNCNAME[$tmp]}(): "
}
LogPrintMessage "$__INTERNAL_LogPrio" "${__INTERNAL_Log_prefix}${pref}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
return 0
}; # end of LogDo }}}
# LogDebug ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogDebug() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
__INTERNAL_Log_level_do=${2:-$__INTERNAL_Log_level_DEBUG}
__INTERNAL_LogPrio='DEBUG'
[[ $__INTERNAL_Log_level_do -ge $__INTERNAL_Log_level_MORE ]] && __INTERNAL_LogPrio="${__INTERNAL_LogPrio}:$(($__INTERNAL_Log_level_do-$__INTERNAL_Log_level_DEBUG+1))"
eval "$(__INTERNAL_Log_condition \${2:-\$__INTERNAL_Log_level_DEBUG} \"\$1\")"
LogDo $pref "$1"
return 0
}; # end of LogDebug }}}
# LogMore ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogMore() {
# log if DEBUG does not containg a number
# or the number is greater or equal to 2
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" ${2:-$__INTERNAL_Log_level_MORE}
}; # end of LogMore }}}
# LogMore_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogMore_() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE_
}; # end of LogMore_ }}}
# LogMore__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogMore__() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE__
}; # end of LogMore__ }}}
# LogMore___ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogMore___() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE___
}; # end of LogMore___ }}}
# LogMoreLow ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogMoreLow_Obs=''
LogMoreLow() {
[[ -z "$__INTERNAL_LogMoreLow_Obs" ]] && {
LogMore_ -f "LogMoreLow is obsoleted by LogMore_"
__INTERNAL_LogMoreLow_Obs=1
}
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE_
}; # end of LogMoreLow }}}
# LogMoreMed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogMoreMed_Obs=''
LogMoreMed() {
[[ -z "$__INTERNAL_LogMoreMed_Obs" ]] && {
LogMore__ -f "LogMoreMed is obsoleted by LogMore__"
__INTERNAL_LogMoreMed_Obs=1
}
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE__
}; # end of LogMoreMed }}}
# LogMoreHigh ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogMoreHigh_Obs=''
LogMoreHigh() {
[[ -z "$__INTERNAL_LogMoreHigh_Obs" ]] && {
LogMore___ -f "LogMoreHigh is obsoleted by LogMore___"
__INTERNAL_LogMoreHigh_Obs=1
}
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE___
}; # end of LogMoreHigh }}}
# LogjAddMessage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogjAddMessage() {
LogMore__ -f "begin '$*'"
__INTERNAL_Log_journal=("${__INTERNAL_Log_journal[@]}" "$1" "$2")
LogMore__ -f "end"
true;
}; # end of LogjAddMessage }}}
# __INTERNAL_LogCenterText ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogCenterText() {
local spaces=' '
# strip colors
local log_pri_strip=$(echo -en "$1" | sed -r "s:\x1B\[[0-9;]*[mK]::g")
local log_pri_strip_count=${#log_pri_strip}
local left_spaces=$(( ($2 - $log_pri_strip_count) / 2 ))
local right_spaces=$(( $2 - $log_pri_strip_count - $left_spaces ))
echo -en "${spaces:0:$left_spaces}${1}${spaces:0:$right_spaces}"
}; # end of __INTERNAL_LogCenterText }}}
# LogPrintMessage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogPrintMessage() {
echo -e ":: [$(__INTERNAL_LogCenterText "$1" 10)] :: $2" >&2
return 0
}; # end of LogPrintMessage }}}
# LogReport ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 LogReport
Prints final report similar to breakerlib's rlJournalPrintText. This is useful
mainly if you use TCF without beakerlib.
LogReport
=cut
#'
LogReport() {
echo -e "\n ====== Summary report begin ======"
local a p l i
for i in $(seq 0 2 $((${#__INTERNAL_Log_journal[@]}-1)) ); do
LogPrintMessage "${__INTERNAL_Log_journal[$i]}" "${__INTERNAL_Log_journal[$((++i))]}"
done
echo " ======= Summary report end ======="
__INTERNAL_Log_journal=()
}; # end of LogReport }}}
# LogFile ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogFile() {
LogMore__ -f "begin '$*'"
local prio=''
[[ $# -ge 3 ]] && {
optsBegin
optsAdd 'prio|tag|p|t' --mandatory
optsDone; eval "${optsCode}"
}
cat $1 | while IFS= read line; do
Log "$line" "${prio:-$2}"
done
LogMore__ -f "end"
}; #}}}
# LogText ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogText() {
LogMore__ -f "begin '$*'"
local prio=''
[[ $# -ge 3 ]] && {
optsBegin
optsAdd 'prio|tag|p|t' --mandatory
optsDone; eval "${optsCode}"
}
{
if [[ "$1" == "-" ]]; then
cat -
else
echo "$1"
fi
} | while IFS= read line; do
Log "$line" "${prio:-$2}"
done
LogMore__ -f "end"
}; #}}}
# LogStrippedDiff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogStrippedDiff() {
LogMore__ -f "begin '$*'"
local prio=''
[[ $# -ge 3 ]] && {
optsBegin
optsAdd 'prio|tag|p|t' --mandatory
optsDone; eval "${optsCode}"
}
{
if [[ -n "$2" ]]; then
diff -U0 "$1" "$2"
else
cat $1
fi
} | grep -v -e '^@@ ' -e '^--- ' -e '^+++ ' | while IFS= read line; do
Log "$line" "$prio"
done
LogMore__ -f "end"
}; #}}}
# LogRun ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogRun() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogMore
local dolog=$?
[[ $dolog -eq 0 ]] || {
local param params blacklist="[[:space:]]|>|<|\|"
[[ "${#@}" -eq 1 ]] && params="$1" || {
for param in "$@"; do
if [[ "$param" =~ $blacklist ]]; then
params="$params \"${param//\"/\\\"}\""
else
params="$params $param"
fi
done
params="${params:1}"
}
LogDo $pref "executing >>>>> ${params} <<<<<"
}
eval "$@"
ret=$?
[[ $dolog -eq 0 ]] || LogMore $pref "execution >>>>> ${params} <<<<< returned '$ret'"
return $ret
}; # end of LogRun }}}
# LogDebugNext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogDebugNext() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}))"
}
LogDebug '' ${1:-$__INTERNAL_Log_level_DEBUG} || {
__INTERNAL_Log_DEBUGING=0
trap "
__INTERNAL_Log_DEBUGING_res=\$?
let __INTERNAL_Log_DEBUGING++
if [[ \$__INTERNAL_Log_DEBUGING -eq 1 ]]; then
__INTERNAL_Log_DEBUGING_cmd=\"\$BASH_COMMAND\"
LogDebug $pref \"executing >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<<\" ${1:-$__INTERNAL_Log_level_DEBUG}
else
trap - DEBUG
LogDebug $pref \"execution >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<< returned \$__INTERNAL_Log_DEBUGING_res\" ${1:-$__INTERNAL_Log_level_DEBUG}
fi" DEBUG
}
}; # end of LogDebugNext }}}
# LogMoreNext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogMoreNext() {
LogMore || {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}))"
}
LogDebugNext $pref ${1:-$__INTERNAL_Log_level_MORE}
}
}; # end of LogMoreNext }}}
LogNext() {
LogMoreNext "$@"
}
# LogDebugOn ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogDebugOn() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}))"
}
LogDebug '' ${1:-$__INTERNAL_Log_level_DEBUG} || {
trap "
__INTERNAL_Log_DEBUGING_res=\$?
let __INTERNAL_Log_DEBUGING++
if [[ -z \"\$__INTERNAL_Log_DEBUGING_cmd\" ]]; then
__INTERNAL_Log_DEBUGING_cmd=\"\$BASH_COMMAND\"
LogDebug $pref \"executing >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<<\" ${1:-$__INTERNAL_Log_level_DEBUG}
else
LogDebug $pref \"execution >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<< returned \$__INTERNAL_Log_DEBUGING_res\" ${1:-$__INTERNAL_Log_level_DEBUG}
__INTERNAL_Log_DEBUGING_cmd=\"\$BASH_COMMAND\"
if [[ \"\$__INTERNAL_Log_DEBUGING_cmd\" =~ LogDebugOff ]]; then
trap - DEBUG
else
LogDebug $pref \"executing >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<<\" ${1:-$__INTERNAL_Log_level_DEBUG}
fi
fi" DEBUG
}
}; # end of LogDebugOn }}}
# LogMoreOn ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogMoreOn() {
LogMore || {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}))"
}
LogDebugOn $pref ${1:-$__INTERNAL_Log_level_MORE}
}
}; # end of LogMoreOn }}}
# LogDebugOff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogDebugOff() {
__INTERNAL_Log_DEBUGING_cmd=''
}; # end of LogDebugOff }}}
# LogVar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogVar() {
[[ -n "$DEBUG" ]] && {
echo -n 'eval '
while [[ -n "$1" ]]; do
echo -n "LogDebug -f \"\$(set | grep -P '^$1=')\";"
shift
done
}
}; # end of LogVar }}}
# __INTERNAL_LogRedirectToBeakerlib ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogRedirectToBeakerlib() {
echo -e "\nrunning inside the beakerlib - redirect own logging functions to beakerlib ones"
true; LogjAddMessage() {
LogMore___ -f "begin $*"
rljAddMessage "$2" "$1"
LogMore___ -f "end $*"
}
true; Log() {
LogMore___ -f "begin $*"
case ${2} in
INFO)
LogjAddMessage "INFO" "$1"
LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
;;
BEGIN)
LogjAddMessage "INFO" "$*:"
LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
;;
WARNING|WARN|ERROR|FATAL)
LogjAddMessage "WARNING" "$1"
LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
;;
SKIP|SKIPPING)
LogjAddMessage "WARNING" "$*:"
LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
;;
FAIL)
rlFail "$*"
return $?
;;
PASS)
rlPass "$*"
return $?
;;
*)
rlLog "$*"
;;
esac
LogMore___ -f "end $*"
return 0;
}
}
# end of __INTERNAL_LogRedirectToBeakerlib }}}
# LogLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogLibraryLoaded() {
declare -F rlDie > /dev/null && __INTERNAL_LogRedirectToBeakerlib
return 0
}; # end of LogLibraryLoaded }}}
echo "done."
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut

View File

@ -1,48 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/opts
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/opts
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Provides simple way for defining script's or function's options including help" >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RhtsRequires: library(distribution/Log)" >> $(METADATA)
@echo "Provides: library(distribution/opts)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,338 +0,0 @@
#!/bin/bash
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2013 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = opts
# library-version = 4
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_opts_LIB_VERSION=4
: <<'=cut'
=pod
=head1 NAME
BeakerLib library opts
=head1 DESCRIPTION
This library provides simple way for defining script's or function's option
agruments including help.
=head1 USAGE
To use this functionality you need to import library distribution/opts and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/opts)" >> $(METADATA)
B<Code example>
testfunction() {
optsBegin -h "Usage: $0 [options]
options:
"
optsAdd 'flag1' --flag
optsAdd 'optional1|o' --optional
optsAdd 'Optional2|O' "echo opt \$1" --optional --long --var-name opt
optsAdd 'mandatory1|m' "echo man \$1" --mandatory
optsDone; eval "${optsCode}"
echo "$optional1"
echo "$opt"
echo "$mandatory1"
}
=head1 FUNCTIONS
=cut
echo -n "loading library opts v$__INTERNAL_opts_LIB_VERSION... "
# optsAdd ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsAdd() {
LogMoreMed -f "begin '$*'"
local GETOPT=$(getopt -q -o fomv:d:lh:l -l flag,opt,optional,mandatory,varname:,default:,local,help:,long -- "$@")
eval set -- "$GETOPT"
local type='f' var_name var_name_set default help long
while [[ -n "$@" ]]; do
case $1 in
--)
shift; break
;;
-h|--help)
shift
help="$1"
;;
-l|--long)
long=1
;;
-d|--default)
shift
default="$1"
;;
-v|--varname|--var-name)
shift
var_name="$1"
var_name_set=1
;;
-f|--flag)
type='f'
;;
-o|--opt|--optional)
type='o'
;;
-m|--mandatory)
type='m'
;;
*)
echo "unknown option '$1'"
return 1
;;
esac
shift;
done
[ -z "$var_name" ] && {
var_name=$(echo -n "$1" | cut -d '|' -f 1 | sed -e 's/-//g;s/^[0-9]/_\0/')
LogMoreHigh -f "constructing variable name '$var_name'"
}
local opts='' opts_help='' optsi=''
for optsi in $(echo -n "$1" | tr '|' ' '); do
if [[ ${#optsi} -ge 2 || $long -eq 1 ]]; then
opts="$opts|--$optsi"
opts_help="$opts_help|--$optsi[=ARG]"
__INTERNAL_opts_long="${__INTERNAL_opts_long},${optsi}"
LogMoreHigh -f "adding long option '$optsi'"
case $type in
m)
__INTERNAL_opts_long="${__INTERNAL_opts_long}:"
;;
o)
__INTERNAL_opts_long="${__INTERNAL_opts_long}::"
;;
esac
else
opts="$opts|-$optsi"
opts_help="$opts_help|-${optsi}[ARG]"
__INTERNAL_opts_short="${__INTERNAL_opts_short}${optsi}"
LogMoreHigh -f "adding short option '$optsi'"
case $type in
m)
__INTERNAL_opts_short="${__INTERNAL_opts_short}:"
;;
o)
__INTERNAL_opts_short="${__INTERNAL_opts_short}::"
;;
esac
fi
done
optsCode="${optsCode}
${opts:1})
optsPresent=\"\${optsPresent}$var_name \""
LogMoreHigh -f "adding code for processing option '${opts:1}'"
__INTERNAL_opts_init_var="$__INTERNAL_opts_init_var
${__INTERNAL_opts_local}$var_name=()"
__INTERNAL_opts_default="$__INTERNAL_opts_default
[[ \"\$optsPresent\" =~ \$(echo \"\<${var_name}\>\") ]] || ${__INTERNAL_opts_local}$var_name='$default'"
case $type in
f)
[[ -z "$2" || -n "$var_name_set" ]] && {
local val=1
[[ -n "$default" ]] && val=''
optsCode="$optsCode
$var_name+=( '$val' )"
}
__INTERNAL_opts_help="${__INTERNAL_opts_help}
${opts:1}"
;;
o|m)
optsCode="$optsCode
shift"
[[ -z "$2" || -n "$var_name_set" ]] && optsCode="$optsCode
$var_name+=( \"\$1\" )"
if [[ "$type" == "o" ]]; then
__INTERNAL_opts_help="${__INTERNAL_opts_help}
${opts_help:1}"
else
__INTERNAL_opts_help="${__INTERNAL_opts_help}
${opts:1} ARG"
fi
;;
esac
[[ -n "$2" ]] && {
optsCode="$optsCode
$2"
}
optsCode="$optsCode
;;"
__INTERNAL_opts_help="${__INTERNAL_opts_help}${help:+
$help
}"
LogMoreMed -f "end"
}; # end of optsAdd }}}
# optsBegin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsBegin() {
LogMoreMed -f "begin '$*'"
optsCode=''
optsPresent=' '
__INTERNAL_opts_short='.'
__INTERNAL_opts_long='help'
__INTERNAL_opts_help=''
__INTERNAL_opts_local=''
__INTERNAL_opts_default=''
__INTERNAL_opts_init_var=''
[[ "${FUNCNAME[1]}" != "main" ]] && __INTERNAL_opts_local='local '
while [[ -n "$1" ]]; do
case $1 in
--)
shift; break
;;
-h|--help)
shift
__INTERNAL_opts_help="$1"
;;
*)
echo "unknown option '$1'"
return 1
;;
esac
shift;
done
LogMoreMed -f "end"
}; # end of optsBegin }}}
# optsDone ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsDone() {
LogMoreMed -f "begin '$*'"
optsCode="${__INTERNAL_opts_local}GETOPT=\$(getopt -o ${__INTERNAL_opts_short} -l ${__INTERNAL_opts_long} -- \"\$@\")
[[ \$? -ne 0 ]] && {
echo 'Exiting'
return 1 >& /dev/null
exit 1
}
eval set -- \"\$GETOPT\"
${__INTERNAL_opts_init_var:1}
while [[ -n \"\$1\" ]]; do
case \$1 in
--)
shift; break
;;
${optsCode}
--help)
echo \"\$__INTERNAL_opts_help\"
return >& /dev/null
exit
;;
*)
echo \"unknown option '\$1'\"
return 1 >& /dev/null
exit 1
;;
esac
shift
done
${__INTERNAL_opts_default:1}
unset optsCode __INTERNAL_opts_help __INTERNAL_opts_short __INTERNAL_opts_long __INTERNAL_opts_default __INTERNAL_opts_init_var __INTERNAL_opts_local
"
if ! echo "$optsCode" | grep -q -- '--help$'; then
__INTERNAL_opts_help="$__INTERNAL_opts_help
--help
Show this help."
fi
LogMoreHigh -f "optsCode:\n$optsCode"
LogMoreMed -f "end"
}; # end of optsDone }}}
# optsSelfCheck ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsSelfCheck() {
optsBegin -h "Usage: $0 [options]
options:
"
# optsAdd 'help' -f 'echo help'
optsAdd 'flag' -f 'echo f'
optsAdd 'optional|o' -o "echo opt \$1"
optsAdd 'Optional|O' -o "echo opt \$1" --long
optsAdd 'mandatory|m' -m "echo man \$1"
optsDone
echo "${optsCode}"
echo ...
eval "${optsCode}"
echo ...
fce() {
optsBegin -h "Usage: $0 [options]
options:
"
# optsAdd 'help' -f 'echo help'
optsAdd 'flag' -f
optsAdd 'optional|o' -o "echo opt \$1"
optsAdd 'Optional|O' -o "echo opt \$1" --long
optsAdd 'mandatory|m' -m "echo man \$1"
optsDone
echo "${optsCode}"
echo ...
eval "${optsCode}"
echo ...
}
echo -e 'test for opts in function\n========================='
fce --help
}; # end of optsSelfCheck }}}
# optsLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsLibraryLoaded() {
return 0
}; # end of LogLibraryLoaded }}}
echo "done."
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut

View File

@ -1,60 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/tcf
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/tcf
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Block style coding with ability of skipping parts." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RhtsRequires: library(distribution/Log)" >> $(METADATA)
@echo "Provides: library(distribution/tcf)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,903 +0,0 @@
#!/bin/bash
# try-check-final.sh
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = tcf
# library-version = 14
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_tcf_LIB_VERSION=14
: <<'=cut'
=pod
=head1 NAME
BeakerLib library Try-Check-Final
=head1 DESCRIPTION
This file contains functions which gives user the ability to define blocks of
code where some of the blocks can be automatically skipped if some of preceeding
blocks failed.
ATTENTION
This plugin modifies some beakerlib functions! If you suspect that it breakes
some functionality set the environment variable TCF_NOHACK to nonempty value.
=head1 USAGE
To use this functionality you need to import library distribution/tcf and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/tcf)" >> $(METADATA)
=head1 FUNCTIONS
=cut
echo -n "loading library try-check-final v$__INTERNAL_tcf_LIB_VERSION... "
let __INTERNAL_tcf_DEBUG_LEVEL_LOW=3
let __INTERNAL_tcf_DEBUG_LEVEL_MED=$__INTERNAL_tcf_DEBUG_LEVEL_LOW+1
let __INTERNAL_tcf_DEBUG_LEVEL_HIGH=$__INTERNAL_tcf_DEBUG_LEVEL_LOW+2
# global variables {{{
__INTERNAL_tcf_result=0
__INTERNAL_tcf_result_file="${BEAKERLIB_DIR:-"/var/tmp"}/tcf.result"
echo -n "$__INTERNAL_tcf_result" > "$__INTERNAL_tcf_result_file"
__INTERNAL_tcf_current_level_data=()
__INTERNAL_tcf_current_level_val=0
__INTERNAL_tcf_journal=()
#}}}
# __INTERNAL_tcf_colorize ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_colorize() {
local a
case $1 in
PASS)
a="${__INTERNAL_tcf_color_green}${1}${__INTERNAL_tcf_color_reset}"
;;
FAIL)
a="${__INTERNAL_tcf_color_red}${1}${__INTERNAL_tcf_color_reset}"
;;
SKIPPING|WARNING)
a="${__INTERNAL_tcf_color_yellow}${1}${__INTERNAL_tcf_color_reset}"
;;
BEGIN|INFO)
a="${__INTERNAL_tcf_color_blue}${1}${__INTERNAL_tcf_color_reset}"
;;
*)
a=$1
esac
echo -n "$a"
}; # end of __INTERNAL_tcf_colorize }}}
# __INTERNAL_tcf_colors_setup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_colors_setup(){
T="$TERM"
[[ -t 1 ]] || T=""
[[ -t 2 ]] || T=""
[[ "$1" == "--force" ]] && T="xterm"
case $T in
xterm|screen)
__INTERNAL_tcf_color_black="\e[0;30m"
__INTERNAL_tcf_color_dark_gray="\e[1;30m"
__INTERNAL_tcf_color_blue="\e[0;34m"
__INTERNAL_tcf_color_light_blue="\e[1;34m"
__INTERNAL_tcf_color_green="\e[0;32m"
__INTERNAL_tcf_color_light_green="\e[1;32m"
__INTERNAL_tcf_color_cyan="\e[0;36m"
__INTERNAL_tcf_color_light_cyan="\e[1;36m"
__INTERNAL_tcf_color_red="\e[0;31m"
__INTERNAL_tcf_color_light_red="\e[1;31m"
__INTERNAL_tcf_color_purple="\e[0;35m"
__INTERNAL_tcf_color_light_purple="\e[1;35m"
__INTERNAL_tcf_color_brown="\e[0;33m"
__INTERNAL_tcf_color_yellow="\e[1;33m"
__INTERNAL_tcf_color_light_gray="\e[0;37m"
__INTERNAL_tcf_color_white="\e[1;37m"
__INTERNAL_tcf_color_reset="\e[00m"
;;
* )
__INTERNAL_tcf_color_black=""
__INTERNAL_tcf_color_dark_gray=""
__INTERNAL_tcf_color_blue=""
__INTERNAL_tcf_color_light_blue=""
__INTERNAL_tcf_color_green=""
__INTERNAL_tcf_color_light_green=""
__INTERNAL_tcf_color_cyan=""
__INTERNAL_tcf_color_light_cyan=""
__INTERNAL_tcf_color_red=""
__INTERNAL_tcf_color_light_red=""
__INTERNAL_tcf_color_purple=""
__INTERNAL_tcf_color_light_purple=""
__INTERNAL_tcf_color_brown=""
__INTERNAL_tcf_color_yellow=""
__INTERNAL_tcf_color_light_gray=""
__INTERNAL_tcf_color_white=""
__INTERNAL_tcf_color_reset=""
;;
esac
}; # end of __INTERNAL_tcf_colors_setup
__INTERNAL_tcf_colors_setup; # }}}
# __INTERNAL_tcf_copy_function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_copy_function() {
declare -F $1 > /dev/null || return 1
eval "$(echo -n "${2}() "; declare -f ${1} | tail -n +2)"
}; # end of __INTERNAL_tcf_copy_function }}}
# __INTERNAL_tcf_addE2R ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_addE2R() {
__INTERNAL_tcf_copy_function $1 TCF_orig_$1
eval "${1}() { TCF_orig_${1} \"\$@\"; tcfE2R; }"
}; # end of __INTERNAL_tcf_addE2R }}}
# __INTERNAL_tcf_insertE2R ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_insertE2R() {
__INTERNAL_tcf_copy_function $1 TCF_orig_$1
eval "$(echo -n "${1}() "; declare -f ${1} | tail -n +2 | sed -e 's/\(.*__INTERNAL_ConditionalAssert.*\)/\1\ntcfE2R;/')"
}; # end of __INTERNAL_tcf_insertE2R }}}
# __INTERNAL_tcf_get_current_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_get_current_level() {
local l=$__INTERNAL_tcf_current_level_val
if [[ $1 ]]; then
l=$(($l+$1))
fi
local i
for i in $(seq 1 $(($l*2)) ); do echo -n " "; done
return $l
}; # end of __INTERNAL_tcf_get_current_level }}}
# __INTERNAL_tcf_incr_current_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_incr_current_level() {
let __INTERNAL_tcf_current_level_val++
__INTERNAL_Log_prefix=$(__INTERNAL_tcf_get_current_level)
}; # end of __INTERNAL_tcf_incr_current_level }}}
# __INTERNAL_tcf_decr_current_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_decr_current_level() {
let __INTERNAL_tcf_current_level_val--
__INTERNAL_Log_prefix=$(__INTERNAL_tcf_get_current_level)
}; # end of __INTERNAL_tcf_decr_current_level }}}
# __INTERNAL_tcf_do_hack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_do_hack() {
LogDebug "TCF_NOHACK='$TCF_NOHACK'"
if [[ -z "$TCF_NOHACK" ]]; then
tcfChk "Apply TCF beakerlib hacks" && {
rlLog " injecting tcf hacks into the beakerlib functions"
echo -n "patching rlLog"
local rlL=$(declare -f rlLog | sed -e 's|\] ::|\0${__INTERNAL_Log_prefix}|;s|$3 $1"|${3:+"$3 "}$1"|')
eval "$rlL"
echo -n ", rljAddTest"
__INTERNAL_tcf_copy_function rljAddTest __INTERNAL_tcf_orig_rljAddTest
true; rljAddTest() {
local a="${__INTERNAL_Log_prefix}$1"; shift
[[ "$1" != "FAIL" ]]; tcfE2R
__INTERNAL_tcf_journal=("${__INTERNAL_tcf_journal[@]}" "$1" "$a")
__INTERNAL_tcf_orig_rljAddTest "$a" "$@"
}
echo -n ", rljAddMessage"
__INTERNAL_tcf_copy_function rljAddMessage __INTERNAL_tcf_orig_rljAddMessage
true; rljAddMessage() {
local a="${__INTERNAL_Log_prefix}$1"; shift
__INTERNAL_tcf_journal=("${__INTERNAL_tcf_journal[@]}" "$1" "$a")
__INTERNAL_tcf_orig_rljAddMessage "$a" "$@"
}
echo -n ", __INTERNAL_LogAndJournalFail"
__INTERNAL_tcf_copy_function __INTERNAL_LogAndJournalFail __INTERNAL_tcf_orig___INTERNAL_LogAndJournalFail
true; __INTERNAL_LogAndJournalFail() {
tcfNOK
__INTERNAL_tcf_orig___INTERNAL_LogAndJournalFail "$@"
}
echo "."
tcfFin --no-assert --ignore; }
else
Log "skip hacking beakerlib functions"
fi
}; # end of __INTERNAL_tcf_do_hack }}}
# __INTERNAL_tcf_kill_old_plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_kill_old_plugin() {
tcfChk "Get rid of the old TCF implementation. removing" && {
local comma='' i
for i in Try Chk Fin E2R RES OK NOK NEG TCFcheckFinal TCFreport; do
echo -n "${comma}rl$i"
unset -f rl$i
comma=', '
done
echo '.'
tcfFin --no-assert; }
}; # end of __INTERNAL_tcf_kill_old_plugin }}}
: <<'=cut'
=pod
=head2 Block functions
=cut
# __INTERNAL_tcf_parse_params ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_parse_params() {
local GETOPT=$(getopt -q -o if: -l ignore,no-assert,fail-tag: -- "$@")
eval set -- "$GETOPT"
echo "local ignore noass title fail_tag"
echo "[ -z \"\$ignore\" ] && ignore=0"
echo "[ -z \"\$noass\" ] && noass=0"
echo "[ -z \"\$fail_tag\" ] && fail_tag='FAIL'"
while [[ -n "$@" ]]; do
case $1 in
--)
shift; break
;;
--ignore|-i)
echo "ignore=1"
echo "noass=1"
;;
--no-assert|-n)
echo "noass=1"
;;
--fail-tag|-f)
shift
echo "fail_tag='$1'"
;;
*)
echo "unknown option $1"
return 1
;;
esac
shift;
done
[[ -n "$1" ]] && echo "title=\"${1}\""
echo "eval set -- \"$(echo "$GETOPT" | sed -e 's/.*-- //')\""
}; # end of __INTERNAL_tcf_parse_params }}}
# tcfTry ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfTry
Starting function of block which will be skipped if an error has been detected
by tcfFin function occurent before.
tcfTry ["title"] [-i|--ignore] [--no-assert] [--fail-tag TAG] && {
<some code>
tcfFin; }
If title is omitted than noting is printed out so no error will be reported (no
Assert is executed) thus at least the very top level tcfTry should have title.
tcfTry and tcfChk blocks are stackable so you can organize them into a hierarchy
structure.
Note that tcfFin has to be used otherwise the overall result will not be
accurate.
=over
=item title
Text which will be displayed and logged at the beginning and the end (in tcfFin
function) of the block.
=item -i, --ignore
Do not propagate the actual result to the higher level result.
=item -n, --no-assert
Do not log error into the journal.
=item -f, --fail-tag TAG
If the result of the block is FAIL, use TAG instead ie. INFO or WARNING.
=back
Returns 1 if and error occured before, otherwise returns 0.
=cut
tcfTry() {
LogMoreLow -f "begin '$*'"
local vars=$(__INTERNAL_tcf_parse_params "$@") || { Log "$vars" FAIL; return 1; }
LogMoreMed -f "vars:\n$vars"
LogMoreLow -f "evaluating options start"
eval "$vars"
LogMoreLow -f "evaluating options end"
local incr=
local pp="SKIPPING"
tcfRES; # to set __INTERNAL_tcf_result
LogMoreLow -f "result was $__INTERNAL_tcf_result"
if [[ $__INTERNAL_tcf_result -eq 0 ]]; then
__INTERNAL_tcf_current_level_data=("$__INTERNAL_tcf_result" "$vars" "${__INTERNAL_tcf_current_level_data[@]}")
pp="BEGIN"
incr=1
fi
if [[ -n "$title" ]]; then
Log "$title" "$pp"
[[ -n "$incr" ]] && {
LogMoreLow -f "increment indentation level"
__INTERNAL_tcf_incr_current_level
}
fi
LogMoreLow -f "end"
return $__INTERNAL_tcf_result
}; # end of tcfTry }}}
# tcfChk ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfChk
Starting function of block which will be always executed.
tcfChk ["title"] [-i|--ignore] [--no-assert] [--fail-tag TAG] && {
<some code>
tcfFin; }
If title is omitted than noting is printed out so no error will be reported (no
Assert is executed) thus at least the very top level tcfChk should have title.
tcfTry and tcfChk blocks are stackable so you can organize them into a hierarchy
structure.
Note that tcfFin has to be used otherwise the overall result will not be
accurate.
For details about arguments see tcfTry.
Returns 0.
=cut
tcfChk() {
LogMoreLow -f "begin '$*'"
tcfRES; # to set __INTERNAL_tcf_result
local res=$__INTERNAL_tcf_result
tcfRES 0
tcfTry "$@"
__INTERNAL_tcf_current_level_data[0]=$res
LogMoreLow -f "end"
return $__INTERNAL_tcf_result
}; # end of tcfChk }}}
# tcfFin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfFin
Ending function of block. It does some evaluation of previous local and global
results and puts it into the global result.
tcfTry ["title"] && {
<some code>
tcfFin [-i|--ignore] [--no-assert] [--fail-tag TAG]; }
Local result is actualy exit code of the last command int the body.
Global result is an internal varibale hodning previous local results.
Respectively last error or 0.
For details about arguments see tcfTry.
Returns local result of the preceeding block.
=cut
tcfFin() {
local RES=$?
LogMoreLow -f "begin '$*'"
LogMoreMed -f "previous exit code was '$RES'"
local vars=$(__INTERNAL_tcf_parse_params "$@") || { Log "$vars" FAIL; return 1; }
LogMoreMed -f "vars:\n$vars"
LogMoreLow -f "evaluating options start"
eval "$vars"
LogMoreLow -f "evaluating options end"
tcfRES; # to set __INTERNAL_tcf_result
[[ $RES -ne 0 ]] && tcfRES $RES
RES=$__INTERNAL_tcf_result
LogMoreMed -f "overall result is '$RES'"
LogMoreMed -f "data:\n${__INTERNAL_tcf_current_level_data[1]}"
LogMoreLow -f "evaluating data start"
eval "${__INTERNAL_tcf_current_level_data[1]}"
LogMoreLow -f "evaluating data end"
if [[ -n "$title" ]]; then
__INTERNAL_tcf_decr_current_level
if [[ $ignore -eq 1 ]]; then
RES=0
[[ $__INTERNAL_tcf_result -ne 0 ]] && title="$title - ignored"
fi
if [[ $noass -eq 0 ]]; then
tcfAssert0 "$title" $__INTERNAL_tcf_result "$fail_tag"
else
if [[ $__INTERNAL_tcf_result -eq 0 ]]; then
local pp="PASS"
LogInfo "$title - $pp"
else
local pp="${fail_tag:-FAIL}"
LogWarn "$title - $pp"
fi
fi
fi
if [[ $__INTERNAL_tcf_result -eq 0 || $ignore -eq 1 ]]; then
tcfRES ${__INTERNAL_tcf_current_level_data[0]}
fi
local i
for i in 0 1; do unset __INTERNAL_tcf_current_level_data[$i]; done
__INTERNAL_tcf_current_level_data=("${__INTERNAL_tcf_current_level_data[@]}")
LogMoreLow -f "end"
return $RES
}; # end of tcfFin }}}
: <<'=cut'
=pod
=head2 Functions for manipulation with the results
=cut
# tcfRES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfRES
Sets and return the global result.
tcfRES [-p|--print] [number]
=over
=item -p --print
Also print the result value.
=item number
If present the global result is set to this value.
=back
Returns global result.
=cut
tcfRES() {
local p=0
while [[ -n "$1" ]]; do
case $1 in
--print|-p)
p=1
;;
*)
break
;;
esac
shift
done
if [[ -n "$1" ]]; then
__INTERNAL_tcf_result=$1
echo -n "$__INTERNAL_tcf_result" > "$__INTERNAL_tcf_result_file"
else
__INTERNAL_tcf_result="$(cat "$__INTERNAL_tcf_result_file")"
fi
[[ $p -eq 1 ]] && echo $__INTERNAL_tcf_result
return $__INTERNAL_tcf_result
}; # end of tcfRES }}}
# tcfOK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfOK
Sets the global result to 0.
tcfOK
Returns global result.
=cut
tcfOK() {
tcfRES 0
}; # end of tcfOK }}}
# tcfNOK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfNOK
Sets the global result to 1 or given number.
tcfNOK [number]
=over
=item number
If present the global result is set to this value.
=back
Returns global result.
=cut
tcfNOK() {
if [[ -n "$1" ]]; then
[[ $1 -eq 0 ]] && echo "You have requested result '0'. You should use tcfOK instead."
tcfRES $1
else
tcfRES 1
fi
}; # end of tcfNOK }}}
# tcfE2R ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfE2R
Converts exit code of previous command to local result if the exit code is not 0
(zero).
<some command>
tcfE2R [number]
=over
=item number
If present use it instead of exit code.
=back
Returns original exit code or given number.
=cut
tcfE2R() {
local res=$?
[[ -n "$1" ]] && res=$1
[[ $res -ne 0 ]] && tcfRES $res
return $res
}; # end of tcfE2R }}}
: <<'=cut'
=pod
=head2 Functions for manipulation with the exit codes
=cut
# tcfNEG ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfNEG
Negates exit code of previous command.
<some command>
tcfNEG
Returns 1 if original exit code was 0, otherwise returns 0.
=cut
tcfNEG() {
[[ $? -eq 0 ]] && return 1 || return 0
}; # end of tcfNEG }}}
# tcfRun ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfRun
Simmilar to rlRun but it also annouces the beginnign of the command.
tcfRun [--fail-tag|-f TAG] command [exp_result [title]]
Moreover if 'command not found' appears on STDERR it should produce WARNING.
=over
=item command
Command to execute.
=item exp_result
Specification of expect resutl.
It can be a list of values or intervals or * for any result. Also negation (!) can be used.
Example:
<=2,7,10-12,>252,!254 means following values 0,1,2,7,10,11,12,253,255
=item title
Text which will be displayed and logged at the beginning and the end of command execution.
=item --fail-tag | -f
If the command fails use TAG instead of FAIL.
=back
Returns exit code of the executed command.
=cut
tcfRun() {
LogMore_ -f "begin $*"
optsBegin
optsAdd 'fail-tag|f' --mandatory
optsAdd 'timeout' --optional 'timeout="${1:-10}"'
optsAdd 'kill-timeout|kt' --mandatory --default 5
optsAdd 'signal' --mandatory --default TERM
optsAdd 'check-code' --mandatory --default 'kill -0 $cmdpid >&/dev/null'
optsAdd 'kill-code' --mandatory --default '/bin/kill -$signal -- $cmdpid'
optsAdd 'allow-skip|as' --flag
optsAdd 'no-assert|n' --flag
optsDone; eval "${optsCode}"
LogMore_ -f "after opts $*"
[[ -z "$allowskip" ]] && tcfChk
local orig_expecode="${2:-0}"
local expecode="$orig_expecode"
[[ "$expecode" == "*" ]] && expecode="0-255"
local command="$1"
local comment="Running command '$command'"
[[ -n "$3" ]] && comment="$3"
[[ -n "$expecode" ]] && {
expecode=$(echo "$expecode" | tr ',-' '\n ' | sed -e 's/^!=/!/;s/^=//;s/^<=\(.\+\)$/0 \1/;s/^>=\(.\+\)$/\1 255/;s/^<\(.\+\)$/0 \$(( \1 - 1 ))/;s/^>\(.\+\)$/\$(( \1 + 1 )) 255/' | while read line; do [[ "$line" =~ ^[^\ ]+$ ]] && echo "$line" || eval seq $line; done; )
tcfE2R
LogMoreLow -f "orig_expecode='$orig_expecode'"
LogMoreLow -f "expecode='$expecode'"
}
tcfTry ${noassert:+--no-assert} "$comment" && {
local errout=$(mktemp)
LogMoreLow -f "executing '$command'"
if [[ "$optsPresent" =~ $(echo "\<timeout\>") ]]; then
LogDebug -f "using watchdog feature"
local ec="$(mktemp)"
eval "$command; echo $? > $ec 2> >(tee $errout)" &
local cmdpid=$!
local time_start=$(date +%s)
local timeout_t=$(( $time_start + $timeout ))
while true; do
if ! eval "$checkcode"; then
Log "command finished in $(($(date +%s) - $time_start )) seconds"
local res="$(cat $ec)"
break
elif [[ $(date +%s) -ge $timeout_t ]]; then
echo
Log "command is still running, sending $signal signal"
eval "$killcode"
tcfNOK 255
echo 255 > $ec
let timeout_t+=killtimeout
signal=KILL
fi
sleep 0.1
done
rm -f $ec
else
eval "$command" 2> >(tee $errout)
local res=$?
fi
LogMoreLow -f "got '$res'"
local resmatch=$(echo "$expecode" | grep "^\!\?${res}$")
LogMoreLow -f "resmatch='$resmatch'"
[[ -n "$resmatch" && ! "$resmatch" =~ '!' ]]
if tcfE2R; then
! grep -iq "command not found" $errout || { failtag='WARNING'; tcfNOK; }
else
Log "Expected result was '$orig_expecode', got '$res'!"
fi
tcfFin ${failtag:+--fail-tag "$failtag"}; }
rm -f $errout
[[ -z "$allowskip" ]] && tcfFin
LogMore_ -f "end $*"
return $res
}; # end of tcfRun }}}
: <<'=cut'
=pod
=head2 Functions for logging
=cut
# tcfAssert0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
tcfAssert0() {
LogMoreLow -f "begin '$*'"
local RES="${3:-FAIL}"
[[ $2 -eq 0 ]] && RES='PASS'
Log "$1" $RES
LogMoreLow -f "end"
}; # end of tcfAssert0 }}}
# tcfCheckFinal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfCheckFinal
Check that all tcfTry / tcfChk functions have been close by tcfFin.
tcfCheckFinal
=cut
tcfCheckFinal() {
tcfAssert0 "Check that TCF block cache is empty" ${#__INTERNAL_tcf_current_level_data[@]}
tcfAssert0 "Check that TCF current level is 0" $__INTERNAL_tcf_current_level_val
}; # end of tcfCheckFinal }}}
echo "done."
: <<'=cut'
=pod
=head2 Self check functions
=cut
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# tcfSelfCheck {{{
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head3 tcfSelfCheck
Does some basic functionality tests.
tcfSelfCheck
The function is called also by the following command:
./lib.sh selfcheck
=cut
tcfSelfCheck() {
tcfChk "check 1" &&{
tcfTry "try 1.1 - true" &&{
true
tcfFin;}
tcfTry "try 1.2 - false" &&{
false
tcfFin;}
tcfTry "try 1.3 - true" &&{
true
tcfFin;}
tcfFin;}
tcfChk "check 2" &&{
tcfTry "try 2.1 - true" &&{
true
tcfFin;}
tcfTry "try 2.2 - true - ignore" &&{
true
tcfFin -i;}
tcfTry "try 2.3 - true" &&{
true
tcfFin;}
tcfFin;}
tcfChk "check 3" &&{
tcfTry "try 3.1 - true" &&{
true
tcfFin;}
tcfTry "try 3.2 - false - ignore" &&{
false
tcfFin -i;}
tcfTry "try 3.3 - true" &&{
true
tcfFin;}
tcfFin;}
tcfCheckFinal
tcfAssert0 "Overall result" $(tcfRES -p)
LogReport
}
if [[ "$1" == "selfcheck" ]]; then
tcfSelfCheck
fi; # end of tcfSelfCheck }}}
# tcfLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
tcfLibraryLoaded() {
rlImport distribution/Log
declare -F rlDie > /dev/null && {
#rlJournalStart
#rlPhaseStartSetup "TCF"
echo -e "\nrunning inside the beakerlib - using rlAssert0"
true; tcfAssert0() {
local text="$1"
[[ "$3" != "FAIL" && "$3" != "PASS" ]] && text="$text - $3"
__INTERNAL_ConditionalAssert "$text" "$2"
}
__INTERNAL_tcf_do_hack
#rlPhaseEnd
#rlJournalEnd
};
if declare -F rlE2R >& /dev/null; then
__INTERNAL_tcf_kill_old_plugin
fi
true
}; # end of tcfLibraryLoaded }}}
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut

View File

@ -1,60 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/testUser
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/testUser
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Setup/cleanup standard testing user." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RhtsRequires: library(distribution/Log)" >> $(METADATA)
@echo "Provides: library(distribution/testUser)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,234 +0,0 @@
#!/bin/bash
# try-check-final.sh
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = testUser
# library-version = 7
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head1 NAME
BeakerLib library testUser
=head1 DESCRIPTION
This library provide s function for maintaining testing users.
=head1 USAGE
To use this functionality you need to import library distribution/testUser and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/testUser)" >> $(METADATA)
=head1 VARIABLES
=over
=item testUser
Array of testing user login names.
=item testUserPasswd
Array of testing users passwords.
=item testUserUID
Array of testing users UIDs.
=item testUserGID
Array of testing users primary GIDs.
=item testUserGroup
Array of testing users primary group names.
=item testUserGIDs
Array of space separated testing users all GIDs.
=item testUserGroups
Array of space separated testing users all group names.
=item testUserGecos
Array of testing users gecos fields.
=item testUserHomeDir
Array of testing users home directories.
=item testUserShell
Array of testing users default shells.
=back
=head1 FUNCTIONS
=cut
echo -n "loading library testUser... "
: <<'=cut'
=pod
=head3 testUserSetup, testUserCleanup
Creates/removes testing user(s).
rlPhaseStartSetup
testUserSetup [NUM]
rlPhaseEnd
rlPhaseStartCleanup
testUserCleanup
rlPhaseEnd
=over
=item NUM
Optional number of user to be created. If not specified one user is created.
=back
Returns 0 if success.
=cut
testUserSetup() {
# parameter dictates how many users should be created, defaults to 1
local res=0
local count_created=0
local count_wanted=${1:-"1"}
local index=0
(( $count_wanted < 1 )) && return 1
while (( $count_created != $count_wanted ));do
let index++
local newUser="testuser${index}"
local newUserPasswd="redhat"
id "$newUser" &> /dev/null && continue # if user with the name exists, try again
# create
useradd -m $newUser >&2 || ((res++))
echo "$newUserPasswd" | passwd --stdin $newUser || ((res++))
# save the users array
testUser+=($newUser)
testUserPasswd+=($newUserPasswd)
set | grep "^testUser=" > $__INTERNAL_testUser_users_file
set | grep "^testUserPasswd=" >> $__INTERNAL_testUser_users_file
((count_created++))
done
__INTERNAL_testUserRefillInfo || ((res++))
echo ${res}
[[ $res -eq 0 ]]
}
__INTERNAL_testUserRefillInfo() {
local res=0
local user
testUserUID=()
testUserGID=()
testUserGroup=()
testUserGIDs=()
testUserGroups=()
testUserGecos=()
testUserHomeDir=()
testUserShell=()
for user in ${testUser[@]}; do
local ent_passwd=$(getent passwd ${user}) || ((res++))
local users_id="$(id ${user})" || ((res++))
# testUser is filled during user creation - already present
# testUserPasswd is saved same way as testUser - already present
testUserUID+=("$(echo "$ent_passwd" | cut -d ':' -f 3)")
testUserGID+=("$(echo "$ent_passwd" | cut -d ':' -f 4)")
testUserGroup+=("$(echo "$users_id" | sed -r 's/.*gid=(\S+).*/\1/;s/[[:digit:]]+\(//g;s/\)//g;s/,/ /g')")
testUserGIDs+=("$(echo "$users_id" | sed -r 's/.*groups=(\S+).*/\1/;s/\([^\)]+\)//g;s/\)//g;s/,/ /g')")
testUserGroups+=("$(echo "$users_id" | sed -r 's/.*groups=(\S+).*/\1/;s/[[:digit:]]+\(//g;s/\)//g;s/,/ /g')")
testUserGecos+=("$(echo "$ent_passwd" | cut -d ':' -f 5)")
testUserHomeDir+=("$(echo "$ent_passwd" | cut -d ':' -f 6)")
testUserShell+=("$(echo "$ent_passwd" | cut -d ':' -f 7)")
done
echo ${res}
[[ $res -eq 0 ]]
}
testUserCleanup() {
local res=0
for user in ${testUser[@]}; do
userdel -rf "$user" >&2 || ((res++))
done
unset testUser
__INTERNAL_testUserRefillInfo
rm -f $__INTERNAL_testUser_users_file >&2 || ((res++))
echo ${res}
[[ $res -eq 0 ]]
}
# testUserLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
testUserLibraryLoaded() {
local res=0
# necessary init steps
__INTERNAL_testUser_users_file="$BEAKERLIB_DIR/users"
# try to fill in users array with previous data
[[ -f ${__INTERNAL_testUser_users_file} ]] && . ${__INTERNAL_testUser_users_file} >&2
__INTERNAL_testUserRefillInfo >&2 || ((res++))
[[ $res -eq 0 ]]
}; # end of testUserLibraryLoaded }}}
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut
echo "done."

View File

@ -1,163 +0,0 @@
#!/bin/bash
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/sudo/Sanity/run-as
# Description: Test feature 'run as'. This means -u, -g options.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2017 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1151, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include Beaker environment
. /usr/bin/rhts-environment.sh || exit 1
. /usr/share/beakerlib/beakerlib.sh || exit 1
PACKAGE="sudo"
rlJournalStart && {
rlPhaseStartSetup && {
[[ -z "$BEAKERLIB_LIBRARY_PATH" ]] && BEAKERLIB_LIBRARY_PATH="`dirname "$(readlink -f "$0")"`"
rlRun "rlImport --all" 0 "Import libraries" || rlDie "cannot continue"
tcfRun "rlCheckMakefileRequires"
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
CleanupRegister "rlRun 'rm -r $TmpDir' 0 'Removing tmp directory'"
CleanupRegister 'rlRun "popd"'
rlRun "pushd $TmpDir"
CleanupRegister 'tcfRun "testUserCleanup"'
tcfRun "testUserSetup 5"
CleanupRegister 'rlRun "rlFileRestore"'
rlRun "rlFileBackup --clean /etc/sudoers.d"
cat > /etc/sudoers.d/testing << EOF
Defaults !requiretty
$testUser ALL = (ALL:ALL) NOPASSWD: ALL
${testUser[1]} ALL = ( ${testUser[0]} ) NOPASSWD: ALL
${testUser[2]} ALL = ( ${testUser[0]}, ${testUser[1]} ) NOPASSWD: ALL
${testUser[3]} ALL = ( : ${testUserGroup[1]}, ${testUser[0]} ) NOPASSWD: ALL
${testUser[4]} ALL = ( ${testUser[0]} : ${testUserGroup[2]} ) NOPASSWD: ALL
EOF
rlRun "cat /etc/sudoers.d/testing"
rlPhaseEnd; }
CMD='bash -c "ps -o user:15,group:15,ruser:15,rgroup:15,args --ppid $$"'
tcfTry "Tests" --no-assert && {
test() {
local who="$1" as="$2" as_grp="$3" exp_res="$4"
if [[ -z "$exp_res" || "$exp_res" == "0" ]]; then
rlRun -s "su -l $who -c 'sudo ${as:+-u $as} ${as_grp:+-g $as_grp} $CMD'"
[[ -n "$as_grp" && -z "$as" ]] && as="$who"
as="${as:-root}"
as_grp="${as_grp:-$as}"
rlAssertGrep "$as\s+$as_grp\s+$as\s+$as_grp\s+" $rlRun_LOG -Eq
rm -f $rlRun_LOG
else
rlRun -s "su -l $who -c 'sudo ${as:+-u $as} ${as_grp:+-g $as_grp} $CMD'" 1
[[ -n "$as_grp" && -z "$as" ]] && as="$who"
as="${as:-root}"
as_grp="${as_grp:-$as}"
rlAssertNotGrep "$as\s+$as_grp\s+$as\s+$as_grp\s+" $rlRun_LOG -Eq
rm -f $rlRun_LOG
fi
}
rlPhaseStartTest "run as a default user" && {
tcfChk "Test phase" && {
tcfChk "$testUser can run as all" && {
test $testUser "" "" "" 0
tcfFin; }
tcfChk "${testUser[1]} cannot run as anyone" && {
test ${testUser[1]} "" "" 1
tcfFin; }
tcfChk "${testUser[2]} cannot run as anyone" && {
test ${testUser[2]} "" "" 1
tcfFin; }
tcfFin; }
rlPhaseEnd; }
rlPhaseStartTest "run as a user (-u)" && {
tcfChk "Test phase" && {
tcfChk "$testUser can run as all" && {
test $testUser "root" "" 0
test $testUser "${testUser[1]}" "" 0
test $testUser "${testUser[2]}" "" 0
tcfFin; }
tcfChk "${testUser[1]} can run as $testUser" && {
test ${testUser[1]} "root" "" 1
test ${testUser[1]} "${testUser[0]}" "" 0
test ${testUser[1]} "${testUser[2]}" "" 1
tcfFin; }
tcfChk "${testUser[2]} can run as $testUser and ${testUser[1]}" && {
test ${testUser[2]} "root" "" 1
test ${testUser[2]} "${testUser[0]}" "" 0
test ${testUser[2]} "${testUser[1]}" "" 0
tcfFin; }
tcfFin; }
rlPhaseEnd; }
rlPhaseStartTest "run as a group (-g)" && {
tcfChk "Test phase" && {
tcfChk "$testUser can run as all" && {
test $testUser "" "root" 0
test $testUser "" "${testUserGroup[1]}" 0
test $testUser "" "${testUserGroup[2]}" 0
tcfFin; }
tcfChk "${testUser[4]} can run as ${testUserGroup[2]}" && {
test ${testUser[4]} "" "root" 1
test ${testUser[4]} "" "${testUserGroup[0]}" 1
test ${testUser[4]} "" "${testUserGroup[2]}" 0
tcfFin; }
#tcfChk "${testUser[2]} can run as ${testUserGroup[1]}" && {
# test ${testUser[2]} "" "root" 1
# test ${testUser[2]} "" "${testUserGroup[1]}" 1
# test ${testUser[2]} "" "${testUserGroup[2]}" 1
#tcfFin; }
#tcfChk "${testUser[3]}" && {
# test ${testUser[2]} "" "root" 1
# test ${testUser[2]} "" "${testUserGroup[1]}" 0
# test ${testUser[2]} "" "${testUserGroup[2]}" 0
#tcfFin; }
tcfFin; }
rlPhaseEnd; }
rlPhaseStartTest "run as both user (-u) and group (-g)" && {
tcfChk "Test phase" && {
tcfChk "$testUser can run as all" && {
test $testUser "${testUser[1]}" "root" 0
test $testUser "${testUser[2]}" "${testUserGroup[1]}" 0
test $testUser "${testUser[1]}" "${testUserGroup[2]}" 0
tcfFin; }
tcfChk "${testUser[4]} can run as ${testUser[0]} ${testUserGroup[2]}" && {
test ${testUser[4]} "${testUser[0]}" "root" 1
test ${testUser[4]} "${testUser[0]}" "${testUserGroup[0]}" 0
#test ${testUser[4]} "${testUser[0]}" "${testUserGroup[4]}" 0
test ${testUser[4]} "${testUser[4]}" "${testUserGroup[4]}" 0
test ${testUser[4]} "${testUser[0]}" "${testUserGroup[3]}" 1
test ${testUser[4]} "${testUser[0]}" "${testUserGroup[2]}" 0
tcfFin; }
tcfFin; }
rlPhaseEnd; }
tcfFin; }
rlPhaseStartCleanup && {
CleanupDo
tcfCheckFinal
rlPhaseEnd; }
rlJournalPrintText
rlJournalEnd; }

View File

@ -1,67 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/sudo/Sanity/sudoers-options-sanity-test
# Description: This sanity test checks pre-defined (some are commented) options (examples) in sudoers file.
# Author: Ales Marecek <amarecek@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2013 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/sudo/Sanity/sudoers-options-sanity-test
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Ales Marecek <amarecek@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "RhtsRequires: library(distribution/tcf)" >> $(METADATA)
@echo "RhtsRequires: library(distribution/Cleanup)" >> $(METADATA)
@echo "RhtsRequires: library(distribution/ConditionalPhases)" >> $(METADATA)
@echo "RhtsRequires: library(distribution/testUser)" >> $(METADATA)
@echo "Description: This sanity test checks pre-defined (some are commented) options (examples) in sudoers file." >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 30m" >> $(METADATA)
@echo "RunFor: sudo" >> $(METADATA)
@echo "Requires: sudo grep coreutils" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,3 +0,0 @@
PURPOSE of /CoreOS/sudo/Sanity/sudoers-options-sanity-test
Description: This sanity test checks pre-defined (some are commented) options (examples) in sudoers file.
Author: Ales Marecek <amarecek@redhat.com>

View File

@ -1,59 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/Cleanup
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/Cleanup
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Provides function to define cleanup stack which can do its work at any time of the test run." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "Provides: library(distribution/Cleanup)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,314 +0,0 @@
#!/bin/bash
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = Cleanup
# library-version = 9
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_Cleanup_LIB_VERSION=9
: <<'=cut'
=pod
=head1 NAME
BeakerLib library Cleanup
=head1 DESCRIPTION
This file contains functions which provides cleanup stack functionality.
=head1 USAGE
To use this functionality you need to import library distribution/Cleanup and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/Cleanup)" >> $(METADATA)
B<Code example>
rlJournalStart
rlPhaseStartSetup
rlImport 'distribution/Cleanup'
tmp=$(mktemp)
CleanupRegister "
rlLog 'Removing data'
rlRun \"rm -f ${tmp}\"
"
rlLog 'Creating some data'
rlRun "echo 'asdfalkjh' > $tmp"
CleanupRegister "
rlLog 'just something to demonstrate unregistering'
"
ID1=$CleanupRegisterID
CleanupUnregister $ID1
CleanupRegister "
rlLog 'just something to demonstrate partial cleanup'
"
ID2=$CleanupRegisterID
CleanupRegister "rlLog 'cleanup some more things'"
# cleanup everything upto ID2
CleanupDo $ID2
CleanupRegister --mark "
rlLog 'yet another something to demonstrate partial cleanup using internal ID saving'
"
CleanupRegister "rlLog 'cleanup some more things'"
# cleanup everything upto last mark
CleanupDo --mark
rlPhaseEnd
rlPhaseStartCleanup
CleanupDo
rlPhaseEnd
rlJournalPrintText
rlJournalEnd
=head1 FUNCTIONS
=cut
echo -n "loading library Cleanup v$__INTERNAL_Cleanup_LIB_VERSION... "
__INTERNAL_Cleanup_stack_file="$BEAKERLIB_DIR/Cleanup_stack"
touch "$__INTERNAL_Cleanup_stack_file"
chmod ug+rw "$__INTERNAL_Cleanup_stack_file"
# CleanupRegister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# CleanupRegister [--mark] CLEANUP_CODE
# --mark - also mark this position
CleanupRegister() {
local mark=0
[[ "$1" == "--mark" ]] && {
mark=1
shift
}
if ! CleanupGetStack; then
rlLogError "cannot continue, could not get cleanup stack"
return 1
fi
CleanupRegisterID="${RANDOM}$(date +"%s%N")"
echo -n "Registering cleanup ID=$CleanupRegisterID" >&2
if [[ $mark -eq 1 ]]; then
__INTERNAL_CleanupMark=( "$CleanupRegisterID" "${__INTERNAL_CleanupMark[@]}" )
echo -n " with mark" >&2
fi
echo " '$1'" >&2
rlLogDebug "prepending '$1'"
local ID_tag="# ID='$CleanupRegisterID'"
__INTERNAL_Cleanup_stack="$ID_tag
$1
$ID_tag
$__INTERNAL_Cleanup_stack"
if ! CleanupSetStack "$__INTERNAL_Cleanup_stack"; then
rlLogError "an error occured while registering the cleanup '$1'"
return 1
fi
return 0
}; # end of CleanupRegister }}}
# __INTERNAL_Cleanup_get_stack_part ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# 1: ID
# -ID - everything upto the ID
# 2: '' - return ID only
# 'rest' - return exact oposit
__INTERNAL_Cleanup_get_stack_part() {
rlLogDebug "__INTERNAL_Cleanup_get_stack_part(): $* begin"
local ID="$1"
local n='1 0 1'
local stack=''
[[ "${ID:0:1}" == "-" ]] && {
ID="${ID:1}"
n='0 0 1'
}
[[ "$2" == "rest" ]] && {
n="$(echo "${n//0/2}")"
n="$(echo "${n//1/0}")"
n="$(echo "${n//2/1}")"
}
n=($n)
[[ -n "$DEBUG" ]] && rlLogDebug "$(set | grep ^n=)"
local ID_tag="# ID='$ID'"
while IFS= read -r line; do
[[ "$line" == "$ID_tag" ]] && {
n=( "${n[@]:1}" )
continue
}
if [[ $n -eq 0 ]]; then
stack="$stack
$line"
fi
done < <(echo "$__INTERNAL_Cleanup_stack")
rlLogDebug "__INTERNAL_Cleanup_get_stack_part(): cleanup stack part is '${stack:1}'"
echo "${stack:1}"
rlLogDebug "__INTERNAL_Cleanup_get_stack_part(): $* end"
}; # end of __INTERNAL_Cleanup_get_stack_part }}}
# CleanupUnregister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupUnregister() {
local ID="$1"
rlLog "Unregistering cleanup ID='$ID'"
if ! CleanupGetStack; then
rlLogError "cannot continue, could not get cleanup stack"
return 1
fi
rlLogDebug "removing ID='$ID'"
if ! CleanupSetStack "$(__INTERNAL_Cleanup_get_stack_part "$ID" 'rest')"; then
rlLogError "an error occured while registering the cleanup '$1'"
return 1
fi
return 0
}; # end of CleanupUnregister }}}
# CleanupMark ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_CleanupMark=()
CleanupMark() {
echo -n "Setting cleanup mark" >&2
CleanupRegister --mark '' 2>/dev/null
local res=$?
echo " ID='$CleanupRegisterID'" >&2
return $res
}; # end of CleanupMark }}}
# CleanupDo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# 1: '' - cleanup all
# ID - cleanup ID only
# -ID - cleanup all upto ID, including
# mark - cleanup all unto last mark, including
CleanupDo() {
local ID="$1"
if ! CleanupGetStack; then
rlLogError "cannot continue, could not get cleanup stack"
return 1
fi
local res tmp newstack=''
tmp="$(mktemp)"
if [[ "$ID" == "mark" || "$ID" == "--mark" ]]; then
echo "execute cleanup upto mark='$__INTERNAL_CleanupMark'" >&2
__INTERNAL_Cleanup_get_stack_part "-$__INTERNAL_CleanupMark" | grep -v "^# ID='" > "$tmp"
newstack="$(__INTERNAL_Cleanup_get_stack_part "-$__INTERNAL_CleanupMark" 'rest')"
__INTERNAL_CleanupMark=("${__INTERNAL_CleanupMark[@]:1}")
elif [[ -n "$ID" ]]; then
echo "execute cleanup for ID='$ID'" >&2
__INTERNAL_Cleanup_get_stack_part "$ID" | grep -v "^# ID='" > "$tmp"
newstack="$(__INTERNAL_Cleanup_get_stack_part "$ID" 'rest')"
else
CleanupTrapUnhook
trap "echo 'temporarily blocking ctrl+c until cleanup is done' >&2" SIGINT
cat "$__INTERNAL_Cleanup_stack_file" | grep -v "^# ID='" > "$tmp"
echo "execute whole cleanup stack" >&2
fi
. "$tmp"
res=$?
[[ $res -ne 0 ]] && {
echo "cleanup code:" >&2
cat -n "$tmp" >&2
}
rm -f "$tmp"
echo "cleanup execution done" >&2
if [[ -z "$ID" ]]; then
trap - SIGINT
fi
if ! CleanupSetStack "$newstack"; then
rlLogError "an error occured while cleaning the stack"
return 1
fi
return $res
}; # end of CleanupDo }}}
# CleanupGetStack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupGetStack() {
rlLogDebug "getting cleanup stack"
if [[ -r "$__INTERNAL_Cleanup_stack_file" ]]; then
if __INTERNAL_Cleanup_stack="$(cat "$__INTERNAL_Cleanup_stack_file")"; then
rlLogDebug "cleanup stack is '$__INTERNAL_Cleanup_stack'"
return 0
fi
fi
rlLogError "could not load cleanup stack"
return 1
}; # end of CleanupGetStack }}}
# CleanupSetStack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupSetStack() {
rlLogDebug "setting cleanup stack to '$1'"
__INTERNAL_Cleanup_stack="$1"
if echo "$__INTERNAL_Cleanup_stack" > "$__INTERNAL_Cleanup_stack_file"; then
rlLogDebug "cleanup stack is now '$__INTERNAL_Cleanup_stack'"
return 0
fi
rlLogError "could not set cleanup stack"
return 1
}; # end of CleanupSetStack }}}
__INTERNAL_Cleanup_signals=''
__INTERNAL_Cleanup_trap_code='rlJournalStart; rlPhaseStartCleanup; CleanupDo; rlPhaseEnd; rlJournalPrintText; rlJournalEnd; exit'
# CleanupTrapHook ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupTrapHook() {
rlLog "register cleanup trap"
__INTERNAL_Cleanup_signals="${1:-"SIGHUP SIGINT SIGTERM EXIT"}"
eval "trap \"${__INTERNAL_Cleanup_trap_code}\" $__INTERNAL_Cleanup_signals"
}; # end of CleanupTrapHook }}}
# CleanupTrapUnhook ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupTrapUnhook() {
if [[ -n "$__INTERNAL_Cleanup_signals" ]]; then
rlLog "unregister cleanup trap"
eval trap - $__INTERNAL_Cleanup_signals
__INTERNAL_Cleanup_signals=''
fi
}; # end of CleanupTrapUnhook }}}
# CleanupLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
CleanupLibraryLoaded() {
CleanupTrapHook
}; # end of CleanupLibraryLoaded }}}
echo "done."
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut

View File

@ -1,59 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/ConditionalPhases
# Description: Implements conditional phases.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/ConditionalPhases
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Implements conditional phases." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "Provides: library(distribution/ConditionalPhases)" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,166 +0,0 @@
#!/bin/bash
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = ConditionalPhases
# library-version = 2
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_ConditionalPhases_LIB_VERSION=2
__INTERNAL_ConditionalPhases_LIB_NAME='distribution/ConditionalPhases'
: <<'=cut'
=pod
=head1 NAME
BeakerLib library distribution/condpahses
=head1 DESCRIPTION
Implements conditional phases to eficiently select test phases to be execute
using white and black lists.
To use this functionality you need to import library
distribution/ConditionalPhases and add following line to Makefile.
@echo "RhtsRequires: library(distribution/ConditionalPhases)" >> $(METADATA)
=head1 USAGE
=head2 Conditional phases
Each test phase can be conditionally skipped based on a bash regular expression
given in CONDITIONAL_PHASES_BL and/or CONDITIONAL_PHASES_WL variables.
=over
=item CONDITIONAL_PHASES_BL
It is a black list. If match phase name the respective phase should be skipped.
=item CONDITIONAL_PHASES_WL
It is a white list. If does B<not> match phase name the respective phase should
be skipped excluding phases contatning 'setup' or 'cleanup' in its name. Names
'setup' and 'cleanup' are matched case insenitively.
=back
Actual skipping has to be done in the test case itself by using return code of
functions I<rlPhaseStart>, I<rlPhaseStartSetup>, I<rlPhaseStartTest>, and
I<rlPhaseStartCleanup>.
Example:
rlPhaseStartTest "phase name" && {
...
rlPhaseEnd; }
Evaluation of the phase relevancy works as follows:
1. If CONDITIONAL_PHASES_BL is non-empty and matches phase name => return 2.
2. If phase name contains word 'setup' or 'cleanup' or CONDITIONAL_PHASES_WL
is empty => return 0.
3. If CONDITIONAL_PHASES_WL is non-empty and matches phase name => return 0
otherwise return 1.
Normaly Setup and Cleanup phases are not skipped unless hey are B<explicitly>
black-listed.
To make the test work properly with conditional phases it is necessary to
surround phase code with curly brackets and make it conditionally executed
based on rlPhaseStart* function's exit code the same way as it is demostrated in
the example above. To make the process easy you can use following command:
sed 's/rlPhaseStart[^{]*$/& \&\& {/;s/rlPhaseEnd[^}]*$/&; }/'
This code can be embedded in Makefile by modifying build target to following
form:
build: $(BUILT_FILES)
grep -Eq 'rlPhase(Start[^{]*|End[^}]*)$' runtest.sh && sed -i 's/rlPhaseStart[^{]*$/& \&\& {/;s/rlPhaseEnd[^}]*$/&; }/' testrun.sh
test -x runtest.sh || chmod a+x runtest.sh
=cut
#'
echo -n "loading library $__INTERNAL_ConditionalPhases_LIB_NAME v$__INTERNAL_ConditionalPhases_LIB_VERSION... "
# ConditionalPhasesLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
ConditionalPhasesLibraryLoaded() {
if [[ -n "$CONDITIONAL_PHASES_BL" || -n "$CONDITIONAL_PHASES_WL" ]]; then
__INTERNAL_ConditionalPhases_eval() {
# check phases black-list
[[ -n "$CONDITIONAL_PHASES_BL" && "$1" =~ $CONDITIONAL_PHASES_BL ]] && {
rlLogWarning "phase '$1' should be skipped as it is defined in \$CONDITIONAL_PHASES_BL='$CONDITIONAL_PHASES_BL'"
return 2
}
# always execute Setup, Cleanup and if no PHASES (white-list) specified
[[ "$1" =~ $(echo "\<[Ss][Ee][Tt][Uu][Pp]\>") || "$1" =~ $(echo "\<[Cc][Ll][Ee][Aa][Nn][Uu][Pp]\>") ]] && {
rlLogInfo "phase '$1' will be executed as 'setup' and 'cleanup' phases are allowed by default, these can be black-listed"
return 0
}
[[ -z "$CONDITIONAL_PHASES_WL" ]] && {
rlLogInfo "phase '$1' will be executed as there is no rule for it"
return 0
}
[[ "$1" =~ $CONDITIONAL_PHASES_WL ]] && {
rlLogInfo "phase '$1' will be executed as it is defined in \$CONDITIONAL_PHASES_WL='$CONDITIONAL_PHASES_WL'"
return 0
} || {
rlLogWarning "phase '$1' should be skipped as it is not defined in \$CONDITIONAL_PHASES_WL='$CONDITIONAL_PHASES_WL'"
return 1
}
}
rlLogInfo "replacing rlPhaseStart by modified function with conditional phases implemented"
:; rlPhaseStart() {
if [ "x$1" = "xFAIL" -o "x$1" = "xWARN" ] ; then
__INTERNAL_ConditionalPhases_eval "$2" && \
rljAddPhase "$1" "$2"
return $?
else
rlLogError "rlPhaseStart: Unknown phase type: $1"
return 1
fi
}
else
rlLogInfo "Neither CONDITIONAL_PHASES_WL nor CONDITIONAL_PHASES_BL is defined, not applying modifications"
fi
}; # end of ConditionalPhasesLibraryLoaded }}}
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut
echo 'done.'

View File

@ -1,48 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/Log
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/Log
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Provides yet another logging facility that does not rely on beakerlib while it can integrate with it." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RhtsRequires: library(distribution/opts)" >> $(METADATA)
@echo "Provides: library(distribution/Log)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,637 +0,0 @@
#!/bin/bash
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2013 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = Log
# library-version = 11
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_Log_LIB_VERSION=11
: <<'=cut'
=pod
=head1 NAME
BeakerLib library Log
=head1 DESCRIPTION
This library provide logging capability which does not rely on beakerlib so it
can be used standalone.
If it is used within beakerlib it automatically bypass all messages to the
beakerlib.
Also this library provide journaling feature so the summary can be printed out
at the end.
=head1 USAGE
To use this functionality you need to import library distribution/Log and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/Log)" >> $(METADATA)
=head1 FUNCTIONS
=cut
echo -n "loading library Log v$__INTERNAL_Log_LIB_VERSION... "
__INTERNAL_Log_prefix=''
__INTERNAL_Log_prefix2=''
__INTERNAL_Log_postfix=''
__INTERNAL_Log_default_level=3
__INTERNAL_Log_level=$__INTERNAL_Log_default_level
LogSetDebugLevel() {
if [[ -n "$1" ]]; then
if [[ "$1" =~ ^[0-9]+$ ]]; then
let __INTERNAL_Log_level=$__INTERNAL_Log_default_level+$1;
else
__INTERNAL_Log_level=255
fi
else
__INTERNAL_Log_level=$__INTERNAL_Log_default_level
fi
}
LogSetDebugLevel "$DEBUG"
let __INTERNAL_Log_level_LOG=0
let __INTERNAL_Log_level_FATAL=0
let __INTERNAL_Log_level_ERROR=1
let __INTERNAL_Log_level_WARNING=2
let __INTERNAL_Log_level_INFO=3
let __INTERNAL_Log_level_DEBUG=4
let __INTERNAL_Log_level_MORE=5
let __INTERNAL_Log_level_MORE_=$__INTERNAL_Log_level_MORE+1
let __INTERNAL_Log_level_MORE__=$__INTERNAL_Log_level_MORE_+1
let __INTERNAL_Log_level_MORE___=$__INTERNAL_Log_level_MORE__+1
# Log ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
Log() {
LogMore___ -f "begin '$*'"
local pri=$2 message="${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
if [[ -n "$pri" ]]; then
LogPrintMessage "$pri" "$message"
LogjAddMessage "$pri" "$message"
else
LogPrintMessage "$(date +%H:%M:%S)" "$message"
LogjAddMessage "INFO" "$message"
fi
LogMore___ -f "end"
return 0
}; # end of Log }}}
__INTERNAL_Log_condition() {
cat <<EOF
__INTERNAL_Log_level_do=$1
if [[ \$__INTERNAL_Log_level -ge \$__INTERNAL_Log_level_do ]]; then
[[ -z "$2" ]] && return 1
else
return 0
fi
EOF
}
# LogInfo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogInfo() {
__INTERNAL_LogPrio='INFO'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_INFO \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='INFO'
Log "$1" $__INTERNAL_LogPrio
LogMore___ -f "end"
return 0
}; # end of LogInfo }}}
# LogWarn ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogWarn() {
__INTERNAL_LogPrio='WARNING'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_WARNING \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='WARNING'
Log "$1" $__INTERNAL_LogPrio
LogMore___ -f "end"
return 0
}; # end of LogWarn }}}
# LogWarning ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogWarning() {
__INTERNAL_LogPrio='WARNING'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_WARNING \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='WARNING'
Log "$1" $__INTERNAL_LogPrio
LogMore___ -f "end"
return 0
}; # end of LogWarning }}}
# LogError ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogError() {
__INTERNAL_LogPrio='ERROR'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_ERROR \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='ERROR'
Log "$1" $__INTERNAL_LogPrio
LogMore___ -f "end"
return 0
}; # end of LogError }}}
# LogFatal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogFatal() {
__INTERNAL_LogPrio='FATAL'
eval "$(__INTERNAL_Log_condition \$__INTERNAL_Log_level_FATAL \"\$1\")"
LogMore___ -f "begin '$*'"
__INTERNAL_LogPrio='FATAL'
Log "$1" $__INTERNAL_LogPrio
exit 255
LogMore___ -f "end"
}; # end of LogFatal }}}
# LogPASS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogPASS() {
LogMore___ -f "begin '$*'"
Log "$1" PASS
LogMore___ -f "end"
return 0
}
LogPass() {
LogPASS "$@"
}; # end of LogPASS }}}
# LogFAIL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogFAIL() {
LogMore___ -f "begin '$*'"
Log "$1" FAIL
LogMore___ -f "end"
return 0
}
LogFail() {
LogFAIL "$@"
}; # end of LogFAIL }}}
# LogDo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogDo() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
local tmp=${BASH_REMATCH[1]:-1}
pref="${FUNCNAME[$tmp]}(): "
}
LogPrintMessage "$__INTERNAL_LogPrio" "${__INTERNAL_Log_prefix}${pref}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
return 0
}; # end of LogDo }}}
# LogDebug ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogDebug() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
__INTERNAL_Log_level_do=${2:-$__INTERNAL_Log_level_DEBUG}
__INTERNAL_LogPrio='DEBUG'
[[ $__INTERNAL_Log_level_do -ge $__INTERNAL_Log_level_MORE ]] && __INTERNAL_LogPrio="${__INTERNAL_LogPrio}:$(($__INTERNAL_Log_level_do-$__INTERNAL_Log_level_DEBUG+1))"
eval "$(__INTERNAL_Log_condition \${2:-\$__INTERNAL_Log_level_DEBUG} \"\$1\")"
LogDo $pref "$1"
return 0
}; # end of LogDebug }}}
# LogMore ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogMore() {
# log if DEBUG does not containg a number
# or the number is greater or equal to 2
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" ${2:-$__INTERNAL_Log_level_MORE}
}; # end of LogMore }}}
# LogMore_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogMore_() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE_
}; # end of LogMore_ }}}
# LogMore__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogMore__() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE__
}; # end of LogMore__ }}}
# LogMore___ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogMore___() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE___
}; # end of LogMore___ }}}
# LogMoreLow ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogMoreLow_Obs=''
LogMoreLow() {
[[ -z "$__INTERNAL_LogMoreLow_Obs" ]] && {
LogMore_ -f "LogMoreLow is obsoleted by LogMore_"
__INTERNAL_LogMoreLow_Obs=1
}
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE_
}; # end of LogMoreLow }}}
# LogMoreMed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogMoreMed_Obs=''
LogMoreMed() {
[[ -z "$__INTERNAL_LogMoreMed_Obs" ]] && {
LogMore__ -f "LogMoreMed is obsoleted by LogMore__"
__INTERNAL_LogMoreMed_Obs=1
}
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE__
}; # end of LogMoreMed }}}
# LogMoreHigh ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogMoreHigh_Obs=''
LogMoreHigh() {
[[ -z "$__INTERNAL_LogMoreHigh_Obs" ]] && {
LogMore___ -f "LogMoreHigh is obsoleted by LogMore___"
__INTERNAL_LogMoreHigh_Obs=1
}
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogDebug $pref "$1" $__INTERNAL_Log_level_MORE___
}; # end of LogMoreHigh }}}
# LogjAddMessage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogjAddMessage() {
LogMore__ -f "begin '$*'"
__INTERNAL_Log_journal=("${__INTERNAL_Log_journal[@]}" "$1" "$2")
LogMore__ -f "end"
true;
}; # end of LogjAddMessage }}}
# __INTERNAL_LogCenterText ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogCenterText() {
local spaces=' '
# strip colors
local log_pri_strip=$(echo -en "$1" | sed -r "s:\x1B\[[0-9;]*[mK]::g")
local log_pri_strip_count=${#log_pri_strip}
local left_spaces=$(( ($2 - $log_pri_strip_count) / 2 ))
local right_spaces=$(( $2 - $log_pri_strip_count - $left_spaces ))
echo -en "${spaces:0:$left_spaces}${1}${spaces:0:$right_spaces}"
}; # end of __INTERNAL_LogCenterText }}}
# LogPrintMessage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogPrintMessage() {
echo -e ":: [$(__INTERNAL_LogCenterText "$1" 10)] :: $2" >&2
return 0
}; # end of LogPrintMessage }}}
# LogReport ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 LogReport
Prints final report similar to breakerlib's rlJournalPrintText. This is useful
mainly if you use TCF without beakerlib.
LogReport
=cut
#'
LogReport() {
echo -e "\n ====== Summary report begin ======"
local a p l i
for i in $(seq 0 2 $((${#__INTERNAL_Log_journal[@]}-1)) ); do
LogPrintMessage "${__INTERNAL_Log_journal[$i]}" "${__INTERNAL_Log_journal[$((++i))]}"
done
echo " ======= Summary report end ======="
__INTERNAL_Log_journal=()
}; # end of LogReport }}}
# LogFile ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogFile() {
LogMore__ -f "begin '$*'"
local prio=''
[[ $# -ge 3 ]] && {
optsBegin
optsAdd 'prio|tag|p|t' --mandatory
optsDone; eval "${optsCode}"
}
cat $1 | while IFS= read line; do
Log "$line" "${prio:-$2}"
done
LogMore__ -f "end"
}; #}}}
# LogText ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogText() {
LogMore__ -f "begin '$*'"
local prio=''
[[ $# -ge 3 ]] && {
optsBegin
optsAdd 'prio|tag|p|t' --mandatory
optsDone; eval "${optsCode}"
}
{
if [[ "$1" == "-" ]]; then
cat -
else
echo "$1"
fi
} | while IFS= read line; do
Log "$line" "${prio:-$2}"
done
LogMore__ -f "end"
}; #}}}
# LogStrippedDiff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogStrippedDiff() {
LogMore__ -f "begin '$*'"
local prio=''
[[ $# -ge 3 ]] && {
optsBegin
optsAdd 'prio|tag|p|t' --mandatory
optsDone; eval "${optsCode}"
}
{
if [[ -n "$2" ]]; then
diff -U0 "$1" "$2"
else
cat $1
fi
} | grep -v -e '^@@ ' -e '^--- ' -e '^+++ ' | while IFS= read line; do
Log "$line" "$prio"
done
LogMore__ -f "end"
}; #}}}
# LogRun ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogRun() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}+1))"
}
LogMore
local dolog=$?
[[ $dolog -eq 0 ]] || {
local param params blacklist="[[:space:]]|>|<|\|"
[[ "${#@}" -eq 1 ]] && params="$1" || {
for param in "$@"; do
if [[ "$param" =~ $blacklist ]]; then
params="$params \"${param//\"/\\\"}\""
else
params="$params $param"
fi
done
params="${params:1}"
}
LogDo $pref "executing >>>>> ${params} <<<<<"
}
eval "$@"
ret=$?
[[ $dolog -eq 0 ]] || LogMore $pref "execution >>>>> ${params} <<<<< returned '$ret'"
return $ret
}; # end of LogRun }}}
# LogDebugNext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogDebugNext() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}))"
}
LogDebug '' ${1:-$__INTERNAL_Log_level_DEBUG} || {
__INTERNAL_Log_DEBUGING=0
trap "
__INTERNAL_Log_DEBUGING_res=\$?
let __INTERNAL_Log_DEBUGING++
if [[ \$__INTERNAL_Log_DEBUGING -eq 1 ]]; then
__INTERNAL_Log_DEBUGING_cmd=\"\$BASH_COMMAND\"
LogDebug $pref \"executing >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<<\" ${1:-$__INTERNAL_Log_level_DEBUG}
else
trap - DEBUG
LogDebug $pref \"execution >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<< returned \$__INTERNAL_Log_DEBUGING_res\" ${1:-$__INTERNAL_Log_level_DEBUG}
fi" DEBUG
}
}; # end of LogDebugNext }}}
# LogMoreNext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogMoreNext() {
LogMore || {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}))"
}
LogDebugNext $pref ${1:-$__INTERNAL_Log_level_MORE}
}
}; # end of LogMoreNext }}}
LogNext() {
LogMoreNext "$@"
}
# LogDebugOn ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogDebugOn() {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}))"
}
LogDebug '' ${1:-$__INTERNAL_Log_level_DEBUG} || {
trap "
__INTERNAL_Log_DEBUGING_res=\$?
let __INTERNAL_Log_DEBUGING++
if [[ -z \"\$__INTERNAL_Log_DEBUGING_cmd\" ]]; then
__INTERNAL_Log_DEBUGING_cmd=\"\$BASH_COMMAND\"
LogDebug $pref \"executing >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<<\" ${1:-$__INTERNAL_Log_level_DEBUG}
else
LogDebug $pref \"execution >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<< returned \$__INTERNAL_Log_DEBUGING_res\" ${1:-$__INTERNAL_Log_level_DEBUG}
__INTERNAL_Log_DEBUGING_cmd=\"\$BASH_COMMAND\"
if [[ \"\$__INTERNAL_Log_DEBUGING_cmd\" =~ LogDebugOff ]]; then
trap - DEBUG
else
LogDebug $pref \"executing >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<<\" ${1:-$__INTERNAL_Log_level_DEBUG}
fi
fi" DEBUG
}
}; # end of LogDebugOn }}}
# LogMoreOn ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogMoreOn() {
LogMore || {
local pref=''
[[ "$1" =~ ^-f([0-9]*) ]] && {
shift
pref="-f$((${BASH_REMATCH[1]:-1}))"
}
LogDebugOn $pref ${1:-$__INTERNAL_Log_level_MORE}
}
}; # end of LogMoreOn }}}
# LogDebugOff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
# log info about execution to Debug level
LogDebugOff() {
__INTERNAL_Log_DEBUGING_cmd=''
}; # end of LogDebugOff }}}
# LogVar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogVar() {
[[ -n "$DEBUG" ]] && {
echo -n 'eval '
while [[ -n "$1" ]]; do
echo -n "LogDebug -f \"\$(set | grep -P '^$1=')\";"
shift
done
}
}; # end of LogVar }}}
# __INTERNAL_LogRedirectToBeakerlib ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_LogRedirectToBeakerlib() {
echo -e "\nrunning inside the beakerlib - redirect own logging functions to beakerlib ones"
true; LogjAddMessage() {
LogMore___ -f "begin $*"
rljAddMessage "$2" "$1"
LogMore___ -f "end $*"
}
true; Log() {
LogMore___ -f "begin $*"
case ${2} in
INFO)
LogjAddMessage "INFO" "$1"
LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
;;
BEGIN)
LogjAddMessage "INFO" "$*:"
LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
;;
WARNING|WARN|ERROR|FATAL)
LogjAddMessage "WARNING" "$1"
LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
;;
SKIP|SKIPPING)
LogjAddMessage "WARNING" "$*:"
LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}"
;;
FAIL)
rlFail "$*"
return $?
;;
PASS)
rlPass "$*"
return $?
;;
*)
rlLog "$*"
;;
esac
LogMore___ -f "end $*"
return 0;
}
}
# end of __INTERNAL_LogRedirectToBeakerlib }}}
# LogLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
LogLibraryLoaded() {
declare -F rlDie > /dev/null && __INTERNAL_LogRedirectToBeakerlib
return 0
}; # end of LogLibraryLoaded }}}
echo "done."
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut

View File

@ -1,48 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/opts
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/opts
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Provides simple way for defining script's or function's options including help" >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RhtsRequires: library(distribution/Log)" >> $(METADATA)
@echo "Provides: library(distribution/opts)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,338 +0,0 @@
#!/bin/bash
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2013 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = opts
# library-version = 4
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_opts_LIB_VERSION=4
: <<'=cut'
=pod
=head1 NAME
BeakerLib library opts
=head1 DESCRIPTION
This library provides simple way for defining script's or function's option
agruments including help.
=head1 USAGE
To use this functionality you need to import library distribution/opts and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/opts)" >> $(METADATA)
B<Code example>
testfunction() {
optsBegin -h "Usage: $0 [options]
options:
"
optsAdd 'flag1' --flag
optsAdd 'optional1|o' --optional
optsAdd 'Optional2|O' "echo opt \$1" --optional --long --var-name opt
optsAdd 'mandatory1|m' "echo man \$1" --mandatory
optsDone; eval "${optsCode}"
echo "$optional1"
echo "$opt"
echo "$mandatory1"
}
=head1 FUNCTIONS
=cut
echo -n "loading library opts v$__INTERNAL_opts_LIB_VERSION... "
# optsAdd ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsAdd() {
LogMoreMed -f "begin '$*'"
local GETOPT=$(getopt -q -o fomv:d:lh:l -l flag,opt,optional,mandatory,varname:,default:,local,help:,long -- "$@")
eval set -- "$GETOPT"
local type='f' var_name var_name_set default help long
while [[ -n "$@" ]]; do
case $1 in
--)
shift; break
;;
-h|--help)
shift
help="$1"
;;
-l|--long)
long=1
;;
-d|--default)
shift
default="$1"
;;
-v|--varname|--var-name)
shift
var_name="$1"
var_name_set=1
;;
-f|--flag)
type='f'
;;
-o|--opt|--optional)
type='o'
;;
-m|--mandatory)
type='m'
;;
*)
echo "unknown option '$1'"
return 1
;;
esac
shift;
done
[ -z "$var_name" ] && {
var_name=$(echo -n "$1" | cut -d '|' -f 1 | sed -e 's/-//g;s/^[0-9]/_\0/')
LogMoreHigh -f "constructing variable name '$var_name'"
}
local opts='' opts_help='' optsi=''
for optsi in $(echo -n "$1" | tr '|' ' '); do
if [[ ${#optsi} -ge 2 || $long -eq 1 ]]; then
opts="$opts|--$optsi"
opts_help="$opts_help|--$optsi[=ARG]"
__INTERNAL_opts_long="${__INTERNAL_opts_long},${optsi}"
LogMoreHigh -f "adding long option '$optsi'"
case $type in
m)
__INTERNAL_opts_long="${__INTERNAL_opts_long}:"
;;
o)
__INTERNAL_opts_long="${__INTERNAL_opts_long}::"
;;
esac
else
opts="$opts|-$optsi"
opts_help="$opts_help|-${optsi}[ARG]"
__INTERNAL_opts_short="${__INTERNAL_opts_short}${optsi}"
LogMoreHigh -f "adding short option '$optsi'"
case $type in
m)
__INTERNAL_opts_short="${__INTERNAL_opts_short}:"
;;
o)
__INTERNAL_opts_short="${__INTERNAL_opts_short}::"
;;
esac
fi
done
optsCode="${optsCode}
${opts:1})
optsPresent=\"\${optsPresent}$var_name \""
LogMoreHigh -f "adding code for processing option '${opts:1}'"
__INTERNAL_opts_init_var="$__INTERNAL_opts_init_var
${__INTERNAL_opts_local}$var_name=()"
__INTERNAL_opts_default="$__INTERNAL_opts_default
[[ \"\$optsPresent\" =~ \$(echo \"\<${var_name}\>\") ]] || ${__INTERNAL_opts_local}$var_name='$default'"
case $type in
f)
[[ -z "$2" || -n "$var_name_set" ]] && {
local val=1
[[ -n "$default" ]] && val=''
optsCode="$optsCode
$var_name+=( '$val' )"
}
__INTERNAL_opts_help="${__INTERNAL_opts_help}
${opts:1}"
;;
o|m)
optsCode="$optsCode
shift"
[[ -z "$2" || -n "$var_name_set" ]] && optsCode="$optsCode
$var_name+=( \"\$1\" )"
if [[ "$type" == "o" ]]; then
__INTERNAL_opts_help="${__INTERNAL_opts_help}
${opts_help:1}"
else
__INTERNAL_opts_help="${__INTERNAL_opts_help}
${opts:1} ARG"
fi
;;
esac
[[ -n "$2" ]] && {
optsCode="$optsCode
$2"
}
optsCode="$optsCode
;;"
__INTERNAL_opts_help="${__INTERNAL_opts_help}${help:+
$help
}"
LogMoreMed -f "end"
}; # end of optsAdd }}}
# optsBegin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsBegin() {
LogMoreMed -f "begin '$*'"
optsCode=''
optsPresent=' '
__INTERNAL_opts_short='.'
__INTERNAL_opts_long='help'
__INTERNAL_opts_help=''
__INTERNAL_opts_local=''
__INTERNAL_opts_default=''
__INTERNAL_opts_init_var=''
[[ "${FUNCNAME[1]}" != "main" ]] && __INTERNAL_opts_local='local '
while [[ -n "$1" ]]; do
case $1 in
--)
shift; break
;;
-h|--help)
shift
__INTERNAL_opts_help="$1"
;;
*)
echo "unknown option '$1'"
return 1
;;
esac
shift;
done
LogMoreMed -f "end"
}; # end of optsBegin }}}
# optsDone ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsDone() {
LogMoreMed -f "begin '$*'"
optsCode="${__INTERNAL_opts_local}GETOPT=\$(getopt -o ${__INTERNAL_opts_short} -l ${__INTERNAL_opts_long} -- \"\$@\")
[[ \$? -ne 0 ]] && {
echo 'Exiting'
return 1 >& /dev/null
exit 1
}
eval set -- \"\$GETOPT\"
${__INTERNAL_opts_init_var:1}
while [[ -n \"\$1\" ]]; do
case \$1 in
--)
shift; break
;;
${optsCode}
--help)
echo \"\$__INTERNAL_opts_help\"
return >& /dev/null
exit
;;
*)
echo \"unknown option '\$1'\"
return 1 >& /dev/null
exit 1
;;
esac
shift
done
${__INTERNAL_opts_default:1}
unset optsCode __INTERNAL_opts_help __INTERNAL_opts_short __INTERNAL_opts_long __INTERNAL_opts_default __INTERNAL_opts_init_var __INTERNAL_opts_local
"
if ! echo "$optsCode" | grep -q -- '--help$'; then
__INTERNAL_opts_help="$__INTERNAL_opts_help
--help
Show this help."
fi
LogMoreHigh -f "optsCode:\n$optsCode"
LogMoreMed -f "end"
}; # end of optsDone }}}
# optsSelfCheck ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsSelfCheck() {
optsBegin -h "Usage: $0 [options]
options:
"
# optsAdd 'help' -f 'echo help'
optsAdd 'flag' -f 'echo f'
optsAdd 'optional|o' -o "echo opt \$1"
optsAdd 'Optional|O' -o "echo opt \$1" --long
optsAdd 'mandatory|m' -m "echo man \$1"
optsDone
echo "${optsCode}"
echo ...
eval "${optsCode}"
echo ...
fce() {
optsBegin -h "Usage: $0 [options]
options:
"
# optsAdd 'help' -f 'echo help'
optsAdd 'flag' -f
optsAdd 'optional|o' -o "echo opt \$1"
optsAdd 'Optional|O' -o "echo opt \$1" --long
optsAdd 'mandatory|m' -m "echo man \$1"
optsDone
echo "${optsCode}"
echo ...
eval "${optsCode}"
echo ...
}
echo -e 'test for opts in function\n========================='
fce --help
}; # end of optsSelfCheck }}}
# optsLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
optsLibraryLoaded() {
return 0
}; # end of LogLibraryLoaded }}}
echo "done."
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut

View File

@ -1,60 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/tcf
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/tcf
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Block style coding with ability of skipping parts." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RhtsRequires: library(distribution/Log)" >> $(METADATA)
@echo "Provides: library(distribution/tcf)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,903 +0,0 @@
#!/bin/bash
# try-check-final.sh
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = tcf
# library-version = 14
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__INTERNAL_tcf_LIB_VERSION=14
: <<'=cut'
=pod
=head1 NAME
BeakerLib library Try-Check-Final
=head1 DESCRIPTION
This file contains functions which gives user the ability to define blocks of
code where some of the blocks can be automatically skipped if some of preceeding
blocks failed.
ATTENTION
This plugin modifies some beakerlib functions! If you suspect that it breakes
some functionality set the environment variable TCF_NOHACK to nonempty value.
=head1 USAGE
To use this functionality you need to import library distribution/tcf and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/tcf)" >> $(METADATA)
=head1 FUNCTIONS
=cut
echo -n "loading library try-check-final v$__INTERNAL_tcf_LIB_VERSION... "
let __INTERNAL_tcf_DEBUG_LEVEL_LOW=3
let __INTERNAL_tcf_DEBUG_LEVEL_MED=$__INTERNAL_tcf_DEBUG_LEVEL_LOW+1
let __INTERNAL_tcf_DEBUG_LEVEL_HIGH=$__INTERNAL_tcf_DEBUG_LEVEL_LOW+2
# global variables {{{
__INTERNAL_tcf_result=0
__INTERNAL_tcf_result_file="${BEAKERLIB_DIR:-"/var/tmp"}/tcf.result"
echo -n "$__INTERNAL_tcf_result" > "$__INTERNAL_tcf_result_file"
__INTERNAL_tcf_current_level_data=()
__INTERNAL_tcf_current_level_val=0
__INTERNAL_tcf_journal=()
#}}}
# __INTERNAL_tcf_colorize ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_colorize() {
local a
case $1 in
PASS)
a="${__INTERNAL_tcf_color_green}${1}${__INTERNAL_tcf_color_reset}"
;;
FAIL)
a="${__INTERNAL_tcf_color_red}${1}${__INTERNAL_tcf_color_reset}"
;;
SKIPPING|WARNING)
a="${__INTERNAL_tcf_color_yellow}${1}${__INTERNAL_tcf_color_reset}"
;;
BEGIN|INFO)
a="${__INTERNAL_tcf_color_blue}${1}${__INTERNAL_tcf_color_reset}"
;;
*)
a=$1
esac
echo -n "$a"
}; # end of __INTERNAL_tcf_colorize }}}
# __INTERNAL_tcf_colors_setup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_colors_setup(){
T="$TERM"
[[ -t 1 ]] || T=""
[[ -t 2 ]] || T=""
[[ "$1" == "--force" ]] && T="xterm"
case $T in
xterm|screen)
__INTERNAL_tcf_color_black="\e[0;30m"
__INTERNAL_tcf_color_dark_gray="\e[1;30m"
__INTERNAL_tcf_color_blue="\e[0;34m"
__INTERNAL_tcf_color_light_blue="\e[1;34m"
__INTERNAL_tcf_color_green="\e[0;32m"
__INTERNAL_tcf_color_light_green="\e[1;32m"
__INTERNAL_tcf_color_cyan="\e[0;36m"
__INTERNAL_tcf_color_light_cyan="\e[1;36m"
__INTERNAL_tcf_color_red="\e[0;31m"
__INTERNAL_tcf_color_light_red="\e[1;31m"
__INTERNAL_tcf_color_purple="\e[0;35m"
__INTERNAL_tcf_color_light_purple="\e[1;35m"
__INTERNAL_tcf_color_brown="\e[0;33m"
__INTERNAL_tcf_color_yellow="\e[1;33m"
__INTERNAL_tcf_color_light_gray="\e[0;37m"
__INTERNAL_tcf_color_white="\e[1;37m"
__INTERNAL_tcf_color_reset="\e[00m"
;;
* )
__INTERNAL_tcf_color_black=""
__INTERNAL_tcf_color_dark_gray=""
__INTERNAL_tcf_color_blue=""
__INTERNAL_tcf_color_light_blue=""
__INTERNAL_tcf_color_green=""
__INTERNAL_tcf_color_light_green=""
__INTERNAL_tcf_color_cyan=""
__INTERNAL_tcf_color_light_cyan=""
__INTERNAL_tcf_color_red=""
__INTERNAL_tcf_color_light_red=""
__INTERNAL_tcf_color_purple=""
__INTERNAL_tcf_color_light_purple=""
__INTERNAL_tcf_color_brown=""
__INTERNAL_tcf_color_yellow=""
__INTERNAL_tcf_color_light_gray=""
__INTERNAL_tcf_color_white=""
__INTERNAL_tcf_color_reset=""
;;
esac
}; # end of __INTERNAL_tcf_colors_setup
__INTERNAL_tcf_colors_setup; # }}}
# __INTERNAL_tcf_copy_function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_copy_function() {
declare -F $1 > /dev/null || return 1
eval "$(echo -n "${2}() "; declare -f ${1} | tail -n +2)"
}; # end of __INTERNAL_tcf_copy_function }}}
# __INTERNAL_tcf_addE2R ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_addE2R() {
__INTERNAL_tcf_copy_function $1 TCF_orig_$1
eval "${1}() { TCF_orig_${1} \"\$@\"; tcfE2R; }"
}; # end of __INTERNAL_tcf_addE2R }}}
# __INTERNAL_tcf_insertE2R ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_insertE2R() {
__INTERNAL_tcf_copy_function $1 TCF_orig_$1
eval "$(echo -n "${1}() "; declare -f ${1} | tail -n +2 | sed -e 's/\(.*__INTERNAL_ConditionalAssert.*\)/\1\ntcfE2R;/')"
}; # end of __INTERNAL_tcf_insertE2R }}}
# __INTERNAL_tcf_get_current_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_get_current_level() {
local l=$__INTERNAL_tcf_current_level_val
if [[ $1 ]]; then
l=$(($l+$1))
fi
local i
for i in $(seq 1 $(($l*2)) ); do echo -n " "; done
return $l
}; # end of __INTERNAL_tcf_get_current_level }}}
# __INTERNAL_tcf_incr_current_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_incr_current_level() {
let __INTERNAL_tcf_current_level_val++
__INTERNAL_Log_prefix=$(__INTERNAL_tcf_get_current_level)
}; # end of __INTERNAL_tcf_incr_current_level }}}
# __INTERNAL_tcf_decr_current_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_decr_current_level() {
let __INTERNAL_tcf_current_level_val--
__INTERNAL_Log_prefix=$(__INTERNAL_tcf_get_current_level)
}; # end of __INTERNAL_tcf_decr_current_level }}}
# __INTERNAL_tcf_do_hack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_do_hack() {
LogDebug "TCF_NOHACK='$TCF_NOHACK'"
if [[ -z "$TCF_NOHACK" ]]; then
tcfChk "Apply TCF beakerlib hacks" && {
rlLog " injecting tcf hacks into the beakerlib functions"
echo -n "patching rlLog"
local rlL=$(declare -f rlLog | sed -e 's|\] ::|\0${__INTERNAL_Log_prefix}|;s|$3 $1"|${3:+"$3 "}$1"|')
eval "$rlL"
echo -n ", rljAddTest"
__INTERNAL_tcf_copy_function rljAddTest __INTERNAL_tcf_orig_rljAddTest
true; rljAddTest() {
local a="${__INTERNAL_Log_prefix}$1"; shift
[[ "$1" != "FAIL" ]]; tcfE2R
__INTERNAL_tcf_journal=("${__INTERNAL_tcf_journal[@]}" "$1" "$a")
__INTERNAL_tcf_orig_rljAddTest "$a" "$@"
}
echo -n ", rljAddMessage"
__INTERNAL_tcf_copy_function rljAddMessage __INTERNAL_tcf_orig_rljAddMessage
true; rljAddMessage() {
local a="${__INTERNAL_Log_prefix}$1"; shift
__INTERNAL_tcf_journal=("${__INTERNAL_tcf_journal[@]}" "$1" "$a")
__INTERNAL_tcf_orig_rljAddMessage "$a" "$@"
}
echo -n ", __INTERNAL_LogAndJournalFail"
__INTERNAL_tcf_copy_function __INTERNAL_LogAndJournalFail __INTERNAL_tcf_orig___INTERNAL_LogAndJournalFail
true; __INTERNAL_LogAndJournalFail() {
tcfNOK
__INTERNAL_tcf_orig___INTERNAL_LogAndJournalFail "$@"
}
echo "."
tcfFin --no-assert --ignore; }
else
Log "skip hacking beakerlib functions"
fi
}; # end of __INTERNAL_tcf_do_hack }}}
# __INTERNAL_tcf_kill_old_plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_kill_old_plugin() {
tcfChk "Get rid of the old TCF implementation. removing" && {
local comma='' i
for i in Try Chk Fin E2R RES OK NOK NEG TCFcheckFinal TCFreport; do
echo -n "${comma}rl$i"
unset -f rl$i
comma=', '
done
echo '.'
tcfFin --no-assert; }
}; # end of __INTERNAL_tcf_kill_old_plugin }}}
: <<'=cut'
=pod
=head2 Block functions
=cut
# __INTERNAL_tcf_parse_params ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
__INTERNAL_tcf_parse_params() {
local GETOPT=$(getopt -q -o if: -l ignore,no-assert,fail-tag: -- "$@")
eval set -- "$GETOPT"
echo "local ignore noass title fail_tag"
echo "[ -z \"\$ignore\" ] && ignore=0"
echo "[ -z \"\$noass\" ] && noass=0"
echo "[ -z \"\$fail_tag\" ] && fail_tag='FAIL'"
while [[ -n "$@" ]]; do
case $1 in
--)
shift; break
;;
--ignore|-i)
echo "ignore=1"
echo "noass=1"
;;
--no-assert|-n)
echo "noass=1"
;;
--fail-tag|-f)
shift
echo "fail_tag='$1'"
;;
*)
echo "unknown option $1"
return 1
;;
esac
shift;
done
[[ -n "$1" ]] && echo "title=\"${1}\""
echo "eval set -- \"$(echo "$GETOPT" | sed -e 's/.*-- //')\""
}; # end of __INTERNAL_tcf_parse_params }}}
# tcfTry ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfTry
Starting function of block which will be skipped if an error has been detected
by tcfFin function occurent before.
tcfTry ["title"] [-i|--ignore] [--no-assert] [--fail-tag TAG] && {
<some code>
tcfFin; }
If title is omitted than noting is printed out so no error will be reported (no
Assert is executed) thus at least the very top level tcfTry should have title.
tcfTry and tcfChk blocks are stackable so you can organize them into a hierarchy
structure.
Note that tcfFin has to be used otherwise the overall result will not be
accurate.
=over
=item title
Text which will be displayed and logged at the beginning and the end (in tcfFin
function) of the block.
=item -i, --ignore
Do not propagate the actual result to the higher level result.
=item -n, --no-assert
Do not log error into the journal.
=item -f, --fail-tag TAG
If the result of the block is FAIL, use TAG instead ie. INFO or WARNING.
=back
Returns 1 if and error occured before, otherwise returns 0.
=cut
tcfTry() {
LogMoreLow -f "begin '$*'"
local vars=$(__INTERNAL_tcf_parse_params "$@") || { Log "$vars" FAIL; return 1; }
LogMoreMed -f "vars:\n$vars"
LogMoreLow -f "evaluating options start"
eval "$vars"
LogMoreLow -f "evaluating options end"
local incr=
local pp="SKIPPING"
tcfRES; # to set __INTERNAL_tcf_result
LogMoreLow -f "result was $__INTERNAL_tcf_result"
if [[ $__INTERNAL_tcf_result -eq 0 ]]; then
__INTERNAL_tcf_current_level_data=("$__INTERNAL_tcf_result" "$vars" "${__INTERNAL_tcf_current_level_data[@]}")
pp="BEGIN"
incr=1
fi
if [[ -n "$title" ]]; then
Log "$title" "$pp"
[[ -n "$incr" ]] && {
LogMoreLow -f "increment indentation level"
__INTERNAL_tcf_incr_current_level
}
fi
LogMoreLow -f "end"
return $__INTERNAL_tcf_result
}; # end of tcfTry }}}
# tcfChk ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfChk
Starting function of block which will be always executed.
tcfChk ["title"] [-i|--ignore] [--no-assert] [--fail-tag TAG] && {
<some code>
tcfFin; }
If title is omitted than noting is printed out so no error will be reported (no
Assert is executed) thus at least the very top level tcfChk should have title.
tcfTry and tcfChk blocks are stackable so you can organize them into a hierarchy
structure.
Note that tcfFin has to be used otherwise the overall result will not be
accurate.
For details about arguments see tcfTry.
Returns 0.
=cut
tcfChk() {
LogMoreLow -f "begin '$*'"
tcfRES; # to set __INTERNAL_tcf_result
local res=$__INTERNAL_tcf_result
tcfRES 0
tcfTry "$@"
__INTERNAL_tcf_current_level_data[0]=$res
LogMoreLow -f "end"
return $__INTERNAL_tcf_result
}; # end of tcfChk }}}
# tcfFin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfFin
Ending function of block. It does some evaluation of previous local and global
results and puts it into the global result.
tcfTry ["title"] && {
<some code>
tcfFin [-i|--ignore] [--no-assert] [--fail-tag TAG]; }
Local result is actualy exit code of the last command int the body.
Global result is an internal varibale hodning previous local results.
Respectively last error or 0.
For details about arguments see tcfTry.
Returns local result of the preceeding block.
=cut
tcfFin() {
local RES=$?
LogMoreLow -f "begin '$*'"
LogMoreMed -f "previous exit code was '$RES'"
local vars=$(__INTERNAL_tcf_parse_params "$@") || { Log "$vars" FAIL; return 1; }
LogMoreMed -f "vars:\n$vars"
LogMoreLow -f "evaluating options start"
eval "$vars"
LogMoreLow -f "evaluating options end"
tcfRES; # to set __INTERNAL_tcf_result
[[ $RES -ne 0 ]] && tcfRES $RES
RES=$__INTERNAL_tcf_result
LogMoreMed -f "overall result is '$RES'"
LogMoreMed -f "data:\n${__INTERNAL_tcf_current_level_data[1]}"
LogMoreLow -f "evaluating data start"
eval "${__INTERNAL_tcf_current_level_data[1]}"
LogMoreLow -f "evaluating data end"
if [[ -n "$title" ]]; then
__INTERNAL_tcf_decr_current_level
if [[ $ignore -eq 1 ]]; then
RES=0
[[ $__INTERNAL_tcf_result -ne 0 ]] && title="$title - ignored"
fi
if [[ $noass -eq 0 ]]; then
tcfAssert0 "$title" $__INTERNAL_tcf_result "$fail_tag"
else
if [[ $__INTERNAL_tcf_result -eq 0 ]]; then
local pp="PASS"
LogInfo "$title - $pp"
else
local pp="${fail_tag:-FAIL}"
LogWarn "$title - $pp"
fi
fi
fi
if [[ $__INTERNAL_tcf_result -eq 0 || $ignore -eq 1 ]]; then
tcfRES ${__INTERNAL_tcf_current_level_data[0]}
fi
local i
for i in 0 1; do unset __INTERNAL_tcf_current_level_data[$i]; done
__INTERNAL_tcf_current_level_data=("${__INTERNAL_tcf_current_level_data[@]}")
LogMoreLow -f "end"
return $RES
}; # end of tcfFin }}}
: <<'=cut'
=pod
=head2 Functions for manipulation with the results
=cut
# tcfRES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfRES
Sets and return the global result.
tcfRES [-p|--print] [number]
=over
=item -p --print
Also print the result value.
=item number
If present the global result is set to this value.
=back
Returns global result.
=cut
tcfRES() {
local p=0
while [[ -n "$1" ]]; do
case $1 in
--print|-p)
p=1
;;
*)
break
;;
esac
shift
done
if [[ -n "$1" ]]; then
__INTERNAL_tcf_result=$1
echo -n "$__INTERNAL_tcf_result" > "$__INTERNAL_tcf_result_file"
else
__INTERNAL_tcf_result="$(cat "$__INTERNAL_tcf_result_file")"
fi
[[ $p -eq 1 ]] && echo $__INTERNAL_tcf_result
return $__INTERNAL_tcf_result
}; # end of tcfRES }}}
# tcfOK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfOK
Sets the global result to 0.
tcfOK
Returns global result.
=cut
tcfOK() {
tcfRES 0
}; # end of tcfOK }}}
# tcfNOK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfNOK
Sets the global result to 1 or given number.
tcfNOK [number]
=over
=item number
If present the global result is set to this value.
=back
Returns global result.
=cut
tcfNOK() {
if [[ -n "$1" ]]; then
[[ $1 -eq 0 ]] && echo "You have requested result '0'. You should use tcfOK instead."
tcfRES $1
else
tcfRES 1
fi
}; # end of tcfNOK }}}
# tcfE2R ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfE2R
Converts exit code of previous command to local result if the exit code is not 0
(zero).
<some command>
tcfE2R [number]
=over
=item number
If present use it instead of exit code.
=back
Returns original exit code or given number.
=cut
tcfE2R() {
local res=$?
[[ -n "$1" ]] && res=$1
[[ $res -ne 0 ]] && tcfRES $res
return $res
}; # end of tcfE2R }}}
: <<'=cut'
=pod
=head2 Functions for manipulation with the exit codes
=cut
# tcfNEG ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfNEG
Negates exit code of previous command.
<some command>
tcfNEG
Returns 1 if original exit code was 0, otherwise returns 0.
=cut
tcfNEG() {
[[ $? -eq 0 ]] && return 1 || return 0
}; # end of tcfNEG }}}
# tcfRun ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfRun
Simmilar to rlRun but it also annouces the beginnign of the command.
tcfRun [--fail-tag|-f TAG] command [exp_result [title]]
Moreover if 'command not found' appears on STDERR it should produce WARNING.
=over
=item command
Command to execute.
=item exp_result
Specification of expect resutl.
It can be a list of values or intervals or * for any result. Also negation (!) can be used.
Example:
<=2,7,10-12,>252,!254 means following values 0,1,2,7,10,11,12,253,255
=item title
Text which will be displayed and logged at the beginning and the end of command execution.
=item --fail-tag | -f
If the command fails use TAG instead of FAIL.
=back
Returns exit code of the executed command.
=cut
tcfRun() {
LogMore_ -f "begin $*"
optsBegin
optsAdd 'fail-tag|f' --mandatory
optsAdd 'timeout' --optional 'timeout="${1:-10}"'
optsAdd 'kill-timeout|kt' --mandatory --default 5
optsAdd 'signal' --mandatory --default TERM
optsAdd 'check-code' --mandatory --default 'kill -0 $cmdpid >&/dev/null'
optsAdd 'kill-code' --mandatory --default '/bin/kill -$signal -- $cmdpid'
optsAdd 'allow-skip|as' --flag
optsAdd 'no-assert|n' --flag
optsDone; eval "${optsCode}"
LogMore_ -f "after opts $*"
[[ -z "$allowskip" ]] && tcfChk
local orig_expecode="${2:-0}"
local expecode="$orig_expecode"
[[ "$expecode" == "*" ]] && expecode="0-255"
local command="$1"
local comment="Running command '$command'"
[[ -n "$3" ]] && comment="$3"
[[ -n "$expecode" ]] && {
expecode=$(echo "$expecode" | tr ',-' '\n ' | sed -e 's/^!=/!/;s/^=//;s/^<=\(.\+\)$/0 \1/;s/^>=\(.\+\)$/\1 255/;s/^<\(.\+\)$/0 \$(( \1 - 1 ))/;s/^>\(.\+\)$/\$(( \1 + 1 )) 255/' | while read line; do [[ "$line" =~ ^[^\ ]+$ ]] && echo "$line" || eval seq $line; done; )
tcfE2R
LogMoreLow -f "orig_expecode='$orig_expecode'"
LogMoreLow -f "expecode='$expecode'"
}
tcfTry ${noassert:+--no-assert} "$comment" && {
local errout=$(mktemp)
LogMoreLow -f "executing '$command'"
if [[ "$optsPresent" =~ $(echo "\<timeout\>") ]]; then
LogDebug -f "using watchdog feature"
local ec="$(mktemp)"
eval "$command; echo $? > $ec 2> >(tee $errout)" &
local cmdpid=$!
local time_start=$(date +%s)
local timeout_t=$(( $time_start + $timeout ))
while true; do
if ! eval "$checkcode"; then
Log "command finished in $(($(date +%s) - $time_start )) seconds"
local res="$(cat $ec)"
break
elif [[ $(date +%s) -ge $timeout_t ]]; then
echo
Log "command is still running, sending $signal signal"
eval "$killcode"
tcfNOK 255
echo 255 > $ec
let timeout_t+=killtimeout
signal=KILL
fi
sleep 0.1
done
rm -f $ec
else
eval "$command" 2> >(tee $errout)
local res=$?
fi
LogMoreLow -f "got '$res'"
local resmatch=$(echo "$expecode" | grep "^\!\?${res}$")
LogMoreLow -f "resmatch='$resmatch'"
[[ -n "$resmatch" && ! "$resmatch" =~ '!' ]]
if tcfE2R; then
! grep -iq "command not found" $errout || { failtag='WARNING'; tcfNOK; }
else
Log "Expected result was '$orig_expecode', got '$res'!"
fi
tcfFin ${failtag:+--fail-tag "$failtag"}; }
rm -f $errout
[[ -z "$allowskip" ]] && tcfFin
LogMore_ -f "end $*"
return $res
}; # end of tcfRun }}}
: <<'=cut'
=pod
=head2 Functions for logging
=cut
# tcfAssert0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
tcfAssert0() {
LogMoreLow -f "begin '$*'"
local RES="${3:-FAIL}"
[[ $2 -eq 0 ]] && RES='PASS'
Log "$1" $RES
LogMoreLow -f "end"
}; # end of tcfAssert0 }}}
# tcfCheckFinal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
: <<'=cut'
=pod
=head3 tcfCheckFinal
Check that all tcfTry / tcfChk functions have been close by tcfFin.
tcfCheckFinal
=cut
tcfCheckFinal() {
tcfAssert0 "Check that TCF block cache is empty" ${#__INTERNAL_tcf_current_level_data[@]}
tcfAssert0 "Check that TCF current level is 0" $__INTERNAL_tcf_current_level_val
}; # end of tcfCheckFinal }}}
echo "done."
: <<'=cut'
=pod
=head2 Self check functions
=cut
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# tcfSelfCheck {{{
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head3 tcfSelfCheck
Does some basic functionality tests.
tcfSelfCheck
The function is called also by the following command:
./lib.sh selfcheck
=cut
tcfSelfCheck() {
tcfChk "check 1" &&{
tcfTry "try 1.1 - true" &&{
true
tcfFin;}
tcfTry "try 1.2 - false" &&{
false
tcfFin;}
tcfTry "try 1.3 - true" &&{
true
tcfFin;}
tcfFin;}
tcfChk "check 2" &&{
tcfTry "try 2.1 - true" &&{
true
tcfFin;}
tcfTry "try 2.2 - true - ignore" &&{
true
tcfFin -i;}
tcfTry "try 2.3 - true" &&{
true
tcfFin;}
tcfFin;}
tcfChk "check 3" &&{
tcfTry "try 3.1 - true" &&{
true
tcfFin;}
tcfTry "try 3.2 - false - ignore" &&{
false
tcfFin -i;}
tcfTry "try 3.3 - true" &&{
true
tcfFin;}
tcfFin;}
tcfCheckFinal
tcfAssert0 "Overall result" $(tcfRES -p)
LogReport
}
if [[ "$1" == "selfcheck" ]]; then
tcfSelfCheck
fi; # end of tcfSelfCheck }}}
# tcfLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
tcfLibraryLoaded() {
rlImport distribution/Log
declare -F rlDie > /dev/null && {
#rlJournalStart
#rlPhaseStartSetup "TCF"
echo -e "\nrunning inside the beakerlib - using rlAssert0"
true; tcfAssert0() {
local text="$1"
[[ "$3" != "FAIL" && "$3" != "PASS" ]] && text="$text - $3"
__INTERNAL_ConditionalAssert "$text" "$2"
}
__INTERNAL_tcf_do_hack
#rlPhaseEnd
#rlJournalEnd
};
if declare -F rlE2R >& /dev/null; then
__INTERNAL_tcf_kill_old_plugin
fi
true
}; # end of tcfLibraryLoaded }}}
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut

View File

@ -1,60 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /distribution/Library/testUser
# Description: Block style coding with ability of skipping parts.
# Author: Dalibor Pospisil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/distribution/Library/testUser
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) lib.sh Makefile
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Dalibor Pospisil <dapospis@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Setup/cleanup standard testing user." >> $(METADATA)
@echo "Type: Library" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RhtsRequires: library(distribution/Log)" >> $(METADATA)
@echo "Provides: library(distribution/testUser)" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,234 +0,0 @@
#!/bin/bash
# try-check-final.sh
# Authors: Dalibor Pospíšil <dapospis@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# library-prefix = testUser
# library-version = 7
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head1 NAME
BeakerLib library testUser
=head1 DESCRIPTION
This library provide s function for maintaining testing users.
=head1 USAGE
To use this functionality you need to import library distribution/testUser and add
following line to Makefile.
@echo "RhtsRequires: library(distribution/testUser)" >> $(METADATA)
=head1 VARIABLES
=over
=item testUser
Array of testing user login names.
=item testUserPasswd
Array of testing users passwords.
=item testUserUID
Array of testing users UIDs.
=item testUserGID
Array of testing users primary GIDs.
=item testUserGroup
Array of testing users primary group names.
=item testUserGIDs
Array of space separated testing users all GIDs.
=item testUserGroups
Array of space separated testing users all group names.
=item testUserGecos
Array of testing users gecos fields.
=item testUserHomeDir
Array of testing users home directories.
=item testUserShell
Array of testing users default shells.
=back
=head1 FUNCTIONS
=cut
echo -n "loading library testUser... "
: <<'=cut'
=pod
=head3 testUserSetup, testUserCleanup
Creates/removes testing user(s).
rlPhaseStartSetup
testUserSetup [NUM]
rlPhaseEnd
rlPhaseStartCleanup
testUserCleanup
rlPhaseEnd
=over
=item NUM
Optional number of user to be created. If not specified one user is created.
=back
Returns 0 if success.
=cut
testUserSetup() {
# parameter dictates how many users should be created, defaults to 1
local res=0
local count_created=0
local count_wanted=${1:-"1"}
local index=0
(( $count_wanted < 1 )) && return 1
while (( $count_created != $count_wanted ));do
let index++
local newUser="testuser${index}"
local newUserPasswd="redhat"
id "$newUser" &> /dev/null && continue # if user with the name exists, try again
# create
useradd -m $newUser >&2 || ((res++))
echo "$newUserPasswd" | passwd --stdin $newUser || ((res++))
# save the users array
testUser+=($newUser)
testUserPasswd+=($newUserPasswd)
set | grep "^testUser=" > $__INTERNAL_testUser_users_file
set | grep "^testUserPasswd=" >> $__INTERNAL_testUser_users_file
((count_created++))
done
__INTERNAL_testUserRefillInfo || ((res++))
echo ${res}
[[ $res -eq 0 ]]
}
__INTERNAL_testUserRefillInfo() {
local res=0
local user
testUserUID=()
testUserGID=()
testUserGroup=()
testUserGIDs=()
testUserGroups=()
testUserGecos=()
testUserHomeDir=()
testUserShell=()
for user in ${testUser[@]}; do
local ent_passwd=$(getent passwd ${user}) || ((res++))
local users_id="$(id ${user})" || ((res++))
# testUser is filled during user creation - already present
# testUserPasswd is saved same way as testUser - already present
testUserUID+=("$(echo "$ent_passwd" | cut -d ':' -f 3)")
testUserGID+=("$(echo "$ent_passwd" | cut -d ':' -f 4)")
testUserGroup+=("$(echo "$users_id" | sed -r 's/.*gid=(\S+).*/\1/;s/[[:digit:]]+\(//g;s/\)//g;s/,/ /g')")
testUserGIDs+=("$(echo "$users_id" | sed -r 's/.*groups=(\S+).*/\1/;s/\([^\)]+\)//g;s/\)//g;s/,/ /g')")
testUserGroups+=("$(echo "$users_id" | sed -r 's/.*groups=(\S+).*/\1/;s/[[:digit:]]+\(//g;s/\)//g;s/,/ /g')")
testUserGecos+=("$(echo "$ent_passwd" | cut -d ':' -f 5)")
testUserHomeDir+=("$(echo "$ent_passwd" | cut -d ':' -f 6)")
testUserShell+=("$(echo "$ent_passwd" | cut -d ':' -f 7)")
done
echo ${res}
[[ $res -eq 0 ]]
}
testUserCleanup() {
local res=0
for user in ${testUser[@]}; do
userdel -rf "$user" >&2 || ((res++))
done
unset testUser
__INTERNAL_testUserRefillInfo
rm -f $__INTERNAL_testUser_users_file >&2 || ((res++))
echo ${res}
[[ $res -eq 0 ]]
}
# testUserLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{
testUserLibraryLoaded() {
local res=0
# necessary init steps
__INTERNAL_testUser_users_file="$BEAKERLIB_DIR/users"
# try to fill in users array with previous data
[[ -f ${__INTERNAL_testUser_users_file} ]] && . ${__INTERNAL_testUser_users_file} >&2
__INTERNAL_testUserRefillInfo >&2 || ((res++))
[[ $res -eq 0 ]]
}; # end of testUserLibraryLoaded }}}
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Dalibor Pospisil <dapospis@redhat.com>
=back
=cut
echo "done."

File diff suppressed because one or more lines are too long

View File

@ -1,53 +0,0 @@
---
- hosts: localhost
tags: [ always ]
tasks:
- set_fact:
our_required_packages:
- sudo
- passwd # sudoers-options-sanity-test needs passwd command
- postfix # sudoers-options-sanity-test needs mailq command
- wget # upstream-testsuite-execution-and-rebuild-test needs wget command
- yum-utils # upstream-testsuite-execution-and-rebuild-test needs yum-builddep command
- rpm-build # upstream-testsuite-execution-and-rebuild-test needs rpmbuild command
- openssh-clients # use_pty-option needs ssh command
- expect # use_pty-option needs expect command
- procps # run-as needs ps command
- hosts: localhost
tags:
- classic
roles:
- role: standard-test-beakerlib
tests:
- sudoers-options-sanity-test
- upstream-testsuite-execution-and-rebuild-test
#- use_pty-option # test logic is currently broken; maintainer is looking into it
- run-as
- fully-qualified-hostnames
required_packages: "{{ our_required_packages }}"
- hosts: localhost
tags:
- container
roles:
- role: standard-test-beakerlib
tests:
- sudoers-options-sanity-test
- upstream-testsuite-execution-and-rebuild-test
#- use_pty-option # cannot run (needs sshd configured and running)
- run-as
#- fully-qualified-hostnames # cannot run (needs sshd configured and running)
required_packages: "{{ our_required_packages }}"
- hosts: localhost
tags:
- atomic
roles:
- role: standard-test-beakerlib
tests:
- run-as
# - sudoers-options-sanity-test # cannot run (needs to re-install package)
# - upstream-testsuite-execution-and-rebuild-test # cannot run (needs compiler suite)
# - use_pty-option # cannot run (needs expect)
# - fully-qualified-hostnames # cannot run (needs expect)

View File

@ -1,70 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/sudo/Sanity/upstream-testsuite-execution-and-rebuild-test
# Description: This test rebuild sudo source rpm and checks that rebuild is OK. The second - main - part is about upstream testsuite execution.
# Author: Ales Marecek <amarecek@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2013 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/sudo/Sanity/upstream-testsuite-execution-and-rebuild-test
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Ales Marecek <amarecek@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: This test rebuild sudo source rpm and checks that rebuild is OK. The second - main - part is about upstream testsuite execution." >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 15m" >> $(METADATA)
@echo "RunFor: sudo" >> $(METADATA)
@echo "Requires: sudo" >> $(METADATA)
@echo "Requires: sed" >> $(METADATA)
@echo "Requires: grep" >> $(METADATA)
@echo "Requires: rpm-build" >> $(METADATA)
@echo "Requires: yum-utils" >> $(METADATA)
@echo "Requires: make" >> $(METADATA)
@echo "Requires: libcap-devel" >> $(METADATA)
@echo "Requires: audit-libs-devel" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,3 +0,0 @@
PURPOSE of /CoreOS/sudo/Sanity/upstream-testsuite-execution-and-rebuild-test
Description: This test rebuild sudo source rpm and checks that rebuild is OK. The second - main - part is about upstream testsuite execution.
Author: Ales Marecek <amarecek@redhat.com>

View File

@ -1,80 +0,0 @@
#!/bin/bash
# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/sudo/Sanity/upstream-testsuite-execution-and-rebuild-test
# Description: This test rebuild sudo source rpm and checks that rebuild is OK. The second - main - part is about upstream testsuite execution.
# Author: Ales Marecek <amarecek@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2013 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include Beaker environment
. /usr/bin/rhts-environment.sh || exit 1
. /usr/share/beakerlib/beakerlib.sh || exit 1
PACKAGE="sudo"
_SPEC_DIR="$(rpm --eval=%_specdir)"
_BUILD_DIR="$(rpm --eval=%_builddir)"
_LOG_REBUILD_F="${PACKAGE}-rebuild.log"
_LOG_TESTSUITE_F="${PACKAGE}-testsuite.log"
rlJournalStart
rlPhaseStartSetup
rlAssertRpm $PACKAGE
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
rlRun "pushd $TmpDir"
# Source package is needed for code inspection
rlFetchSrcForInstalled "${PACKAGE}" || yumdownloader --source "${PACKAGE}"
rlRun "find . -size 0 -delete" 0 "Remove empty src.rpm-s"
rlRun "yum-builddep -y --nogpgcheck ${PACKAGE}-*.src.rpm" 0 "Installing build dependencies"
[ -d ${_BUILD_DIR} ] && rlRun "rm -rf ${_BUILD_DIR}/*" 0 "Cleaning build directory"
rlRun "rpm -ivh ${PACKAGE}-*.src.rpm" 0 "Installing source rpm"
rlPhaseEnd
rlPhaseStartTest
rlRun "QA_RPATHS=0x0002 rpmbuild -ba ${_SPEC_DIR}/${PACKAGE}.spec" 0 "Test: Rebuild of source '${PACKAGE}' package"
rlGetPhaseState
if [ $? -eq 0 ]; then
cd ${_BUILD_DIR}/${PACKAGE}-*
rlRun -s "make check" 0 "Test: Upstream testsuite"
cd ${TmpDir}
while read -r I; do
if [[ "$I" =~ $(echo '([^:]+): .+ tests run, .+ errors, (.*)% success rate') ]]; then
[[ "${BASH_REMATCH[2]}" == "100" ]]
rlAssert0 "Test: Checking tests of '${BASH_REMATCH[1]}'" $?
elif [[ "$I" =~ $(echo "([^:]+): .+ tests passed; (.+)/.+ tests failed") ]]; then
[[ "${BASH_REMATCH[2]}" == "0" ]]
rlAssert0 "Test: Checking tests of '${BASH_REMATCH[1]}'" $?
fi
done < $rlRun_LOG
rm -f $rlRun_LOG
else
rlFail "Skipping testsuite part because rebuild part failed."
fi
rlPhaseEnd
rlPhaseStartCleanup
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View File

@ -1,72 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/sudo/Sanity/use_pty-option
# Description: checks if use_pty option in /etc/sudoers works as expected
# Author: Milos Malik <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2011 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/sudo/Sanity/use_pty-option
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE forker.sh ssh-sudo.exp
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
chmod a+x runtest.sh
chmod a+x ssh-sudo.exp
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Milos Malik <mmalik@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: checks if use_pty option in /etc/sudoers works as expected" >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 10m" >> $(METADATA)
@echo "RunFor: sudo" >> $(METADATA)
@echo "Requires: sudo" >> $(METADATA)
@echo "Requires: iputils" >> $(METADATA)
@echo "Requires: sed" >> $(METADATA)
@echo "Requires: grep" >> $(METADATA)
@echo "Requires: mktemp" >> $(METADATA)
@echo "Requires: openssh-server" >> $(METADATA)
@echo "Requires: openssh-clients" >> $(METADATA)
@echo "Requires: expect" >> $(METADATA)
@echo "Requires: shadow-utils" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -1,4 +0,0 @@
PURPOSE of /CoreOS/sudo/Sanity/use_pty-option
Description: checks if use_pty option in /etc/sudoers works as expected
Author: Milos Malik <mmalik@redhat.com>

View File

@ -1,5 +0,0 @@
#!/bin/bash
for i in `seq 1 10`; do
( ping -c 10 -q www.redhat.com & )
done

View File

@ -1,76 +0,0 @@
#!/bin/bash
# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/sudo/Sanity/use_pty-option
# Description: checks if use_pty option in /etc/sudoers works as expected
# Author: Milos Malik <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2011 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include rhts environment
. /usr/bin/rhts-environment.sh
. /usr/share/beakerlib/beakerlib.sh
PACKAGE="sudo"
USER_NAME="user${RANDOM}"
USER_SECRET="s3kr3T${RANDOM}"
rlJournalStart
rlPhaseStartSetup
rlAssertRpm ${PACKAGE}
OUTPUT_FILE=`mktemp`
rlFileBackup /etc/sudoers
rlFileBackup --clean ~/.ssh
rlRun "useradd ${USER_NAME}"
rlRun "echo ${USER_SECRET} | passwd --stdin ${USER_NAME}"
rlRun "cp ./forker.sh /home/${USER_NAME}/"
rlRun "chown ${USER_NAME}:${USER_NAME} /home/${USER_NAME}/forker.sh"
rlRun "chmod u+x /home/${USER_NAME}/forker.sh"
rlRun "echo \"${USER_NAME} ALL = NOPASSWD: /home/${USER_NAME}/forker.sh\" >> /etc/sudoers"
rlRun "sed -i 's/^.*requiretty.*$//' /etc/sudoers"
rlRun "echo \"Defaults !requiretty\" >> /etc/sudoers"
rlRun "> ~/.ssh/known_hosts"
rlPhaseEnd
rlPhaseStartTest "use_pty option is enabled"
rlRun "sed -i 's/^.*use_pty.*$//' /etc/sudoers"
rlRun "echo \"Defaults use_pty\" >> /etc/sudoers"
rlRun "./ssh-sudo.exp ${USER_NAME} ${USER_SECRET} localhost ./forker.sh 2>&1 | tee ${OUTPUT_FILE}"
rlAssertNotGrep "ping statistics" ${OUTPUT_FILE}
rlPhaseEnd
rlPhaseStartTest "use_pty option is disabled"
rlRun "sed -i 's/^.*use_pty.*$//' /etc/sudoers"
rlRun "echo \"Defaults !use_pty\" >> /etc/sudoers"
rlRun "./ssh-sudo.exp ${USER_NAME} ${USER_SECRET} localhost ./forker.sh 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "ping statistics" ${OUTPUT_FILE}
rlPhaseEnd
rlPhaseStartCleanup
rlRun "userdel -rf ${USER_NAME}"
rlFileRestore
rm -f ${OUTPUT_FILE}
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View File

@ -1,20 +0,0 @@
#!/usr/bin/expect -f
# usage:
# ./ssh-sudo.exp username password hostname command
set username [lrange $argv 0 0]
set password [lrange $argv 1 1]
set hostname [lrange $argv 2 2]
set command [lrange $argv 3 3]
set timeout 15
spawn ssh $username@$hostname sudo $command
expect "*yes/no*" {
send -- "yes\r"
}
expect "*assword*" {
send -- "$password\r"
}
expect "*assword*" {
send -- "$password\r"
}
expect eof