Heterogenes Client-Management

Erol Ülükmen

Copyright

Das Copyright an diesem Handbuch liegt bei der uib gmbh in Mainz.

Dieses Handuch ist veröffentlicht unter der creative commons Lizenz
Namensnennung - Weitergabe unter gleichen Bedingungen (by-sa).

CC by sa

Eine Beschreibung der Lizenz finden Sie hier:
http://creativecommons.org/licenses/by-sa/3.0/de/

Der rechtsverbindliche Text der Lizenz ist hier:
http://creativecommons.org/licenses/by-sa/3.0/de/legalcode

Die Software von opsi ist in weiten Teilen Open Source.
Nicht Open Source sind die Teile des Quellcodes, welche neue Erweiterungen enthalten die noch unter Kofinanzierung stehen, also noch nicht bezahlt sind.
siehe auch: http://uib.de/de/opsi-erweiterungen/erweiterungen/

Der restliche Quellcode ist veröffentlicht unter der AGPLv3:

agplv3

Der rechtsverbindliche Text der AGPLv3 Lizenz ist hier:
http://www.gnu.org/licenses/agpl-3.0-standalone.html

Deutsche Infos zur AGPL: http://www.gnu.org/licenses/agpl-3.0.de.html

Für Lizenzen zur Nutzung von opsi im Zusammenhang mit Closed Source Software kontaktieren Sie bitte die uib gmbh.

Die Namen opsi, opsi.org, open pc server integration und das opsi-logo sind eingetragene Marken der uib gmbh.

Übersicht

Voraussetzungen

Linux-Support

Warum ein weiteres Managementwerkzeug für Linux?

Linux-Support

Es gibt doch bereits Linux-Managementsysteme: FAI, M23, Puppet, Ansible, Chef, CFEngine… Was ist anders in opsi?

opsi in der Infrastruktur

Beispiel einer Infrastruktur mit opsi

infrastrukturplan.png

opsi-script: Nützliche Befehle

Wo sind wir gerade?

Architektur

Windows

Linux

opsi-script: Nützliche Befehle

getMsVersionInfo [W]

GetMsVersionInfo

Windows Version

5.0

Windows 2000

5.1

Windows XP (Home, Prof)

….

….

6.1

Windows 7, 2008 R2

6.2

Windows 8, 2012

6.3

Windows 8.1, 2012 R2

10.0

Windows 10

opsi-script: Nützliche Befehle

getMsVersionMap [W]

Set  $INST_Resultlist$ = getMSVersionMap

Ergebnis als Stringliste:

(string   0)major_version=5
(string   1)minor_version=1
(string   2)build_number=2600
(string   3)platform_id=2
....

opsi-script: Nützliche Befehle

Abholen eines Wertes mit getValue:

DefVar $result$
set $result$ = getValue("build_number", $INST_Resultlist$)

opsi-script: Nützliche Befehle

getLinuxVersionMap [L]

Set  $INST_Resultlist$ = getLinuxVersionMap

Ergebnis als Stringliste

(string   0)Distributor ID=Ubuntu
(string   1)Description=Ubuntu 16.04.3 LTS
(string   2)Release=16.04
(string   3)Codename=xenial
(string   4)SubRelease=
(string   5)kernel name=Linux
...

opsi-script: Nützliche Befehle

shellCall [W/L]

shellCall("echo Hallo Welt")

opsi-script: Nützliche Befehle

shellCall Magic

set $string$ = shellCall("echo Hallo Welt")
set $stringlist$ = shellCall("echo Hallo Welt")

opsi-script: Nützliche Befehle

shellCall [W/L]

shellCall(’net start’)

Ist eine Abkürzung für:

DosInAnIcon_netstart winst /sysnative

[DosInAnIcon_netstart]
net start

opsi-script: Nützliche Befehle

shellCall [W/L]

DefVar $exitcode$
set $exitcode$ = shellCall(’net start’)

Ist eine Abkürzung für:

DefVar $exitcode$
DosInAnIcon_netstart winst /sysnative
set $exitcode$ = getLastExitcode

[DosInAnIcon_netstart]
net start

