staging.inyokaproject.org

Skripte ausrollen per Jenkins inkl. sudo

Status: Ungelöst | Ubuntu-Version: Ubuntu 17.04 (Zesty Zapus)
Antworten |

gurbelunder

Avatar von gurbelunder

Anmeldungsdatum:
6. Juni 2006

Beiträge: 268

Hallo zusammen,

ich hoffe, ich habe jetzt die richtige Kategorie ausgewählt.

Für mein internes Monitoring möchte ich über einen jenkins Server automatisiert Skripte aus meinem Git auf meine Ubuntu Maschine ausliefern lassen. Dazu cloned Jenkins das Repository von mir auf seiner eigenen Maschine aus, tar't die Dateien, schiebt sie per SSH auf die Ubuntu Maschine und packt sie dort aus. Alles geschieht als User "jenkins_de" und funktioniert wunderbar.

Nun müssen aber die Skripte in den Ordner /usr/lib64/nagios/plugins verschoben werden, wo sie im allgemeinen hin gehören. Das Verzeichnis gehört root und die Dateien / Skripte ebenfalls. Daran möchte ich auch nichts ändern.

Ich habe nun das folgende Skript geschrieben

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/bin/bash

###############################################################################

# description:
# script for rolling out monitoring scripts to nagios plugin folder

# author: dpasternak

# last change done by: me
# last change done at: 10.08.2017

# $Id: $

# $HeadURL: $

###############################################################################

# *****************************************************************************
# deklarations
# *****************************************************************************

# *****************************************************************************
# functions
# *****************************************************************************

