opsi-script on Linux or macOS

Introduction

As of version 4.11.4 there is a Linux port of opsi-script.

As of version 4.12.1 there is a macOS port of opsi-script.

Conditionally to the progress on porting and the differences between Linux, Windows and macOS not all functionalities are available for all operating systems.

In the following section the availability is marked as:

  • [W/L/M] may be used on Windows, Linux and macOS as well

  • [W] Windows only

  • [L] Linux only

  • [M] macOS only

Important differences and hints

'opsi-script.exe' is at Windows a GUI application which may be started with the parameter /silent also without a GUI.

opsi-script is at Linux and macOS command line version which can be started without any access to a graphical display. Nevertheless this program starts a test if a access to a graphical display is possible and (if it is) starts the GUI version 'opsi-script-gui'. This feature may be suppressed by calling opsi-script with the parameter -silent.

'opsi-script-gui' is a graphical version which can not be started without access to a graphical display.

At Linux and macOS the parameter delimiter is not "/" but "-". So instead of calling opsi-script /help you should call opsi-script -help at Linux and macOS.

opsi-script path at Linux

Since opsi-client-agent 4.2 you will find all components of the opsi-script program at /opt/opsi-script/.

Before opsi-client-agent 4.2:

  • executable programs:
    /usr/bin/opsi-script
    /usr/bin/opsi-script-nogui

  • logfiles directories:
    if running with root privileges: /var/log/opsi-script
    if not running with root privileges: /tmp

  • language files:
    /usr/share/locale

  • skin files:
    Default = /usr/share/opsi-script/skin
    Custom = /usr/share/opsi-script/customskin

  • opsi-script library files:
    /usr/share/opsi-script/lib

Independent of the version:

  • logfiles directories:
    if running with root privileges: /var/log/opsi-script
    if not running with root privileges: /tmp

  • config files:
    /etc/opsi-script

opsi-script path at macOS

You will find all components of the opsi-script program at /Applications/opsi-script/.

  • logfiles directories:
    if running with root privileges: /var/log/opsi-script
    if not running with root privileges: /tmp

  • config files:
    /etc/opsi-script

Path handling in opsi-script

As of version 4.11.4 for all functions that expect a path as argument, the path string is converted to a valid path for the actual operating system. This means that all path delimiters will be set OS specific. For example a path string like /home/opsiproduct\myproduct\CLIENT_DATA will be on Linux converted to /home/opsiproduct/myproduct/CLIENT_DATA. Therefore it is not possible to handle files that have a backslash in their name.

Linux specific functions