opsi-script: Nützliche Befehle

shellCall [W/L]

DefStringList $list$
set $list$ = shellCall(’net start’)

Ist eine Abkürzung für:

DefStringList $list$
set $list$ = getOutStreamFromSection (’DosInAnIcon_netstart winst /sysnative’)

[DosInAnIcon_netstart]
net start

opsi-script: Nützliche Befehle

processCall [W/L]

processCall(<string>) :string (exitcode)  [W/L]

Startet das Programm <string> als Prozess und liefert den Exitcode zurück.

opsi-script: Nützliche Befehle

processCall [W/L] Erläuterung:

set $exitcode$ = processCall('setup.exe /S')

Ist eine Abkürzung für den Ausdruck:

Winbatch_setup
set $exitcode$ = getLastExitcode

[Winbatch_setup]
setup.exe /S

opsi-script: Nützliche Befehle

Nutzung der OS-Paketverwaltung [L]

opsi-script: Nützliche Befehle

waitForPackageLock (Snippet aus l-opsi-server)

Message "Try to get Package Lock..."
if waitForPackageLock("300","false")
        comment "we got the package lock."
        if $distroName$ = 'Univention'
                comment "UCS: Extra check if package lock is available."
                ...
        endif
else
        LogError "could not get Package Lock"
        isFatalError "package lock failed"
endif

opsi-script: Internal flow

opsi-script: Internal flow

opsi-script: Internal flow

Warum ist das folgende wichtig?

Errordetection

Methoden:

getLastExitCode :string (exitcode) [W/L]

markErrorNumber / errorsOccurredSinceMark [W/L]
LogError

Errordetection: Exitcode 1

getLastExitCode

getLastExitCode :string (exitcode) [W/L]

Errordetection: Exitcode 2

cmd.exe

[DosInAnIcon_exit1]
rem create an errolevel= 1
VERIFY OTHER 2> NUL
exit %ERRORLEVEL%

bash

[ShellInAnIcon_Upgrade_ucs]
set -x
univention-upgrade --noninteractive --ignoreterm
exit $?

Errordetection: Exitcode 3

Problem an einem bash-Beispiel

[ShellInAnIcon_Upgrade_deb]
set -x
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get --yes dist-upgrade
exit $?

Errordetection: Exitcode 3a

Lösung

[ShellInAnIcon_Upgrade_deb]
set -x
export DEBIAN_FRONTEND=noninteractive
EXITCODE=0
apt-get update
EC=$?; if [ $EC -ne 0 ]; then EXITCODE=$EC; fi
apt-get --yes dist-upgrade
EC=$?; if [ $EC -ne 0 ]; then EXITCODE=$EC; fi
exit $EXITCODE

Errordetection: Exitcode 3b

Lösung mit shellCall ohne sekundäre Sektion (NOT TESTED)

set $exitcode$ = shellCall("apt-get update")
if $exitcode$ = 0
  set $exitcode$ = shellCall("apt-get --yes dist-upgrade")
  if NOT ($exitcode$ = 0)
    logError("dist-updrade failed with exitcode: " + $exitcode)
  endif
else
  logError("apt-get update failed with exitcode: " + $exitcode)
endif

Errordetection: Exitcode 4

Errordetection: markErrorNumber

Beispiel:

markErrorNumber
logError "test error"
if errorsOccurredSinceMark > 0
    comment "error occured"
else
    comment "no error occured"
endif

Errordetection: Fehlerauswertung

Errordetection: Fehlerauswertung Methoden

isFatalError [W/L]
isSuspended [W/L]
isSuccess [W/L]
noUpdateScript [W/L]

Errordetection: Fehlerauswertung 2

Errordetection: Fehlerauswertung isFatalError

isFatalError
isFatalError "short message"

Errordetection: Fehlerauswertung 3 (ausführliche Fehlerbehandlung)

DefStringList $ErrorList$
Message "Configure depotadmin as depotadmin..."
ShellInAnIcon_config_depotadmin
if not("0" = getLastExitCode)
        LogError "failed config_depotadmin"
        set $fatal_error$ = "true"
        set $errorList$ = addtolist($errorList$, " failed config_depotadmin")