# usage - check the usage of script and close with exit 1 if parameters not OK
usage() {
    [ $# == 0 ] || abort 'usage '${0##*/}' without any options\n'
}

# msg - give out any message
msg() {
    [ $# == 1 ] || msg 'wrong params @ msg()'

    typeset msg="$*"
    echo -e "$msg"
}

# abort - abort function for other functions
abort() {
    [ $# == 1 ] || msg 'wrong params @ abort()'

    typeset message="$*"
    msg "$message"
    exit 1
}

# start_process - starting copying of scripts
start_process() {
    [ $# == 0 ] || abort ''${0##*/}' - wrong params @ start_process()'

    target_directory="/usr/lib64/nagios/plugins/"

    source_directory="/home/jenkins_de/scripts_monitoring"
    /bin/sudo -u root /bin/cp -rv $source_directory/plugins/* $target_directory
}

# *****************************************************************************
# main
# *****************************************************************************

usage "$@"

start_process

Den Befehl "/bin/sudo -u root /bin/cp -rv $source_directory/plugins/* $target_directory" habe ich in der allgemeinen sudoers auf der Ubuntu Maschine eingetragen, das sieht dort so aus:

1
jenkins_de      ALL = (root) NOPASSWD: /bin/cp -rv /home/jenkins_de/scripts_monitoring/plugins/* /usr/lib64/nagios/plugins/

Natürlich alles fein mit "visudo" gemacht 😉

Führe ich das Skript nun direkt auf der Maschine aus, funktioniert das Kopieren der Dateien wunderbar.

Führe ich aber den Job auf dem Jenkins aus (auf dem Jenkins redet man von Job bauen), dann kommt letztlich der folgende Fehler:

1
sudo: Kein TTY vorhanden und kein »askpass«-Programm angegeben

Skript

Der Aufruf im Jenkins ist ganz einfach nur voller Pfad + Skript:

1
/home/jenkins_de/scripts_monitoring/rollout_monitoring_scripts.sh

So funktioniert es zumindest wunderbar lokal:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[jenkins_de@ubu_server scripts_monitoring]$ /home/jenkins_de/scripts_monitoring/rollout_monitoring_scripts.sh
„/home/jenkins_de/scripts_monitoring/plugins/check_asm“ -> „/usr/lib64/nagios/plugins/check_asm“
„/home/jenkins_de/scripts_monitoring/plugins/check_dummy“ -> „/usr/lib64/nagios/plugins/check_dummy“
„/home/jenkins_de/scripts_monitoring/plugins/check_grid“ -> „/usr/lib64/nagios/plugins/check_grid“
„/home/jenkins_de/scripts_monitoring/plugins/check_hugepages.sh“ -> „/usr/lib64/nagios/plugins/check_hugepages.sh“
„/home/jenkins_de/scripts_monitoring/plugins/check_iowait“ -> „/usr/lib64/nagios/plugins/check_iowait“
„/home/jenkins_de/scripts_monitoring/plugins/check_oracle_asm“ -> „/usr/lib64/nagios/plugins/check_oracle_asm“
„/home/jenkins_de/scripts_monitoring/plugins/check_ora_db“ -> „/usr/lib64/nagios/plugins/check_ora_db“
„/home/jenkins_de/scripts_monitoring/plugins/check_splex.sh“ -> „/usr/lib64/nagios/plugins/check_splex.sh“
„/home/jenkins_de/scripts_monitoring/plugins/check_test“ -> „/usr/lib64/nagios/plugins/check_test“
„/home/jenkins_de/scripts_monitoring/plugins/db_scripts/create_public_synonym_oraerror.sql“ -> „/usr/lib64/nagios/plugins/db_scripts/create_public_synonym_oraerror.sql“
„/home/jenkins_de/scripts_monitoring/plugins/db_scripts/grants_nagios_user.sql“ -> „/usr/lib64/nagios/plugins/db_scripts/grants_nagios_user.sql“
„/home/jenkins_de/scripts_monitoring/plugins/db_scripts/create_nagios_user.sql“ -> „/usr/lib64/nagios/plugins/db_scripts/create_nagios_user.sql“
„/home/jenkins_de/scripts_monitoring/plugins/db_scripts/create_table_system_oraerror.sql“ -> „/usr/lib64/nagios/plugins/db_scripts/create_table_system_oraerror.sql“
„/home/jenkins_de/scripts_monitoring/plugins/db_scripts/create_trigger_after_error.sql“ -> „/usr/lib64/nagios/plugins/db_scripts/create_trigger_after_error.sql“
„/home/jenkins_de/scripts_monitoring/plugins/db_scripts/create_export_tables.sql“ -> „/usr/lib64/nagios/plugins/db_scripts/create_export_tables.sql“
„/home/jenkins_de/scripts_monitoring/plugins/include/common.global.functions“ -> „/usr/lib64/nagios/plugins/include/common.global.functions“
„/home/jenkins_de/scripts_monitoring/plugins/include/common.global.statics“ -> „/usr/lib64/nagios/plugins/include/common.global.statics“
„/home/jenkins_de/scripts_monitoring/plugins/libexec/check_oracle_health“ -> „/usr/lib64/nagios/plugins/libexec/check_oracle_health“
[jenkins_de@ubu_serverscripts_monitoring]$

So langsam verstehe ich nur noch Bahnhof. Ich vermute fast, dass es an dem sudoers Eintrag letztlich nicht liegt, sondern entweder an der "Art und Weise", wie ich den copy Befehl im Skript ausführe oder wie das Skript im Jenkins aufgerufen wird.

Habt ihr noch Ideen?

Danke euch und beste Grüße, David

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

gurbelunder schrieb:

Den Befehl "/bin/sudo -u root /bin/cp -rv $source_directory/plugins/* $target_directory" habe ich in der allgemeinen sudoers auf der Ubuntu Maschine eingetragen, das sieht dort so aus:

1
jenkins_de      ALL = (root) NOPASSWD: /bin/cp -rv /home/jenkins_de/scripts_monitoring/plugins/* /usr/lib64/nagios/plugins/

Das geht m.W. nicht. Man kann nur ein Kommando angeben. Warum gibst Du nicht das Skript /home/jenkins_de/scripts_monitoring/rollout_monitoring_scripts.sh an und rufst es mit sudo aus dem Jenkins-Job auf?

Führe ich aber den Job auf dem Jenkins aus (auf dem Jenkins redet man von Job bauen), dann kommt letztlich der folgende Fehler:

1
sudo: Kein TTY vorhanden und kein »askpass«-Programm angegeben

Ja, daran erkennst Du, dass die Konfiguration in /etc/sudoers nicht funktioniert, wie Du Dir das vorgestellt hast.

Der Aufruf im Jenkins ist ganz einfach nur voller Pfad + Skript:

1
/home/jenkins_de/scripts_monitoring/rollout_monitoring_scripts.sh

Da sollte ein sudo davor stehen, wie oben angemerkt und das Skript sollte dann in der /etc/sudoers eingetragen sein. Du willst ja auch nicht ein so allgemeines Kommando wie cp automatisch per "root" ausführen lassen.

gurbelunder

(Themenstarter)
Avatar von gurbelunder

Anmeldungsdatum:
6. Juni 2006

Beiträge: 268

rklm schrieb:

gurbelunder schrieb:

Der Aufruf im Jenkins ist ganz einfach nur voller Pfad + Skript:

1
/home/jenkins_de/scripts_monitoring/rollout_monitoring_scripts.sh

Da sollte ein sudo davor stehen, wie oben angemerkt und das Skript sollte dann in der /etc/sudoers eingetragen sein. Du willst ja auch nicht ein so allgemeines Kommando wie cp automatisch per "root" ausführen lassen.

An sich ja sicher sinnig, aber warum funktioniert es dann genau so lokal als jenkins_de User?

rklm schrieb:

gurbelunder schrieb:

Den Befehl "/bin/sudo -u root /bin/cp -rv $source_directory/plugins/* $target_directory" habe ich in der allgemeinen sudoers auf der Ubuntu Maschine eingetragen, das sieht dort so aus:

1
jenkins_de      ALL = (root) NOPASSWD: /bin/cp -rv /home/jenkins_de/scripts_monitoring/plugins/* /usr/lib64/nagios/plugins/

Das geht m.W. nicht. Man kann nur ein Kommando angeben. Warum gibst Du nicht das Skript /home/jenkins_de/scripts_monitoring/rollout_monitoring_scripts.sh an und rufst es mit sudo aus dem Jenkins-Job auf?

Ich habe da zwar schon andere Erfahrungen gemacht, bin aber sehr gerne offen für neue Ideen. Daher fix die sudoers geändert:

1
jenkins_de      ALL = (root) NOPASSWD: /home/jenkins_de/scripts_monitoring/rollout_monitoring_scripts.sh

Dann noch das Skript angepasst, dieser Teil braucht ja dann kein sudo mehr:

1
Code

Zuletzt noch den Aufruf im Jenkins angepasst auf:

1
sudo -u root /home/jenkins_de/scripts_monitoring/rollout_monitoring_scripts.sh

Und dann den Job wieder gebaut. Es bleibt dabei:

1
sudo -u root /home/jenkins_de/scripts_monitoring/rollout_monitoring_scripts.sh

Funktioniert leider nicht.

Ich habe daher wieder alles auf die hier im Anfangspost beschriebene Ursprungslösung gedreht und diesmal funktioniert es sogar. Ich bin des öfteren über das Problem gestoßen, dass ich irgendwelche nicht sichtbaren Sonderzeichen in die sudoers gebracht habe. Evtl. hat es die jetzt vernichtet. Die Skripte werden nun wunderbar ausgerollt, mein sudoers Eintrag sieht wieder so aus:

1
jenkins_de      ALL = (root) NOPASSWD: /bin/cp -rv /home/jenkins_de/scripts_monitoring/plugins/* /usr/lib64/nagios/plugins/

Klappt wunderbar. Danke für eure Hilfe!

Beste Grüße, David

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Ich habe noch mal nachgeschaut und Du hast Recht: man kann Kommandozeilenargumente angeben:

     If a Cmnd has associated command line arguments, then the arguments in the Cmnd must match exactly those given by the user on the
     command line (or match the wildcards if there are any).  Note that the following characters must be escaped with a ‘\’ if they are
     used in command arguments: ‘,’, ‘:’, ‘=’, ‘\’.  The built-in command “sudoedit” is used to permit a user to run sudo with the -e
     option (or as sudoedit).  It may take command line arguments just as a normal command does.  Note that “sudoedit” is a command
     built into sudo itself and must be specified in the sudoers file without a leading path.

Wieder was gelernt!

👍

gurbelunder

(Themenstarter)
Avatar von gurbelunder

Anmeldungsdatum:
6. Juni 2006

Beiträge: 268

Ergänzend, was ich gerade noch nicht gelöst bekomme:

Ich habe den sudoers Eintrag, so, wie er ist, mit visudo -f in eine eigene sudoers Datei gepackt und aus der zentralen sudoers wieder raus genommen.

1
[root@kent ~]# visudo -f /etc/sudoers.d/jenkins_monitoring

Inhalt der jenkins-monitoring sudoers Datei:

1
jenkins_de      ALL = (root) NOPASSWD: /bin/cp -rv /home/jenkins_de/scripts_monitoring/plugins/* /usr/lib64/nagios/plugins/

Damit funktioniert es leider nicht mehr. Aber warum?

TheDarkRose

Avatar von TheDarkRose

Anmeldungsdatum:
28. Juli 2010

Beiträge: 3459

gurbelunder schrieb:

tar't die Dateien, schiebt sie per SSH auf die Ubuntu Maschine und packt sie dort aus.

Möglichkeit 1: Ich würd einfach mal sagen, dass ist der falsche Weg. Ein tar und einfach auspacken ist kein Artifakt. Richtiger wäre es im Jenkins ein .deb zu bauen. Dort hast du dann auch die postinstall Skripte um deine Skripte an die richtige Stelle zu schieben (wenn überhaupt nötig - weil die richtige Position schon beim Packen vom .deb möglich ist). Das .deb wird dann entweder wirklich noch "händisch" vom Jenkins wie dpkg installiert, oder besser du kannst es in ein Repository pushen und auf deinen Servern nur ein Update auslösen.

Möglichkeit 2: Du schaust dir z.B. Ansible an und pusht deine Konfiguration damit rauf. Bisschen oversized außer es wird noch mehr.

Möglichkeit 3: Wo ist das Problem auf den Nagios Ordner via ACLs dem jenkins_de User die Schreibrechte zu geben? sudo ist da wirklich overkill. (Selbiges gilt für Möglichkeit 2 - braucht auch entweder sudo oder Schreibrechte via ACLs z.B.)

gurbelunder

(Themenstarter)
Avatar von gurbelunder

Anmeldungsdatum:
6. Juni 2006

Beiträge: 268

Also es ist ja echt eine Geschmackssache, aber für 4-5 Skripte extra ein deb Paket bauen, was auch selbst noch eine Versionierung braucht, finde ich wieder total oversized. Aber dennoch besten Dank für den Tipp.

Antworten |