For Linux support there are the following special functions:

  • GetOS // 'Linux' or 'Windows_NT' or 'macos' [W/L/M] GetOS

  • getLinuxDistroType // 'debian' or 'redhat' or 'suse' [L] GetOSgetLinuxDistroType

  • getLinuxVersionMap [L] getLinuxVersionMap

  • chmod in Files sections [L/M] xref:prim-section.adoc#chmod>>

  • waitForPackageLock(<wait_seconds>,<abort_on_timeout>`) : bool` waitForPackageLock

In the following chapters are some commands presented, that are useful to install software on Linux. These commands are part of the opsi-script library uib_lin_install.

For an overview we start to explain the different approaches of these commands.

  • distribution independent commands

    • cleanupPackageSystem

    • installupdates

  • Installation of one or more packages from an online repo for one specific distribution. (This is what you wnt to do if you have only one distribution in your organization)
    These command take a stringlist with the name of the packages to install as argument. If you want to install only one package you may use createStringList(<package name>) instead of $packagelist$.
    The given package names must match to your distribution. You have to choose the command that matches your distribution family.

    • debinstall($packagelist$ : stringlist) : string //since 4.12.4 [L]

    • redinstall($packagelist$ : stringlist) : string //since 4.12.4 [L]

    • suseinstall($packagelist$ : stringlist) : string //since 4.12.4 [L]

    • ucsinstall($packagelist$ : stringlist) : string //since 4.12.4 [L]

  • Installation / uninstall of one or more packages from an online repo for one specific distribution. This command is distribution independent.

    • genericLinInstall($packagelist$ : stringlist) : string

    • linuxRemoveOnePackage($packagename$ : string) : string

    • linuxInstallOneFile($packagefile$ : string) : string

  • Installation / check / uninstall of one package from an online repo for different distributions. Therefor this one package may have different names in different distributions. All these different names are part of the $packagelist$ argument. This command is distribution independent.

    • linuxInstallOneOf($packagelist$ : stringlist) : string

    • isOneInstalled($packagelist$ : stringlist) : string

    • linuxRemoveOneOf($packagelist$ : stringlist) : string

The details to these library commands you will find here: Documentation of opsi library: uib_lin_install.opsiscript

References to some mor Linux specific library function you will find at: Linux specific functions

Example scripts for Linux

Run on Linux only

[Actions]
DefVar $OS$

set $OS$ = GetOS

if not ($OS$ = "Linux")
	logError "Installation aborted: wrong OS version: only Linux allowed"
	isFatalError "wrong OS"
endif

Which Linux Version

[Actions]
DefVar $distCodeName$
DefVar $distroName$
DefVar $distRelease$
DefVar $distrotype$


DefStringList $linuxInfo$

set $distrotype$ = getLinuxDistroType
set $linuxInfo$ = getLinuxVersionMap
set $distCodeName$ = getValue("Codename", $linuxInfo$)
set $distRelease$ = getValue("Release", $linuxInfo$)
set $distroName$  = getValue("Distributor ID", $linuxInfo$)
Table 1. getLinuxVersionMap Result Examples
Distro Distributor ID Release Codename Description

Ubuntu Focal

Ubuntu

20.04

focal

Debian 8

Debian

8.3

jessie

Debian GNU/Linux 8.3 (jessie)

openSUSE Leap 42.1

SUSE LINUX

42.1

n/a

openSUSE Leap 42.1 (x86_64)

SLES12SP1

SUSE LINUX

12.1

n/a

SUSE Linux Enterprise Server 12 SP1

CentOS 7.0

CentOS

7.0.1406

Core

CentOS Linux release 7.0.1406 (Core)

RedHat 7.0

RedHatEnterpriseServer

7.0

Maipo

Red Hat Enterprise Linux Server release 7.0 (Maipo)

UCS 4.1

Univention

4.1-1 errata122

Vahr

Univention Corporate Server 4.1-1 errata122 (Vahr)

ShellScript call

[Actions]

ShellScript_ls

[ShellScript_ls]
set -x
ls
exit $?

It’s always a good idea to start with set -x for more information in the log and to set the PATH. You should end with exit $? so that the exitcode of the last call is the exitcode of the section.

Add a repository

Ubuntu / Debian
[Actions]
DefVar $newrepo$

set $newrepo$ = "deb http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/Debian_7.0/ ./"

comment "Method 1: use add-apt-repository ..."
ShellScript_add_rep_deb
ShellScript_add_repokey_deb
comment "Method 2: use add-apt-repository ..."
PatchTextFile_add_repo_deb "/etc/apt/sources.list"
ShellScript_add_repokey_deb

[ShellScript_add_rep_deb]
set -x
export DEBIAN_FRONTEND=noninteractive
apt-get --yes --force-yes install software-properties-common
apt-get --yes --force-yes install python-software-properties
add-apt-repository '$newrepo$'
exit $?

[PatchTextFile_add_repo_deb]
FindLine_StartingWith "$newrepo$"
DeleteTheLine
GoToBottom
InsertLine "$newrepo$"

[ShellScript_add_repokey_deb]
set -x
wget --no-check-certificate -O - $newrepo$/Release.key | apt-key add -
apt-get update
exit $?
SUSE
[Actions]
DefVar $newrepo$

set $newrepo$ = "http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/openSUSE_13.1/home:uibmz:opsi:opsi40.repo"

ShellScript_add_opsi_repository_suse

[ShellScript_add_opsi_repository_suse]
set -x
zypper --no-gpg-checks --non-interactive --gpg-auto-import-keys ar --refresh $newrepo$
zypper --no-gpg-checks --non-interactive --gpg-auto-import-keys refresh
exit $?
CentOS / Redhat
[Actions]
DefVar $newrepo$

set $newrepo$ = "http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/CentOS_7/home:uibmz:opsi:opsi40.repo"

comment "Method 1: use wget ..."
ShellScript_add_repo_redhat
ShellScript_refresh_repo_redhat
comment "Method 2: use PatchTextFile ..."
PatchTextFile_add_repo_redhat "/etc/yum.repos.d/mynew.repo"
ShellScript_refresh_repo_redhat

ShellScript_add_repo_redhat

[ShellScript_add_repo_redhat]
set -x
yum -y install wget
cd /etc/yum.repos.d
wget --no-check-certificate $newrepo$
exit $?

[PatchTextFile_add_repo_redhat]
AppendLine "[home_uibmz_opsi_opsi40]"
AppendLine "name=opsi 4.0 (CentOS_7)"
AppendLine "type=rpm-md"
AppendLine "baseurl=http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/CentOS_7/"
AppendLine "gpgcheck=1"
AppendLine "gpgkey=http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/CentOS_7/repodata/repomd.xml.key"
AppendLine "enabled=1"

[ShellScript_refresh_repo_redhat]
set -x
yum makecache
yum -y repolist
exit $?

Delete a repository

Ubuntu / Debian
[Actions]
DefVar $delrepo$
DefStringlist = $resultlist$

set $delrepo$ = "deb http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/Debian_7.0/ ./"

if LineBeginning_ExistsIn($delrepo$, "/etc/apt/sources.list")
	PatchTextFile_del_repo_deb  "/etc/apt/sources.list"
	set $resultlist$ = shellCall("apt-get update")
endif

[PatchTextFile_del_repo_deb]
FindLine_StartingWith "$delrepo$"
DeleteTheLine
SUSE
[Actions]
DefVar $delrepo$

comment "$delrepo$ is the section name of the repo file in /etc/zypp/repos.d/"
comment "$delrepo$ can be found by zypper lr"
set $delrepo$ = "home_uibmz_opsi_opsi40"
ShellScript_del_opsi_repository_suse

[ShellScript_del_opsi_repository_suse]
set -x
zypper --non-interactive rr  $delrepo$
exit $?
CentOS / Redhat
[Actions]
DefVar $delrepo$

comment "$delrepo$ ist the name of the repo file in /etc/yum.repos.d"
set $delrepo$ = "/etc/yum.repos.d/home:uibmz:opsi:opsi40.repo"

[ShellScript_del_opsi_repository_redhat]
set -x
rm $delrepo$
yum makecache
yum -y repolist
exit $?

Installing a package

Generic for all supported distributions

A simple example:

[Actions]
importlib "uib_lin_install"

DefStringlist $packages$
DefVar $installresult$

comment "install new needed packages"
if waitForPackageLock("300", "false")
	comment "we got the package lock."
else
	LogError "could not get Package Lock"
endif

set $packages$ = CreateStringlist("lsb-release","cifs-utils","xterm")
set $installresult$ = genericLinInstall($packages$)
if not(stringtobool($installresult$))
	LogError "failed install packages"
	Message "failed install packages"
	isFatalError "failed dependent packages"
endif

A more sophisticated example:

[Actions]
importlib "uib_lin_install"

DefStringlist $packages$
DefVar $installresult$
DefStringlist $errorList$
DefVar $fatal_error$
DefVar $result_string$

if waitForPackageLock("300", "false")
	comment "we got the package lock."
else
	LogError "could not get Package Lock"
endif

comment "update and clean package system"
cleanupPackageSystem()

comment "install pending updates"
set $result_string$ = installupdates()

comment "install new needed packages"
set $packages$ = CreateStringlist("lsb-release","cifs-utils","xterm")
set $installresult$ = genericLinInstall($packages$)
if not(stringtobool($installresult$))
	if waitForPackageLock("300", "false")
		comment "we got the package lock."
	else
		LogError "could not get Package Lock"
	endif
	cleanupPackageSystem()
	set $installresult$ = genericLinInstall($packages$)
	if not(stringtobool($installresult$))
		LogError "failed install packages"
		Message "failed install packages"
		;isFatalError "failed install packages"
		set $fatal_error$ = "true"
		set $errorList$ = addtolist($errorList$, " failed install packages")
	endif
endif

macOS specific functions

For macOS support there are the following special functions:

  • GetOS // 'Linux' or 'Windows_NT' or 'macos' [W/L/M] GetOS

  • getMacosVersionInfo [M] getMacosVersionInfo

  • getMacosVersionMap [M] getMacosVersionMap

  • getOSArchitecture // 'x86_32' or 'x86_64' or 'arm_64' [W/L/M] getOSArchitecture

  • chmod in Files sections [L/M] xref:prim-section.adoc#chmod>>

  • importlib "uib_macosinstalllib" :

  • install_macos_app($myapp$ : string) : string [M]

  • install_macos_pkg($mypkg$ : string) : string [M]

  • install_macos_dmg($mydmg$ : string) : string [M]

  • install_macos_zip($myzip$ : string) : string [M]

  • install_macos_generic($myfile$ : string) : string [M]

The details to these library commands you will find here: Documentation of opsi library: uib_macosinstalllib.opsiscript

References to more macOS specific library functions you will find at: macOS specific functions

Example scripts for macOS

Run on macOS only

[Actions]
DefVar $OS$

set $OS$ = GetOS

if not ($OS$ = "macos")
	logError "Installation aborted: wrong OS version: only macOS allowed"
	isFatalError "wrong OS"
endif

Which macOS Version

The code:

Set  $macosinfomap$ = getMacosVersionMap

gives (for example) the log:

The value of the variable "$macosinfomap$" is now:
(string   0)Release=11.0
(string   1)Build=20A5364e
(string   2)kernel name=Darwin
(string   3)node name=vmmac1100onmm1.uib.local
(string   4)kernel release=20.1.0
(string   5)kernel version=Darwin Kernel Version 20.1.0: Fri Aug 28 20:45:30 PDT 2020; root:xnu-7195.40.65.0.2~61/RELEASE_X86_64
(string   6)machine=x86_64
(string   7)processor=i386
(string   8)operating system=macOS