endif
if count($errorList$) > "0"
        logError "Error summary:"
        setloglevel = 6
        for %akterror% in $errorList$ do LogError "%akterror%"
endif
if $fatal_error$ = "true"
  isFatalError
endif

Errordetection: Fehlerauswertung 4

Errordetection: Weitere Methoden für Fehlerauswertung

opsi-script: Local Functions

Was ist das Problem

opsi-script: Local Functions

Vorstellung: Local Functions in opsi-script

Ein Beispiel:

DefFunc myFunc(val $str1$ : string, $str2$ : string) : string
        set $result$ = $str1$ + $str2$
endfunc

opsi-script: Local Functions

Konzept und Ziel dieser Erweiterung

opsi-script: Local Functions

CallByValue vs. CallByReference

opsi-script: Local Functions

Konzept und Ziel dieser Erweiterung Fortsetzung

opsi-script: Local Functions

Konzept und Ziel dieser Erweiterung Fortsetzung

opsi-script: Local Functions

Syntax

DefFunc <func name>([calltype parameter type][,[calltype parameter type]]) : type
<function body>
endfunc

opsi-script: Local Functions

Syntax

DefFunc <func name>([calltype parameter type][,[calltype parameter type]]) : type
<function body>
endfunc

opsi-script: Local Functions

Beispiel1: Local Functions in opsi-script

[actions]
DefVar $mystr$
DefVar $str1$
set $str1$ = 'ha'

DefFunc myFunc(val $str1$ : string, $str2$ : string) : string
        set $result$ = $str1$ + $str2$
endfunc

set $mystr$ = myFunc("he","ho")
set $mystr$ = myFunc("he",timeStampAsFloatStr)
set $mystr$ = myFunc("he",$str1$)

opsi-script: Local Functions

Beispiel1: Local Functions in opsi-script

Erwartete Ergebnisse:

  • heho
  • he42921.809
  • heha
....
set $mystr$ = myFunc("he","ho")
set $mystr$ = myFunc("he",timeStampAsFloatStr)
set $mystr$ = myFunc("he",$str1$)
....

opsi-script: Local Functions

Beispiel2: Local Functions in opsi-script

[actions]
DefVar $mystr$
DefVar $str1$
DefStringlist $list1$
DefStringlist $list2$

set $str1$ = 'ha'

DefFunc myFunc1(val $str1$ : string, $list1$ : stringlist) : stringlist
        set $result$ = createStringlist($str1$ , takeString(2,$list1$))
endfunc

set $list2$ = splitstring("/etc/opsi/huhu","/")
set $list1$ = myFunc1("hi",$list2$)

opsi-script: Local Functions

Beispiel3: Local Functions in opsi-script

[actions]
DefFunc myFunc2($str1$ : string) : string
        if $str1$ > "0"
                set $result$ = "true"
        else
                set $result$ = "false"
        endif
endfunc
if stringtobool(myfunc2("1"))
        comment "true"
else
        comment "false"
endif

opsi-script: Local Functions

Beispiel4: Local Functions in opsi-script

(defined_functions3.opsiscript)

[actions]
DefVar $mystr$

DefFunc myFunc3($str1$ : string) : string
        DefVar $locstr1$
        set $locstr1$ = '123'
        set $result$ = $locstr1$ + $str1$
endfunc

set $mystr$ = myFunc3("he")

opsi-script: Local Functions

Beispiel5: Local Functions in opsi-script

[actions]
DefVar $mystr$

DefFunc myFunc4($str1$ : string) : string
        DefVar $locstr1$

        DefFunc myFunc5($str1$ : string) : string
                set $result$ = 'inner' + $str1$
        endfunc

        set $locstr1$ = '123'
        set $result$ = $str1$ + myFunc5($locstr1$)
endfunc

set $mystr$ = myFunc4("outer")

opsi-script: Local Functions

Beispiel6: Local Functions in opsi-script

[actions]
DefStringlist $list1$
DefFunc myFunc8($str1$ : string) : stringlist
        DefStringlist $loclist1$
        set $loclist1$ = getoutstreamfromsection("shellInAnIcon_test")
        set $result$ = $loclist1$

        [shellinanicon_test]
        set -x
        $str1$
endfunc
if GetOS = 'Linux'
        set $list1$ = myFunc8('set -x ; pwd')
else
        set $list1$ = myFunc8('echo %cd%')
endif

opsi-script: Local Functions

Beispiel6: Erwartete Ergebnisse:

Linux:

$list1$ = [pwd, /home/uib/gitwork/lazarus/opsi-script]

Windows:

The value of the variable "$list1$" is now:
(string   0)
(string   1)W:\opsi-script-test\CLIENT_DATA\standalone-tests>echo W:\opsi-script-test\CLIENT_DATA\standalone-tests
(string   2)W:\opsi-script-test\CLIENT_DATA\standalone-tests

opsi-script: Libraries of Local Functions

Importlib

Syntax

`importLib` <string expr>  ; import library // since 4.12.0.0
<string expr> : <file name>[.<file extension>][`::`<function name>]
Wenn keine '.<file extension>' (Dateierweiterung übergeben wird, so wird `.opsiscript` als Default verwendet.
Wenn kein '::<function name>' über geben wird, so werden alle Funktionen der angegebenen Datei importiert.

opsi-script: Libraries of Local Functions

Importlib Erläuterung

opsi-script: Libraries of Local Functions

Importlib Beispiel

Die Library Datei myfirstlib.opsiscript:

DefFunc myFunc(val $str1$ : string, $str2$ : string) : string
        set $result$ = $str1$ + $str2$
endfunc

opsi-script: Libraries of Local Functions

Importlib Beispiel

Das Programm:

[actions]
DefVar $mystr$
DefVar $str1$

importLib "%scriptpath%\myfirstlib.opsiscript"

set $str1$ = 'ha'


set $mystr$ = myFunc("he","ho")
set $mystr$ = myFunc("he",timeStampAsFloatStr)
set $mystr$ = myFunc("he",$str1$)

opsi-script: Libraries of Local Functions

Importlib Beispiel Varianten

Die Zeile
importLib "%scriptpath%\myfirstlib.opsiscript"
könnte auch folgende Form haben:

opsi-script: Libraries of Local Functions

opsi-script: Local Functions / Libraries: Missing Features (Roadmap)

opsi-script: UIB Library of Local Functions

opsi-script Library im opsi-winst Paket

Seit opsi-script 4.12.0.13 enthält das Unterverzeichnis lib Librarydateien welche von Standard opsi Produkten verwendet werden:

Diese Library wird direkt von uib gepflegt und dient hauptsächlich für interne Zwecke.

Project: Community driven opsi.org Library of Local Functions

Wir starten hiermit den Aufbau einer öffentlichen opsi-script Bibliothek die zum Austauch innerhalb der opsi Community dienen soll

Übersicht und Anforderungen

Project: Community driven opsi.org Library of Local Functions

Struktur: Gliederung in Dateien nach Funktionsgruppen

Namespace

Namespace:

Ob und wie sollen die Funktionen aus dieser Library am Namen erkennbar sein ?
z.B. opsi als Post- oder Prefix ?

Project: Community driven opsi.org Library of Local Functions

Dokumentation der Funktionen

Damit Funktionen einer Library auch verwendet werden, müssen sie nach Funktion und Syntax auffindbar sein.
D.h. sie müssen dokumentiert und in einer zentralen Dokumentation aufgefürt sein. Dazu wird zur Zeit ein Werkzeug entwickelt, welches auf Basis von Kommentaren innerhalb der Funktion eine Dokumentation in den Formaten HTML, PDF, ASCIIDOC erstellen kann.

Project: Community driven opsi.org Library of Local Functions

Zentrale Versionskontrolle, Bereitstellung und Download

Wir planen die Bereitstellung der Library in unserem öffentlichen Versionskontrollsystem GIT.
Zur Verteilung soll die Library natürlich auch als opsi-Paket Bereitgestellt werden

Test der Funktionen

Für die Funktionen müssen Tests bereit stehen:

/

#