diff --git a/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz b/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz new file mode 100644 index 0000000..c1090a4 Binary files /dev/null and b/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz differ diff --git a/backup_proxmox_dump.py b/backup_proxmox_dump.py new file mode 100644 index 0000000..96056a8 --- /dev/null +++ b/backup_proxmox_dump.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +# +# (c) Rene Hadler, iteas IT Services GmbH +# rene.hadler@iteas.at +# www.iteas.at +# + +import os +import sys +import re +import subprocess + +if len(sys.argv) < 4 or len(sys.argv) > 5: + print("Nicht genĂĽgend Argumente: %s " % (sys.argv[0])) + sys.exit(0) + +backup_count = int(sys.argv[1]) +dump_dir = sys.argv[2] +backup_dir = sys.argv[3] + +# Find unique ids +id_list = [] +re_id_match = re.compile(r"^vzdump\-(qemu|lxc)\-([0-9]{3})\-.*$") +for file in os.listdir(dump_dir): + res = re_id_match.search(file) + if res != None: + file_id = res.group(2) + if file_id not in id_list: + id_list.append(file_id) + +id_list = sorted(id_list) + +for id in id_list: + fp = os.popen("ls -t %s/vzdump*%s*lzo | head -n%s " % (dump_dir, id, backup_count), "r") + files = [os.path.basename(x).strip() for x in fp.readlines()] + for file in files: + cmd_cp = "rsync -av %s %s" % (dump_dir + "/" + file, backup_dir + "/.") + print(cmd_cp) + subprocess.call(cmd_cp, shell=True) \ No newline at end of file diff --git a/config/nano.tar b/config/nano.tar new file mode 100644 index 0000000..cf80d49 Binary files /dev/null and b/config/nano.tar differ diff --git a/config/zshrc_root b/config/zshrc_root new file mode 100644 index 0000000..a39f2cc --- /dev/null +++ b/config/zshrc_root @@ -0,0 +1,3310 @@ +# Filename: /etc/zsh/zshrc +# Purpose: config file for zsh (z shell) +# Authors: grml-team (grml.org), (c) Michael Prokop +# Bug-Reports: see http://grml.org/bugs/ +# License: This file is licensed under the GPL v2. +################################################################################ +# This file is sourced only for interactive shells. It +# should contain commands to set up aliases, functions, +# options, key bindings, etc. +# +# Global Order: zshenv, zprofile, zshrc, zlogin +################################################################################ + +# USAGE +# If you are using this file as your ~/.zshrc file, please use ~/.zshrc.pre +# and ~/.zshrc.local for your own customisations. The former file is read +# before ~/.zshrc, the latter is read after it. Also, consider reading the +# refcard and the reference manual for this setup, both available from: +# + +# Contributing: +# If you want to help to improve grml's zsh setup, clone the grml-etc-core +# repository from git.grml.org: +# git clone git://git.grml.org/grml-etc-core.git +# +# Make your changes, commit them; use 'git format-patch' to create a series +# of patches and send those to the following address via 'git send-email': +# grml-etc-core@grml.org +# +# Doing so makes sure the right people get your patches for review and +# possibly inclusion. + +# zsh-refcard-tag documentation: +# You may notice strange looking comments in this file. +# These are there for a purpose. grml's zsh-refcard can now be +# automatically generated from the contents of the actual configuration +# file. However, we need a little extra information on which comments +# and what lines of code to take into account (and for what purpose). +# +# Here is what they mean: +# +# List of tags (comment types) used: +# #a# Next line contains an important alias, that should +# be included in the grml-zsh-refcard. +# (placement tag: @@INSERT-aliases@@) +# #f# Next line contains the beginning of an important function. +# (placement tag: @@INSERT-functions@@) +# #v# Next line contains an important variable. +# (placement tag: @@INSERT-variables@@) +# #k# Next line contains an important keybinding. +# (placement tag: @@INSERT-keybindings@@) +# #d# Hashed directories list generation: +# start denotes the start of a list of 'hash -d' +# definitions. +# end denotes its end. +# (placement tag: @@INSERT-hasheddirs@@) +# #A# Abbreviation expansion list generation: +# start denotes the beginning of abbreviations. +# end denotes their end. +# Lines within this section that end in '#d .*' provide +# extra documentation to be included in the refcard. +# (placement tag: @@INSERT-abbrev@@) +# #m# This tag allows you to manually generate refcard entries +# for code lines that are hard/impossible to parse. +# Example: +# #m# k ESC-h Call the run-help function +# That would add a refcard entry in the keybindings table +# for 'ESC-h' with the given comment. +# So the syntax is: #m#
+# #o# This tag lets you insert entries to the 'other' hash. +# Generally, this should not be used. It is there for +# things that cannot be done easily in another way. +# (placement tag: @@INSERT-other-foobar@@) +# +# All of these tags (except for m and o) take two arguments, the first +# within the tag, the other after the tag: +# +# #
# +# +# Where
is really just a number, which are defined by the +# @secmap array on top of 'genrefcard.pl'. The reason for numbers +# instead of names is, that for the reader, the tag should not differ +# much from a regular comment. For zsh, it is a regular comment indeed. +# The numbers have got the following meanings: +# 0 -> "default" +# 1 -> "system" +# 2 -> "user" +# 3 -> "debian" +# 4 -> "search" +# 5 -> "shortcuts" +# 6 -> "services" +# +# So, the following will add an entry to the 'functions' table in the +# 'system' section, with a (hopefully) descriptive comment: +# #f1# Edit an alias via zle +# edalias() { +# +# It will then show up in the @@INSERT-aliases-system@@ replacement tag +# that can be found in 'grml-zsh-refcard.tex.in'. +# If the section number is omitted, the 'default' section is assumed. +# Furthermore, in 'grml-zsh-refcard.tex.in' @@INSERT-aliases@@ is +# exactly the same as @@INSERT-aliases-default@@. If you want a list of +# *all* aliases, for example, use @@INSERT-aliases-all@@. + +# zsh profiling +# just execute 'ZSH_PROFILE_RC=1 zsh' and run 'zprof' to get the details +if [[ $ZSH_PROFILE_RC -gt 0 ]] ; then + zmodload zsh/zprof +fi + +# load .zshrc.pre to give the user the chance to overwrite the defaults +[[ -r ${ZDOTDIR:-${HOME}}/.zshrc.pre ]] && source ${ZDOTDIR:-${HOME}}/.zshrc.pre + +# check for version/system +# check for versions (compatibility reasons) +is4(){ + [[ $ZSH_VERSION == <4->* ]] && return 0 + return 1 +} + +is41(){ + [[ $ZSH_VERSION == 4.<1->* || $ZSH_VERSION == <5->* ]] && return 0 + return 1 +} + +is42(){ + [[ $ZSH_VERSION == 4.<2->* || $ZSH_VERSION == <5->* ]] && return 0 + return 1 +} + +is425(){ + [[ $ZSH_VERSION == 4.2.<5->* || $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0 + return 1 +} + +is43(){ + [[ $ZSH_VERSION == 4.<3->* || $ZSH_VERSION == <5->* ]] && return 0 + return 1 +} + +is433(){ + [[ $ZSH_VERSION == 4.3.<3->* || $ZSH_VERSION == 4.<4->* \ + || $ZSH_VERSION == <5->* ]] && return 0 + return 1 +} + +is437(){ + [[ $ZSH_VERSION == 4.3.<7->* || $ZSH_VERSION == 4.<4->* \ + || $ZSH_VERSION == <5->* ]] && return 0 + return 1 +} + +is439(){ + [[ $ZSH_VERSION == 4.3.<9->* || $ZSH_VERSION == 4.<4->* \ + || $ZSH_VERSION == <5->* ]] && return 0 + return 1 +} + +#f1# Checks whether or not you're running grml +isgrml(){ + [[ -f /etc/grml_version ]] && return 0 + return 1 +} + +#f1# Checks whether or not you're running a grml cd +isgrmlcd(){ + [[ -f /etc/grml_cd ]] && return 0 + return 1 +} + +if isgrml ; then +#f1# Checks whether or not you're running grml-small + isgrmlsmall() { + if [[ ${${${(f)"$( autologin +# Thanks go to Bart Schaefer! +isgrml && checkhome() { + if [[ -z "$ALREADY_DID_CD_HOME" ]] ; then + export ALREADY_DID_CD_HOME=$HOME + cd + fi +} + +# check for zsh v3.1.7+ + +if ! [[ ${ZSH_VERSION} == 3.1.<7->* \ + || ${ZSH_VERSION} == 3.<2->.<->* \ + || ${ZSH_VERSION} == <4->.<->* ]] ; then + + printf '-!-\n' + printf '-!- In this configuration we try to make use of features, that only\n' + printf '-!- require version 3.1.7 of the shell; That way this setup can be\n' + printf '-!- used with a wide range of zsh versions, while using fairly\n' + printf '-!- advanced features in all supported versions.\n' + printf '-!-\n' + printf '-!- However, you are running zsh version %s.\n' "$ZSH_VERSION" + printf '-!-\n' + printf '-!- While this *may* work, it might as well fail.\n' + printf '-!- Please consider updating to at least version 3.1.7 of zsh.\n' + printf '-!-\n' + printf '-!- DO NOT EXPECT THIS TO WORK FLAWLESSLY!\n' + printf '-!- If it does today, you'\''ve been lucky.\n' + printf '-!-\n' + printf '-!- Ye been warned!\n' + printf '-!-\n' + + function zstyle() { : } +fi + +# autoload wrapper - use this one instead of autoload directly +# We need to define this function as early as this, because autoloading +# 'is-at-least()' needs it. +function zrcautoload() { + emulate -L zsh + setopt extended_glob + local fdir ffile + local -i ffound + + ffile=$1 + (( ffound = 0 )) + for fdir in ${fpath} ; do + [[ -e ${fdir}/${ffile} ]] && (( ffound = 1 )) + done + + (( ffound == 0 )) && return 1 + if [[ $ZSH_VERSION == 3.1.<6-> || $ZSH_VERSION == <4->* ]] ; then + autoload -U ${ffile} || return 1 + else + autoload ${ffile} || return 1 + fi + return 0 +} + +# Load is-at-least() for more precise version checks Note that this test will +# *always* fail, if the is-at-least function could not be marked for +# autoloading. +zrcautoload is-at-least || is-at-least() { return 1 } + +# set some important options (as early as possible) + +# append history list to the history file; this is the default but we make sure +# because it's required for share_history. +setopt append_history + +# import new commands from the history file also in other zsh-session +is4 && setopt share_history + +# save each command's beginning timestamp and the duration to the history file +setopt extended_history + +# If a new command line being added to the history list duplicates an older +# one, the older command is removed from the list +is4 && setopt histignorealldups + +# remove command lines from the history list when the first character on the +# line is a space +setopt histignorespace + +# if a command is issued that can't be executed as a normal command, and the +# command is the name of a directory, perform the cd command to that directory. +setopt auto_cd + +# in order to use #, ~ and ^ for filename generation grep word +# *~(*.gz|*.bz|*.bz2|*.zip|*.Z) -> searches for word not in compressed files +# don't forget to quote '^', '~' and '#'! +setopt extended_glob + +# display PID when suspending processes as well +setopt longlistjobs + +# try to avoid the 'zsh: no matches found...' +setopt nonomatch + +# report the status of backgrounds jobs immediately +setopt notify + +# whenever a command completion is attempted, make sure the entire command path +# is hashed first. +setopt hash_list_all + +# not just at the end +setopt completeinword + +# Don't send SIGHUP to background processes when the shell exits. +setopt nohup + +# make cd push the old directory onto the directory stack. +setopt auto_pushd + +# avoid "beep"ing +setopt nobeep + +# don't push the same dir twice. +setopt pushd_ignore_dups + +# * shouldn't match dotfiles. ever. +setopt noglobdots + +# use zsh style word splitting +setopt noshwordsplit + +# don't error out when unset parameters are used +setopt unset + +# setting some default values +NOCOR=${NOCOR:-0} +NOMENU=${NOMENU:-0} +NOPRECMD=${NOPRECMD:-0} +COMMAND_NOT_FOUND=${COMMAND_NOT_FOUND:-0} +GRML_ZSH_CNF_HANDLER=${GRML_ZSH_CNF_HANDLER:-/usr/share/command-not-found/command-not-found} +BATTERY=${BATTERY:-0} +GRMLSMALL_SPECIFIC=${GRMLSMALL_SPECIFIC:-1} +ZSH_NO_DEFAULT_LOCALE=${ZSH_NO_DEFAULT_LOCALE:-0} + +typeset -ga ls_options +typeset -ga grep_options +if ls --help 2> /dev/null | grep -q GNU; then + ls_options=( --color=auto ) +elif [[ $OSTYPE == freebsd* ]]; then + ls_options=( -G ) +fi +if grep --help 2> /dev/null | grep -q GNU || \ + [[ $OSTYPE == freebsd* ]]; then + grep_options=( --color=auto ) +fi + +# utility functions +# this function checks if a command exists and returns either true +# or false. This avoids using 'which' and 'whence', which will +# avoid problems with aliases for which on certain weird systems. :-) +# Usage: check_com [-c|-g] word +# -c only checks for external commands +# -g does the usual tests and also checks for global aliases +check_com() { + emulate -L zsh + local -i comonly gatoo + + if [[ $1 == '-c' ]] ; then + (( comonly = 1 )) + shift + elif [[ $1 == '-g' ]] ; then + (( gatoo = 1 )) + else + (( comonly = 0 )) + (( gatoo = 0 )) + fi + + if (( ${#argv} != 1 )) ; then + printf 'usage: check_com [-c] \n' >&2 + return 1 + fi + + if (( comonly > 0 )) ; then + [[ -n ${commands[$1]} ]] && return 0 + return 1 + fi + + if [[ -n ${commands[$1]} ]] \ + || [[ -n ${functions[$1]} ]] \ + || [[ -n ${aliases[$1]} ]] \ + || [[ -n ${reswords[(r)$1]} ]] ; then + + return 0 + fi + + if (( gatoo > 0 )) && [[ -n ${galiases[$1]} ]] ; then + return 0 + fi + + return 1 +} + +# creates an alias and precedes the command with +# sudo if $EUID is not zero. +salias() { + emulate -L zsh + local only=0 ; local multi=0 + local key val + while [[ $1 == -* ]] ; do + case $1 in + (-o) only=1 ;; + (-a) multi=1 ;; + (--) shift ; break ;; + (-h) + printf 'usage: salias [-h|-o|-a] \n' + printf ' -h shows this help text.\n' + printf ' -a replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n' + printf ' be careful using this option.\n' + printf ' -o only sets an alias if a preceding sudo would be needed.\n' + return 0 + ;; + (*) printf "unkown option: '%s'\n" "$1" ; return 1 ;; + esac + shift + done + + if (( ${#argv} > 1 )) ; then + printf 'Too many arguments %s\n' "${#argv}" + return 1 + fi + + key="${1%%\=*}" ; val="${1#*\=}" + if (( EUID == 0 )) && (( only == 0 )); then + alias -- "${key}=${val}" + elif (( EUID > 0 )) ; then + (( multi > 0 )) && val="${val// ; / ; sudo }" + alias -- "${key}=sudo ${val}" + fi + + return 0 +} + +# a "print -l ${(u)foo}"-workaround for pre-4.2.0 shells +# usage: uprint foo +# Where foo is the *name* of the parameter you want printed. +# Note that foo is no typo; $foo would be wrong here! +if ! is42 ; then + uprint () { + emulate -L zsh + local -a u + local w + local parameter=$1 + + if [[ -z ${parameter} ]] ; then + printf 'usage: uprint \n' + return 1 + fi + + for w in ${(P)parameter} ; do + [[ -z ${(M)u:#$w} ]] && u=( $u $w ) + done + + builtin print -l $u + } +fi + +# Check if we can read given files and source those we can. +xsource() { + if (( ${#argv} < 1 )) ; then + printf 'usage: xsource FILE(s)...\n' >&2 + return 1 + fi + + while (( ${#argv} > 0 )) ; do + [[ -r "$1" ]] && source "$1" + shift + done + return 0 +} + +# Check if we can read a given file and 'cat(1)' it. +xcat() { + emulate -L zsh + if (( ${#argv} != 1 )) ; then + printf 'usage: xcat FILE\n' >&2 + return 1 + fi + + [[ -r $1 ]] && cat $1 + return 0 +} + +# Remove these functions again, they are of use only in these +# setup files. This should be called at the end of .zshrc. +xunfunction() { + emulate -L zsh + local -a funcs + funcs=(salias xcat xsource xunfunction zrcautoload zrcautozle) + for func in $funcs ; do + [[ -n ${functions[$func]} ]] \ + && unfunction $func + done + return 0 +} + +# this allows us to stay in sync with grml's zshrc and put own +# modifications in ~/.zshrc.local +zrclocal() { + xsource "/etc/zsh/zshrc.local" + xsource "${ZDOTDIR:-${HOME}}/.zshrc.local" + return 0 +} + +# locale setup +if (( ZSH_NO_DEFAULT_LOCALE == 0 )); then + xsource "/etc/default/locale" +fi + +for var in LANG LC_ALL LC_MESSAGES ; do + [[ -n ${(P)var} ]] && export $var +done + +xsource "/etc/sysconfig/keyboard" + +TZ=$(xcat /etc/timezone) + +# set some variables +if check_com -c vim ; then +#v# + export EDITOR=${EDITOR:-vim} +else + export EDITOR=${EDITOR:-vi} +fi + +#v# +export PAGER=${PAGER:-less} + +#v# +export MAIL=${MAIL:-/var/mail/$USER} + +# if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/ +export SHELL='/bin/zsh' + +# color setup for ls: +check_com -c dircolors && eval $(dircolors -b) +# color setup for ls on OS X / FreeBSD: +isdarwin && export CLICOLOR=1 +isfreebsd && export CLICOLOR=1 + +# do MacPorts setup on darwin +if isdarwin && [[ -d /opt/local ]]; then + # Note: PATH gets set in /etc/zprofile on Darwin, so this can't go into + # zshenv. + PATH="/opt/local/bin:/opt/local/sbin:$PATH" + MANPATH="/opt/local/share/man:$MANPATH" +fi +# do Fink setup on darwin +isdarwin && xsource /sw/bin/init.sh + +# load our function and completion directories +for fdir in /usr/share/grml/zsh/completion /usr/share/grml/zsh/functions; do + fpath=( ${fdir} ${fdir}/**/*(/N) ${fpath} ) + if [[ ${fdir} == '/usr/share/grml/zsh/functions' ]] ; then + for func in ${fdir}/**/[^_]*[^~](N.) ; do + zrcautoload ${func:t} + done + fi +done +unset fdir func + +# support colors in less +export LESS_TERMCAP_mb=$'\E[01;31m' +export LESS_TERMCAP_md=$'\E[01;31m' +export LESS_TERMCAP_me=$'\E[0m' +export LESS_TERMCAP_se=$'\E[0m' +export LESS_TERMCAP_so=$'\E[01;44;33m' +export LESS_TERMCAP_ue=$'\E[0m' +export LESS_TERMCAP_us=$'\E[01;32m' + +# mailchecks +MAILCHECK=30 + +# report about cpu-/system-/user-time of command if running longer than +# 5 seconds +REPORTTIME=5 + +# watch for everyone but me and root +watch=(notme root) + +# automatically remove duplicates from these arrays +typeset -U path cdpath fpath manpath + +# Load a few modules +is4 && \ +for mod in parameter complist deltochar mathfunc ; do + zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :(" +done + +# autoload zsh modules when they are referenced +if is4 ; then + zmodload -a zsh/stat zstat + zmodload -a zsh/zpty zpty + zmodload -ap zsh/mapfile mapfile +fi + +# completion system +if zrcautoload compinit ; then + compinit || print 'Notice: no compinit available :(' +else + print 'Notice: no compinit available :(' + function compdef { } +fi + +# completion system + +# called later (via is4 && grmlcomp) +# note: use 'zstyle' for getting current settings +# press ^xh (control-x h) for getting tags in context; ^x? (control-x ?) to run complete_debug with trace output +grmlcomp() { + # TODO: This could use some additional information + + # Make sure the completion system is initialised + (( ${+_comps} )) || return 1 + + # allow one error for every three characters typed in approximate completer + zstyle ':completion:*:approximate:' max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' + + # don't complete backup files as executables + zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)' + + # start menu completion only if it could find no unambiguous initial string + zstyle ':completion:*:correct:*' insert-unambiguous true + zstyle ':completion:*:corrections' format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' + zstyle ':completion:*:correct:*' original true + + # activate color-completion + zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS} + + # format on completion + zstyle ':completion:*:descriptions' format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}' + + # automatically complete 'cd -' and 'cd -' with menu + # zstyle ':completion:*:*:cd:*:directory-stack' menu yes select + + # insert all expansions for expand completer + zstyle ':completion:*:expand:*' tag-order all-expansions + zstyle ':completion:*:history-words' list false + + # activate menu + zstyle ':completion:*:history-words' menu yes + + # ignore duplicate entries + zstyle ':completion:*:history-words' remove-all-dups yes + zstyle ':completion:*:history-words' stop yes + + # match uppercase from lowercase + zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' + + # separate matches into groups + zstyle ':completion:*:matches' group 'yes' + zstyle ':completion:*' group-name '' + + if [[ "$NOMENU" -eq 0 ]] ; then + # if there are more than 5 options allow selecting from a menu + zstyle ':completion:*' menu select=5 + else + # don't use any menus at all + setopt no_auto_menu + fi + + zstyle ':completion:*:messages' format '%d' + zstyle ':completion:*:options' auto-description '%d' + + # describe options in full + zstyle ':completion:*:options' description 'yes' + + # on processes completion complete all user processes + zstyle ':completion:*:processes' command 'ps -au$USER' + + # offer indexes before parameters in subscripts + zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters + + # provide verbose completion information + zstyle ':completion:*' verbose true + + # recent (as of Dec 2007) zsh versions are able to provide descriptions + # for commands (read: 1st word in the line) that it will list for the user + # to choose from. The following disables that, because it's not exactly fast. + zstyle ':completion:*:-command-:*:' verbose false + + # set format for warnings + zstyle ':completion:*:warnings' format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' + + # define files to ignore for zcompile + zstyle ':completion:*:*:zcompile:*' ignored-patterns '(*~|*.zwc)' + zstyle ':completion:correct:' prompt 'correct to: %e' + + # Ignore completion functions for commands you don't have: + zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*' + + # Provide more processes in completion of programs like killall: + zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq' + + # complete manual by their section + zstyle ':completion:*:manuals' separate-sections true + zstyle ':completion:*:manuals.*' insert-sections true + zstyle ':completion:*:man:*' menu yes select + + # Search path for sudo completion + zstyle ':completion:*:sudo:*' command-path /usr/local/sbin \ + /usr/local/bin \ + /usr/sbin \ + /usr/bin \ + /sbin \ + /bin \ + /usr/X11R6/bin + + # provide .. as a completion + zstyle ':completion:*' special-dirs .. + + # run rehash on completion so new installed program are found automatically: + _force_rehash() { + (( CURRENT == 1 )) && rehash + return 1 + } + + ## correction + # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it + if [[ "$NOCOR" -gt 0 ]] ; then + zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored + setopt nocorrect + else + # try to be smart about when to use what completer... + setopt correct + zstyle -e ':completion:*' completer ' + if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then + _last_try="$HISTNO$BUFFER$CURSOR" + reply=(_complete _match _ignored _prefix _files) + else + if [[ $words[1] == (rm|mv) ]] ; then + reply=(_complete _files) + else + reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files) + fi + fi' + fi + + # command for process lists, the local web server details and host completion + zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html' + + # caching + [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \ + zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/ + + # host completion + if is42 ; then + [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=() + [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(, Bernhard Tittelbach +beginning-or-end-of-somewhere() { + local hno=$HISTNO + if [[ ( "${LBUFFER[-1]}" == $'\n' && "${WIDGET}" == beginning-of* ) || \ + ( "${RBUFFER[1]}" == $'\n' && "${WIDGET}" == end-of* ) ]]; then + zle .${WIDGET:s/somewhere/buffer-or-history/} "$@" + else + zle .${WIDGET:s/somewhere/line-hist/} "$@" + if (( HISTNO != hno )); then + zle .${WIDGET:s/somewhere/buffer-or-history/} "$@" + fi + fi +} +zle -N beginning-of-somewhere beginning-or-end-of-somewhere +zle -N end-of-somewhere beginning-or-end-of-somewhere + +## toggle the ,. abbreviation feature on/off +# NOABBREVIATION: default abbreviation-state +# 0 - enabled (default) +# 1 - disabled +NOABBREVIATION=${NOABBREVIATION:-0} + +grml_toggle_abbrev() { + if (( ${NOABBREVIATION} > 0 )) ; then + NOABBREVIATION=0 + else + NOABBREVIATION=1 + fi +} +zle -N grml_toggle_abbrev + +# add a command line to the shells history without executing it +commit-to-history() { + print -s ${(z)BUFFER} + zle send-break +} +zle -N commit-to-history + +# only slash should be considered as a word separator: +slash-backward-kill-word() { + local WORDCHARS="${WORDCHARS:s@/@}" + # zle backward-word + zle backward-kill-word +} +zle -N slash-backward-kill-word + +# a generic accept-line wrapper + +# This widget can prevent unwanted autocorrections from command-name +# to _command-name, rehash automatically on enter and call any number +# of builtin and user-defined widgets in different contexts. +# +# For a broader description, see: +# +# +# The code is imported from the file 'zsh/functions/accept-line' from +# , which +# distributed under the same terms as zsh itself. + +# A newly added command will may not be found or will cause false +# correction attempts, if you got auto-correction set. By setting the +# following style, we force accept-line() to rehash, if it cannot +# find the first word on the command line in the $command[] hash. +zstyle ':acceptline:*' rehash true + +function Accept-Line() { + setopt localoptions noksharrays + local -a subs + local -xi aldone + local sub + local alcontext=${1:-$alcontext} + + zstyle -a ":acceptline:${alcontext}" actions subs + + (( ${#subs} < 1 )) && return 0 + + (( aldone = 0 )) + for sub in ${subs} ; do + [[ ${sub} == 'accept-line' ]] && sub='.accept-line' + zle ${sub} + + (( aldone > 0 )) && break + done +} + +function Accept-Line-getdefault() { + emulate -L zsh + local default_action + + zstyle -s ":acceptline:${alcontext}" default_action default_action + case ${default_action} in + ((accept-line|)) + printf ".accept-line" + ;; + (*) + printf ${default_action} + ;; + esac +} + +function Accept-Line-HandleContext() { + zle Accept-Line + + default_action=$(Accept-Line-getdefault) + zstyle -T ":acceptline:${alcontext}" call_default \ + && zle ${default_action} +} + +function accept-line() { + setopt localoptions noksharrays + local -ax cmdline + local -x alcontext + local buf com fname format msg default_action + + alcontext='default' + buf="${BUFFER}" + cmdline=(${(z)BUFFER}) + com="${cmdline[1]}" + fname="_${com}" + + Accept-Line 'preprocess' + + zstyle -t ":acceptline:${alcontext}" rehash \ + && [[ -z ${commands[$com]} ]] \ + && rehash + + if [[ -n ${com} ]] \ + && [[ -n ${reswords[(r)$com]} ]] \ + || [[ -n ${aliases[$com]} ]] \ + || [[ -n ${functions[$com]} ]] \ + || [[ -n ${builtins[$com]} ]] \ + || [[ -n ${commands[$com]} ]] ; then + + # there is something sensible to execute, just do it. + alcontext='normal' + Accept-Line-HandleContext + + return + fi + + if [[ -o correct ]] \ + || [[ -o correctall ]] \ + && [[ -n ${functions[$fname]} ]] ; then + + # nothing there to execute but there is a function called + # _command_name; a completion widget. Makes no sense to + # call it on the commandline, but the correct{,all} options + # will ask for it nevertheless, so warn the user. + if [[ ${LASTWIDGET} == 'accept-line' ]] ; then + # Okay, we warned the user before, he called us again, + # so have it his way. + alcontext='force' + Accept-Line-HandleContext + + return + fi + + if zstyle -t ":acceptline:${alcontext}" nocompwarn ; then + alcontext='normal' + Accept-Line-HandleContext + else + # prepare warning message for the user, configurable via zstyle. + zstyle -s ":acceptline:${alcontext}" compwarnfmt msg + + if [[ -z ${msg} ]] ; then + msg="%c will not execute and completion %f exists." + fi + + zformat -f msg "${msg}" "c:${com}" "f:${fname}" + + zle -M -- "${msg}" + fi + return + elif [[ -n ${buf//[$' \t\n']##/} ]] ; then + # If we are here, the commandline contains something that is not + # executable, which is neither subject to _command_name correction + # and is not empty. might be a variable assignment + alcontext='misc' + Accept-Line-HandleContext + + return + fi + + # If we got this far, the commandline only contains whitespace, or is empty. + alcontext='empty' + Accept-Line-HandleContext +} + +zle -N accept-line +zle -N Accept-Line +zle -N Accept-Line-HandleContext + +# power completion - abbreviation expansion +# power completion / abbreviation expansion / buffer expansion +# see http://zshwiki.org/home/examples/zleiab for details +# less risky than the global aliases but powerful as well +# just type the abbreviation key and afterwards ',.' to expand it +declare -A abk +setopt extendedglob +setopt interactivecomments +abk=( +# key # value (#d additional doc string) +#A# start + '...' '../..' + '....' '../../..' + 'BG' '& exit' + 'C' '| wc -l' + 'G' '|& grep '${grep_options:+"${grep_options[*]}"} + 'H' '| head' + 'Hl' ' --help |& less -r' #d (Display help in pager) + 'L' '| less' + 'LL' '|& less -r' + 'M' '| most' + 'N' '&>/dev/null' #d (No Output) + 'R' '| tr A-z N-za-m' #d (ROT13) + 'SL' '| sort | less' + 'S' '| sort -u' + 'T' '| tail' + 'V' '|& vim -' +#A# end + 'co' './configure && make && sudo make install' +) + +zleiab() { + emulate -L zsh + setopt extendedglob + local MATCH + + if (( NOABBREVIATION > 0 )) ; then + LBUFFER="${LBUFFER},." + return 0 + fi + + LBUFFER=${LBUFFER%%(#m)[.\-+:|_a-zA-Z0-9]#} + LBUFFER+=${abk[$MATCH]:-$MATCH} +} + +zle -N zleiab + +help-show-abk() +{ + zle -M "$(print "Type ,. after these abbreviations to expand them:"; print -a -C 2 ${(kv)abk})" +} + +zle -N help-show-abk + +# press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd +insert-datestamp() { LBUFFER+=${(%):-'%D{%Y-%m-%d}'}; } +zle -N insert-datestamp + +# press esc-m for inserting last typed word again (thanks to caphuso!) +insert-last-typed-word() { zle insert-last-word -- 0 -1 }; +zle -N insert-last-typed-word; + +function grml-zsh-fg() { + if (( ${#jobstates} )); then + zle .push-input + [[ -o hist_ignore_space ]] && BUFFER=' ' || BUFFER='' + BUFFER="${BUFFER}fg" + zle .accept-line + else + zle -M 'No background jobs. Doing nothing.' + fi +} +zle -N grml-zsh-fg + +# run command line as user root via sudo: +sudo-command-line() { + [[ -z $BUFFER ]] && zle up-history + if [[ $BUFFER != sudo\ * ]]; then + BUFFER="sudo $BUFFER" + CURSOR=$(( CURSOR+5 )) + fi +} +zle -N sudo-command-line + +### jump behind the first word on the cmdline. +### useful to add options. +function jump_after_first_word() { + local words + words=(${(z)BUFFER}) + + if (( ${#words} <= 1 )) ; then + CURSOR=${#BUFFER} + else + CURSOR=${#${words[1]}} + fi +} +zle -N jump_after_first_word + +#f5# Create directory under cursor or the selected area +inplaceMkDirs() { + # Press ctrl-xM to create the directory under the cursor or the selected area. + # To select an area press ctrl-@ or ctrl-space and use the cursor. + # Use case: you type "mv abc ~/testa/testb/testc/" and remember that the + # directory does not exist yet -> press ctrl-XM and problem solved + local PATHTOMKDIR + if ((REGION_ACTIVE==1)); then + local F=$MARK T=$CURSOR + if [[ $F -gt $T ]]; then + F=${CURSOR} + T=${MARK} + fi + # get marked area from buffer and eliminate whitespace + PATHTOMKDIR=${BUFFER[F+1,T]%%[[:space:]]##} + PATHTOMKDIR=${PATHTOMKDIR##[[:space:]]##} + else + local bufwords iword + bufwords=(${(z)LBUFFER}) + iword=${#bufwords} + bufwords=(${(z)BUFFER}) + PATHTOMKDIR="${(Q)bufwords[iword]}" + fi + [[ -z "${PATHTOMKDIR}" ]] && return 1 + PATHTOMKDIR=${~PATHTOMKDIR} + if [[ -e "${PATHTOMKDIR}" ]]; then + zle -M " path already exists, doing nothing" + else + zle -M "$(mkdir -p -v "${PATHTOMKDIR}")" + zle end-of-line + fi +} + +#k# mkdir -p from string under cursor or marked area +zle -N inplaceMkDirs + +#v1# set number of lines to display per page +HELP_LINES_PER_PAGE=20 +#v1# set location of help-zle cache file +HELP_ZLE_CACHE_FILE=~/.cache/zsh_help_zle_lines.zsh +# helper function for help-zle, actually generates the help text +help_zle_parse_keybindings() +{ + emulate -L zsh + setopt extendedglob + unsetopt ksharrays #indexing starts at 1 + + #v1# choose files that help-zle will parse for keybindings + ((${+HELPZLE_KEYBINDING_FILES})) || HELPZLE_KEYBINDING_FILES=( /etc/zsh/zshrc ~/.zshrc.pre ~/.zshrc ~/.zshrc.local ) + + if [[ -r $HELP_ZLE_CACHE_FILE ]]; then + local load_cache=0 + for f ($HELPZLE_KEYBINDING_FILES) [[ $f -nt $HELP_ZLE_CACHE_FILE ]] && load_cache=1 + [[ $load_cache -eq 0 ]] && . $HELP_ZLE_CACHE_FILE && return + fi + + #fill with default keybindings, possibly to be overwriten in a file later + #Note that due to zsh inconsistency on escaping assoc array keys, we encase the key in '' which we will remove later + local -A help_zle_keybindings + help_zle_keybindings['@']="set MARK" + help_zle_keybindings['xj']="vi-join lines" + help_zle_keybindings['xb']="jump to matching brace" + help_zle_keybindings['xu']="undo" + help_zle_keybindings['_']="undo" + help_zle_keybindings['xf']="find in cmdline" + help_zle_keybindings['a']="goto beginning of line" + help_zle_keybindings['e']="goto end of line" + help_zle_keybindings['t']="transpose charaters" + help_zle_keybindings['t']="transpose words" + help_zle_keybindings['s']="spellcheck word" + help_zle_keybindings['k']="backward kill buffer" + help_zle_keybindings['u']="forward kill buffer" + help_zle_keybindings['y']="insert previously killed word/string" + help_zle_keybindings["'"]="quote line" + help_zle_keybindings['"']="quote from mark to cursor" + help_zle_keybindings['']="repeat next cmd/char times (-10a -> -10 times 'a')" + help_zle_keybindings['u']="make next word Uppercase" + help_zle_keybindings['l']="make next word lowercase" + help_zle_keybindings['xd']="preview expansion under cursor" + help_zle_keybindings['q']="push current CL into background, freeing it. Restore on next CL" + help_zle_keybindings['.']="insert (and interate through) last word from prev CLs" + help_zle_keybindings[',']="complete word from newer history (consecutive hits)" + help_zle_keybindings['m']="repeat last typed word on current CL" + help_zle_keybindings['v']="insert next keypress symbol literally (e.g. for bindkey)" + help_zle_keybindings['!!:n*']="insert last n arguments of last command" + help_zle_keybindings['!!:n-']="insert arguments n..N-2 of last command (e.g. mv s s d)" + help_zle_keybindings['h']="show help/manpage for current command" + + #init global variables + unset help_zle_lines help_zle_sln + typeset -g -a help_zle_lines + typeset -g help_zle_sln=1 + + local k v + local lastkeybind_desc contents #last description starting with #k# that we found + local num_lines_elapsed=0 #number of lines between last description and keybinding + #search config files in the order they a called (and thus the order in which they overwrite keybindings) + for f in $HELPZLE_KEYBINDING_FILES; do + [[ -r "$f" ]] || continue #not readable ? skip it + contents="$(<$f)" + for cline in "${(f)contents}"; do + #zsh pattern: matches lines like: #k# .............. + if [[ "$cline" == (#s)[[:space:]]#\#k\#[[:space:]]##(#b)(*)[[:space:]]#(#e) ]]; then + lastkeybind_desc="$match[*]" + num_lines_elapsed=0 + #zsh pattern: matches lines that set a keybinding using bindkey or compdef -k + # ignores lines that are commentend out + # grabs first in '' or "" enclosed string with length between 1 and 6 characters + elif [[ "$cline" == [^#]#(bindkey|compdef -k)[[:space:]](*)(#b)(\"((?)(#c1,6))\"|\'((?)(#c1,6))\')(#B)(*) ]]; then + #description prevously found ? description not more than 2 lines away ? keybinding not empty ? + if [[ -n $lastkeybind_desc && $num_lines_elapsed -lt 2 && -n $match[1] ]]; then + #substitute keybinding string with something readable + k=${${${${${${${match[1]/\\e\^h/}/\\e\^\?/}/\\e\[5~/}/\\e\[6~/}//(\\e|\^\[)/}//\^/}/3~/} + #put keybinding in assoc array, possibly overwriting defaults or stuff found in earlier files + #Note that we are extracting the keybinding-string including the quotes (see Note at beginning) + help_zle_keybindings[${k}]=$lastkeybind_desc + fi + lastkeybind_desc="" + else + ((num_lines_elapsed++)) + fi + done + done + unset contents + #calculate length of keybinding column + local kstrlen=0 + for k (${(k)help_zle_keybindings[@]}) ((kstrlen < ${#k})) && kstrlen=${#k} + #convert the assoc array into preformated lines, which we are able to sort + for k v in ${(kv)help_zle_keybindings[@]}; do + #pad keybinding-string to kstrlen chars and remove outermost characters (i.e. the quotes) + help_zle_lines+=("${(r:kstrlen:)k[2,-2]}${v}") + done + #sort lines alphabetically + help_zle_lines=("${(i)help_zle_lines[@]}") + [[ -d ${HELP_ZLE_CACHE_FILE:h} ]] || mkdir -p "${HELP_ZLE_CACHE_FILE:h}" + echo "help_zle_lines=(${(q)help_zle_lines[@]})" >| $HELP_ZLE_CACHE_FILE + zcompile $HELP_ZLE_CACHE_FILE +} +typeset -g help_zle_sln +typeset -g -a help_zle_lines + +# Provides (partially autogenerated) help on keybindings and the zsh line editor +help-zle() +{ + emulate -L zsh + unsetopt ksharrays #indexing starts at 1 + #help lines already generated ? no ? then do it + [[ ${+functions[help_zle_parse_keybindings]} -eq 1 ]] && {help_zle_parse_keybindings && unfunction help_zle_parse_keybindings} + #already displayed all lines ? go back to the start + [[ $help_zle_sln -gt ${#help_zle_lines} ]] && help_zle_sln=1 + local sln=$help_zle_sln + #note that help_zle_sln is a global var, meaning we remember the last page we viewed + help_zle_sln=$((help_zle_sln + HELP_LINES_PER_PAGE)) + zle -M "${(F)help_zle_lines[sln,help_zle_sln-1]}" +} +zle -N help-zle + +## complete word from currently visible Screen or Tmux buffer. +if check_com -c screen || check_com -c tmux; then + _complete_screen_display() { + [[ "$TERM" != "screen" ]] && return 1 + + local TMPFILE=$(mktemp) + local -U -a _screen_display_wordlist + trap "rm -f $TMPFILE" EXIT + + # fill array with contents from screen hardcopy + if ((${+TMUX})); then + #works, but crashes tmux below version 1.4 + #luckily tmux -V option to ask for version, was also added in 1.4 + tmux -V &>/dev/null || return + tmux -q capture-pane \; save-buffer -b 0 $TMPFILE \; delete-buffer -b 0 + else + screen -X hardcopy $TMPFILE + # screen sucks, it dumps in latin1, apparently always. so recode it + # to system charset + check_com recode && recode latin1 $TMPFILE + fi + _screen_display_wordlist=( ${(QQ)$(<$TMPFILE)} ) + # remove PREFIX to be completed from that array + _screen_display_wordlist[${_screen_display_wordlist[(i)$PREFIX]}]="" + compadd -a _screen_display_wordlist + } + #m# k CTRL-x\,\,\,S Complete word from GNU screen buffer + bindkey -r "^xS" + compdef -k _complete_screen_display complete-word '^xS' +fi + +# Load a few more functions and tie them to widgets, so they can be bound: + +function zrcautozle() { + emulate -L zsh + local fnc=$1 + zrcautoload $fnc && zle -N $fnc +} + +function zrcgotwidget() { + (( ${+widgets[$1]} )) +} + +function zrcgotkeymap() { + [[ -n ${(M)keymaps:#$1} ]] +} + +zrcautozle insert-files +zrcautozle edit-command-line +zrcautozle insert-unicode-char +if zrcautoload history-search-end; then + zle -N history-beginning-search-backward-end history-search-end + zle -N history-beginning-search-forward-end history-search-end +fi +zle -C hist-complete complete-word _generic +zstyle ':completion:hist-complete:*' completer _history + +# The actual terminal setup hooks and bindkey-calls: + +# An array to note missing features to ease diagnosis in case of problems. +typeset -ga grml_missing_features + +function zrcbindkey() { + if (( ARGC )) && zrcgotwidget ${argv[-1]}; then + bindkey "$@" + fi +} + +function bind2maps () { + local i sequence widget + local -a maps + + while [[ "$1" != "--" ]]; do + maps+=( "$1" ) + shift + done + shift + + if [[ "$1" == "-s" ]]; then + shift + sequence="$1" + else + sequence="${key[$1]}" + fi + widget="$2" + + [[ -z "$sequence" ]] && return 1 + + for i in "${maps[@]}"; do + zrcbindkey -M "$i" "$sequence" "$widget" + done +} + +if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then + function zle-smkx () { + emulate -L zsh + printf '%s' ${terminfo[smkx]} + } + function zle-rmkx () { + emulate -L zsh + printf '%s' ${terminfo[rmkx]} + } + function zle-line-init () { + zle-smkx + } + function zle-line-finish () { + zle-rmkx + } + zle -N zle-line-init + zle -N zle-line-finish +else + for i in {s,r}mkx; do + (( ${+terminfo[$i]} )) || grml_missing_features+=($i) + done + unset i +fi + +typeset -A key +key=( + Home "${terminfo[khome]}" + End "${terminfo[kend]}" + Insert "${terminfo[kich1]}" + Delete "${terminfo[kdch1]}" + Up "${terminfo[kcuu1]}" + Down "${terminfo[kcud1]}" + Left "${terminfo[kcub1]}" + Right "${terminfo[kcuf1]}" + PageUp "${terminfo[kpp]}" + PageDown "${terminfo[knp]}" + BackTab "${terminfo[kcbt]}" +) + +# Guidelines for adding key bindings: +# +# - Do not add hardcoded escape sequences, to enable non standard key +# combinations such as Ctrl-Meta-Left-Cursor. They are not easily portable. +# +# - Adding Ctrl characters, such as '^b' is okay; note that '^b' and '^B' are +# the same key. +# +# - All keys from the $key[] mapping are obviously okay. +# +# - Most terminals send "ESC x" when Meta-x is pressed. Thus, sequences like +# '\ex' are allowed in here as well. + +bind2maps emacs -- Home beginning-of-somewhere +bind2maps viins vicmd -- Home vi-beginning-of-line +bind2maps emacs -- End end-of-somewhere +bind2maps viins vicmd -- End vi-end-of-line +bind2maps emacs viins -- Insert overwrite-mode +bind2maps vicmd -- Insert vi-insert +bind2maps emacs -- Delete delete-char +bind2maps viins vicmd -- Delete vi-delete-char +bind2maps emacs viins vicmd -- Up up-line-or-search +bind2maps emacs viins vicmd -- Down down-line-or-search +bind2maps emacs -- Left backward-char +bind2maps viins vicmd -- Left vi-backward-char +bind2maps emacs -- Right forward-char +bind2maps viins vicmd -- Right vi-forward-char +bind2maps viins vicmd -- Right vi-forward-char +#k# Display list of abbreviations that expand when followed by ,. +bind2maps emacs viins -- -s ',.' zleiab +bind2maps emacs viins -- -s '^xb' help-show-abk +bind2maps emacs viins -- -s '^xM' inplaceMkDirs +#k# display help for keybindings and ZLE +bind2maps emacs viins -- -s '^xz' help-zle +#k# Insert files and test globbing +bind2maps emacs viins -- -s "^xf" insert-files +#k# Edit the current line in \kbd{\$EDITOR} +bind2maps emacs viins -- -s '\ee' edit-command-line +#k# search history backward for entry beginning with typed text +bind2maps emacs viins -- -s '^xp' history-beginning-search-backward-end +#k# search history forward for entry beginning with typed text +bind2maps emacs viins -- -s '^xP' history-beginning-search-forward-end +#k# search history backward for entry beginning with typed text +bind2maps emacs viins -- PageUp history-beginning-search-backward-end +#k# search history forward for entry beginning with typed text +bind2maps emacs viins -- PageDown history-beginning-search-forward-end +#k# Toggle abbreviation expansion on/off +bind2maps emacs viins -- -s '^xA' grml_toggle_abbrev +bind2maps emacs viins -- -s "^x^h" commit-to-history +#k# Kill left-side word or everything up to next slash +bind2maps emacs viins -- -s '\ev' slash-backward-kill-word +#k# Kill left-side word or everything up to next slash +bind2maps emacs viins -- -s '\e^h' slash-backward-kill-word +#k# Kill left-side word or everything up to next slash +bind2maps emacs viins -- -s '\e^?' slash-backward-kill-word +# Do history expansion on space: +bind2maps emacs viins -- -s ' ' magic-space +#k# Trigger menu-complete +bind2maps emacs viins -- -s '\ei' menu-complete # menu completion via esc-i +#k# Insert a timestamp on the command line (yyyy-mm-dd) +bind2maps emacs viins -- -s '^ed' insert-datestamp +#k# Insert last typed word +bind2maps emacs viins -- -s "\em" insert-last-typed-word +#k# A smart shortcut for \kbd{fg} +bind2maps emacs viins -- -s '^z' grml-zsh-fg +#k# prepend the current command with "sudo" +bind2maps emacs viins -- -s "^os" sudo-command-line +#k# jump to after first word (for adding options) +bind2maps emacs viins -- -s '^x1' jump_after_first_word +#k# complete word from history with menu +bind2maps emacs viins -- -s "^x^x" hist-complete + +# insert unicode character +# usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an § +# See for example http://unicode.org/charts/ for unicode characters code +#k# Insert Unicode character +bind2maps emacs viins -- -s '^xi' insert-unicode-char + +# use the new *-pattern-* widgets for incremental history search +if zrcgotwidget history-incremental-pattern-search-backward; then + for seq wid in '^r' history-incremental-pattern-search-backward \ + '^s' history-incremental-pattern-search-forward + do + bind2maps emacs viins vicmd -- -s $seq $wid + done +fi + +if zrcgotkeymap menuselect; then + #m# k Shift-tab Perform backwards menu completion + bind2maps menuselect -- BackTab reverse-menu-complete + + #k# menu selection: pick item but stay in the menu + bind2maps menuselect -- -s '\e^M' accept-and-menu-complete + # also use + and INSERT since it's easier to press repeatedly + bind2maps menuselect -- -s '+' accept-and-menu-complete + bind2maps menuselect -- Insert accept-and-menu-complete + + # accept a completion and try to complete again by using menu + # completion; very useful with completing directories + # by using 'undo' one's got a simple file browser + bind2maps menuselect -- -s '^o' accept-and-infer-next-history +fi + +# Finally, here are still a few hardcoded escape sequences; Special sequences +# like Ctrl- etc do suck a fair bit, because they are not +# standardised and most of the time are not available in a terminals terminfo +# entry. +# +# While we do not encourage adding bindings like these, we will keep these for +# backward compatibility. + +## use Ctrl-left-arrow and Ctrl-right-arrow for jumping to word-beginnings on +## the command line. +# URxvt sequences: +bind2maps emacs viins vicmd -- -s '\eOc' forward-word +bind2maps emacs viins vicmd -- -s '\eOd' backward-word +# These are for xterm: +bind2maps emacs viins vicmd -- -s '\e[1;5C' forward-word +bind2maps emacs viins vicmd -- -s '\e[1;5D' backward-word +## the same for alt-left-arrow and alt-right-arrow +# URxvt again: +bind2maps emacs viins vicmd -- -s '\e\e[C' forward-word +bind2maps emacs viins vicmd -- -s '\e\e[D' backward-word +# Xterm again: +bind2maps emacs viins vicmd -- -s '^[[1;3C' forward-word +bind2maps emacs viins vicmd -- -s '^[[1;3D' backward-word +# Also try ESC Left/Right: +bind2maps emacs viins vicmd -- -s '\e'${key[Right]} forward-word +bind2maps emacs viins vicmd -- -s '\e'${key[Left]} backward-word + +# autoloading + +zrcautoload zmv +zrcautoload zed + +# we don't want to quote/espace URLs on our own... +# if autoload -U url-quote-magic ; then +# zle -N self-insert url-quote-magic +# zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}=' +# else +# print 'Notice: no url-quote-magic available :(' +# fi +alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic' + +#m# k ESC-h Call \kbd{run-help} for the 1st word on the command line +alias run-help >&/dev/null && unalias run-help +for rh in run-help{,-git,-svk,-svn}; do + zrcautoload $rh +done; unset rh + +# command not found handling + +(( ${COMMAND_NOT_FOUND} == 1 )) && +function command_not_found_handler() { + emulate -L zsh + if [[ -x ${GRML_ZSH_CNF_HANDLER} ]] ; then + ${GRML_ZSH_CNF_HANDLER} $1 + fi + return 1 +} + +# history + +ZSHDIR=${ZDOTDIR:-${HOME}/.zsh} + +#v# +HISTFILE=${ZDOTDIR:-${HOME}}/.zsh_history +isgrmlcd && HISTSIZE=500 || HISTSIZE=5000 +isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history + +# dirstack handling + +DIRSTACKSIZE=${DIRSTACKSIZE:-20} +DIRSTACKFILE=${DIRSTACKFILE:-${ZDOTDIR:-${HOME}}/.zdirs} + +if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then + dirstack=( ${(f)"$(< $DIRSTACKFILE)"} ) + # "cd -" won't work after login by just setting $OLDPWD, so + [[ -d $dirstack[1] ]] && cd $dirstack[1] && cd $OLDPWD +fi + +chpwd() { + local -ax my_stack + my_stack=( ${PWD} ${dirstack} ) + if is42 ; then + builtin print -l ${(u)my_stack} >! ${DIRSTACKFILE} + else + uprint my_stack >! ${DIRSTACKFILE} + fi +} + +# directory based profiles + +if is433 ; then + +# chpwd_profiles(): Directory Profiles, Quickstart: +# +# In .zshrc.local: +# +# zstyle ':chpwd:profiles:/usr/src/grml(|/|/*)' profile grml +# zstyle ':chpwd:profiles:/usr/src/debian(|/|/*)' profile debian +# chpwd_profiles +# +# For details see the `grmlzshrc.5' manual page. +function chpwd_profiles() { + local profile context + local -i reexecute + + context=":chpwd:profiles:$PWD" + zstyle -s "$context" profile profile || profile='default' + zstyle -T "$context" re-execute && reexecute=1 || reexecute=0 + + if (( ${+parameters[CHPWD_PROFILE]} == 0 )); then + typeset -g CHPWD_PROFILE + local CHPWD_PROFILES_INIT=1 + (( ${+functions[chpwd_profiles_init]} )) && chpwd_profiles_init + elif [[ $profile != $CHPWD_PROFILE ]]; then + (( ${+functions[chpwd_leave_profile_$CHPWD_PROFILE]} )) \ + && chpwd_leave_profile_${CHPWD_PROFILE} + fi + if (( reexecute )) || [[ $profile != $CHPWD_PROFILE ]]; then + (( ${+functions[chpwd_profile_$profile]} )) && chpwd_profile_${profile} + fi + + CHPWD_PROFILE="${profile}" + return 0 +} + +chpwd_functions=( ${chpwd_functions} chpwd_profiles ) + +fi # is433 + +# Prompt setup for grml: + +# set colors for use in prompts (modern zshs allow for the use of %F{red}foo%f +# in prompts to get a red "foo" embedded, but it's good to keep these for +# backwards compatibility). +if zrcautoload colors && colors 2>/dev/null ; then + BLUE="%{${fg[blue]}%}" + RED="%{${fg_bold[red]}%}" + GREEN="%{${fg[green]}%}" + CYAN="%{${fg[cyan]}%}" + MAGENTA="%{${fg[magenta]}%}" + YELLOW="%{${fg[yellow]}%}" + WHITE="%{${fg[white]}%}" + NO_COLOR="%{${reset_color}%}" +else + BLUE=$'%{\e[1;34m%}' + RED=$'%{\e[1;31m%}' + GREEN=$'%{\e[1;32m%}' + CYAN=$'%{\e[1;36m%}' + WHITE=$'%{\e[1;37m%}' + MAGENTA=$'%{\e[1;35m%}' + YELLOW=$'%{\e[1;33m%}' + NO_COLOR=$'%{\e[0m%}' +fi + +# First, the easy ones: PS2..4: + +# secondary prompt, printed when the shell needs more information to complete a +# command. +PS2='\`%_> ' +# selection prompt used within a select loop. +PS3='?# ' +# the execution trace prompt (setopt xtrace). default: '+%N:%i>' +PS4='+%N:%i:%_> ' + +# Some additional features to use with our prompt: +# +# - battery status +# - debian_chroot +# - vcs_info setup and version specific fixes + +# display battery status on right side of prompt via running 'BATTERY=1 zsh' +if [[ $BATTERY -gt 0 ]] ; then + if ! check_com -c acpi ; then + BATTERY=0 + fi +fi + +battery() { +if [[ $BATTERY -gt 0 ]] ; then + PERCENT="${${"$(acpi 2>/dev/null)"}/(#b)[[:space:]]#Battery <->: [^0-9]##, (<->)%*/${match[1]}}" + if [[ -z "$PERCENT" ]] ; then + PERCENT='acpi not present' + else + if [[ "$PERCENT" -lt 20 ]] ; then + PERCENT="warning: ${PERCENT}%%" + else + PERCENT="${PERCENT}%%" + fi + fi +fi +} + +# set variable debian_chroot if running in a chroot with /etc/debian_chroot +if [[ -z "$debian_chroot" ]] && [[ -r /etc/debian_chroot ]] ; then + debian_chroot=$( ]] ; then + function VCS_INFO_realpath () { + setopt localoptions NO_shwordsplit chaselinks + ( builtin cd -q $1 2> /dev/null && pwd; ) + } + fi + + zstyle ':vcs_info:*' max-exports 2 + + if [[ -o restricted ]]; then + zstyle ':vcs_info:*' enable NONE + fi +fi + +# Change vcs_info formats for the grml prompt. The 2nd format sets up +# $vcs_info_msg_1_ to contain "zsh: repo-name" used to set our screen title. +# TODO: The included vcs_info() version still uses $VCS_INFO_message_N_. +# That needs to be the use of $VCS_INFO_message_N_ needs to be changed +# to $vcs_info_msg_N_ as soon as we use the included version. +if [[ "$TERM" == dumb ]] ; then + zstyle ':vcs_info:*' actionformats "(%s%)-[%b|%a] " "zsh: %r" + zstyle ':vcs_info:*' formats "(%s%)-[%b] " "zsh: %r" +else + # these are the same, just with a lot of colors: + zstyle ':vcs_info:*' actionformats "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOR} " \ + "zsh: %r" + zstyle ':vcs_info:*' formats "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOR}%} " \ + "zsh: %r" + zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat "%b${RED}:${YELLOW}%r" +fi + +# Now for the fun part: The grml prompt themes in `promptsys' mode of operation + +# This actually defines three prompts: +# +# - grml +# - grml-large +# - grml-chroot +# +# They all share the same code and only differ with respect to which items they +# contain. The main source of documentation is the `prompt_grml_help' function +# below, which gets called when the user does this: prompt -h grml + +function prompt_grml_help () { + cat <<__EOF0__ + prompt grml + + This is the prompt as used by the grml-live system . It is + a rather simple one-line prompt, that by default looks something like this: + + @ [ ]% + + The prompt itself integrates with zsh's prompt themes system (as you are + witnessing right now) and is configurable to a certain degree. In + particular, these aspects are customisable: + + - The items used in the prompt (e.g. you can remove \`user' from + the list of activated items, which will cause the user name to + be omitted from the prompt string). + + - The attributes used with the items are customisable via strings + used before and after the actual item. + + The available items are: at, battery, change-root, date, grml-chroot, + history, host, jobs, newline, path, percent, rc, rc-always, sad-smiley, + shell-level, time, user, vcs + + The actual configuration is done via zsh's \`zstyle' mechanism. The + context, that is used while looking up styles is: + + ':prompt:grml::' + + Here is either \`left' or \`right', signifying whether the + style should affect the left or the right prompt. is either + \`setup' or 'items:', where \`' is one of the available items. + + The styles: + + - use-rprompt (boolean): If \`true' (the default), print a sad smiley + in $RPROMPT if the last command a returned non-successful error code. + (This in only valid if is "right"; ignored otherwise) + + - items (list): The list of items used in the prompt. If \`vcs' is + present in the list, the theme's code invokes \`vcs_info' + accordingly. Default (left): rc change-root user at host path vcs + percent; Default (right): sad-smiley + + Available styles in 'items:' are: pre, post. These are strings that + are inserted before (pre) and after (post) the item in question. Thus, the + following would cause the user name to be printed in red instead of the + default blue: + + zstyle ':prompt:grml:*:items:user' pre '%F{red}' + + Note, that the \`post' style may remain at its default value, because its + default value is '%f', which turns the foreground text attribute off (which + is exactly, what is still required with the new \`pre' value). +__EOF0__ +} + +function prompt_grml-chroot_help () { + cat <<__EOF0__ + prompt grml-chroot + + This is a variation of the grml prompt, see: prompt -h grml + + The main difference is the default value of the \`items' style. The rest + behaves exactly the same. Here are the defaults for \`grml-chroot': + + - left: grml-chroot user at host path percent + - right: (empty list) +__EOF0__ +} + +function prompt_grml-large_help () { + cat <<__EOF0__ + prompt grml-large + + This is a variation of the grml prompt, see: prompt -h grml + + The main difference is the default value of the \`items' style. In + particular, this theme uses _two_ lines instead of one with the plain + \`grml' theme. The rest behaves exactly the same. Here are the defaults + for \`grml-large': + + - left: rc jobs history shell-level change-root time date newline user + at host path vcs percent + - right: sad-smiley +__EOF0__ +} + +function grml_prompt_setup () { + emulate -L zsh + autoload -Uz vcs_info + autoload -Uz add-zsh-hook + add-zsh-hook precmd prompt_$1_precmd +} + +function prompt_grml_setup () { + grml_prompt_setup grml +} + +function prompt_grml-chroot_setup () { + grml_prompt_setup grml-chroot +} + +function prompt_grml-large_setup () { + grml_prompt_setup grml-large +} + +# These maps define default tokens and pre-/post-decoration for items to be +# used within the themes. All defaults may be customised in a context sensitive +# matter by using zsh's `zstyle' mechanism. +typeset -gA grml_prompt_pre_default \ + grml_prompt_post_default \ + grml_prompt_token_default \ + grml_prompt_token_function + +grml_prompt_pre_default=( + at '' + battery ' ' + change-root '' + date '%F{blue}' + grml-chroot '%F{red}' + history '%F{green}' + host '' + jobs '%F{cyan}' + newline '' + path '%B' + percent '' + rc '%F{red}' + rc-always '' + sad-smiley '' + shell-level '%F{red}' + time '%F{blue}' + user '%B%F{blue}' + vcs '' +) + +grml_prompt_post_default=( + at '' + battery '' + change-root '' + date '%f' + grml-chroot '%f ' + history '%f' + host '' + jobs '%f' + newline '' + path '%b' + percent '' + rc '%f' + rc-always '' + sad-smiley '' + shell-level '%f' + time '%f' + user '%f%b' + vcs '' +) + +grml_prompt_token_default=( + at '@' + battery 'PERCENT' + change-root 'debian_chroot' + date '%D{%Y-%m-%d}' + grml-chroot 'GRML_CHROOT' + history '{history#%!} ' + host '%m ' + jobs '[%j running job(s)] ' + newline $'\n' + path '%40<..<%~%<< ' + percent '%# ' + rc '%(?..%? )' + rc-always '%?' + sad-smiley '%(?..:()' + shell-level '%(3L.+ .)' + time '%D{%H:%M:%S} ' + user '%n' + vcs '0' +) + +function GRML_theme_add_token_usage () { + cat <<__EOF__ + Usage: grml_theme_add_token [-f|-i] [
 ]
+
+     is the name for the newly added token. If the \`-f' or \`-i' options
+    are used,  is the name of the function (see below for
+    details). Otherwise it is the literal token string to be used. 
 and
+     are optional.
+
+  Options:
+
+    -f    Use a function named \`' each time the token
+                    is to be expanded.
+
+    -i    Use a function named \`' to initialise the
+                    value of the token _once_ at runtime.
+
+    The functions are called with one argument: the token's new name. The
+    return value is expected in the \$REPLY parameter. The use of these
+    options is mutually exclusive.
+
+  Example:
+
+    To add a new token \`day' that expands to the current weekday in the
+    current locale in green foreground colour, use this:
+
+      grml_theme_add_token day '%D{%A}' '%F{green}' '%f'
+
+    Another example would be support for \$VIRTUAL_ENV:
+
+      function virtual_env_prompt () {
+        REPLY=\${VIRTUAL_ENV+\${VIRTUAL_ENV:t} }
+      }
+      grml_theme_add_token virtual-env -f virtual_env_prompt
+
+    After that, you will be able to use a changed \`items' style to
+    assemble your prompt.
+__EOF__
+}
+
+function grml_theme_add_token () {
+    emulate -L zsh
+    local name token pre post
+    local -i init funcall
+
+    if (( ARGC == 0 )); then
+        GRML_theme_add_token_usage
+        return 0
+    fi
+
+    init=0
+    funcall=0
+    pre=''
+    post=''
+    name=$1
+    shift
+    if [[ $1 == '-f' ]]; then
+        funcall=1
+        shift
+    elif [[ $1 == '-i' ]]; then
+        init=1
+        shift
+    fi
+
+    if (( ARGC == 0 )); then
+        printf '
+grml_theme_add_token: No token-string/function-name provided!\n\n'
+        GRML_theme_add_token_usage
+        return 1
+    fi
+    token=$1
+    shift
+    if (( ARGC != 0 && ARGC != 2 )); then
+        printf '
+grml_theme_add_token: 
 and  need to by specified _both_!\n\n'
+        GRML_theme_add_token_usage
+        return 1
+    fi
+    if (( ARGC )); then
+        pre=$1
+        post=$2
+        shift 2
+    fi
+
+    if (( ${+grml_prompt_token_default[$name]} )); then
+        printf '
+grml_theme_add_token: Token `%s'\'' exists! Giving up!\n\n' $name
+        GRML_theme_add_token_usage
+        return 2
+    fi
+    if (( init )); then
+        $token $name
+        token=$REPLY
+    fi
+    grml_prompt_pre_default[$name]=$pre
+    grml_prompt_post_default[$name]=$post
+    if (( funcall )); then
+        grml_prompt_token_function[$name]=$token
+        grml_prompt_token_default[$name]=23
+    else
+        grml_prompt_token_default[$name]=$token
+    fi
+}
+
+function grml_typeset_and_wrap () {
+    emulate -L zsh
+    local target="$1"
+    local new="$2"
+    local left="$3"
+    local right="$4"
+
+    if (( ${+parameters[$new]} )); then
+        typeset -g "${target}=${(P)target}${left}${(P)new}${right}"
+    fi
+}
+
+function grml_prompt_addto () {
+    emulate -L zsh
+    local target="$1"
+    local lr it apre apost new v
+    local -a items
+    shift
+
+    [[ $target == PS1 ]] && lr=left || lr=right
+    zstyle -a ":prompt:${grmltheme}:${lr}:setup" items items || items=( "$@" )
+    typeset -g "${target}="
+    for it in "${items[@]}"; do
+        zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" pre apre \
+            || apre=${grml_prompt_pre_default[$it]}
+        zstyle -s ":prompt:grml:${grmltheme}:${lr}:$it" post apost \
+            || apost=${grml_prompt_post_default[$it]}
+        zstyle -s ":prompt:${grmltheme}:${lr}:items:$it" token new \
+            || new=${grml_prompt_token_default[$it]}
+        typeset -g "${target}=${(P)target}${apre}"
+        if (( ${+grml_prompt_token_function[$it]} )); then
+            ${grml_prompt_token_function[$it]} $it
+            typeset -g "${target}=${(P)target}${REPLY}"
+        else
+            case $it in
+            battery)
+                grml_typeset_and_wrap $target $new '' ''
+                ;;
+            change-root)
+                grml_typeset_and_wrap $target $new '(' ')'
+                ;;
+            grml-chroot)
+                if [[ -n ${(P)new} ]]; then
+                    typeset -g "${target}=${(P)target}(CHROOT)"
+                fi
+                ;;
+            vcs)
+                v="vcs_info_msg_${new}_"
+                if (( ! vcscalled )); then
+                    vcs_info
+                    vcscalled=1
+                fi
+                if (( ${+parameters[$v]} )) && [[ -n "${(P)v}" ]]; then
+                    typeset -g "${target}=${(P)target}${(P)v}"
+                fi
+                ;;
+            *) typeset -g "${target}=${(P)target}${new}" ;;
+            esac
+        fi
+        typeset -g "${target}=${(P)target}${apost}"
+    done
+}
+
+function prompt_grml_precmd () {
+    emulate -L zsh
+    local grmltheme=grml
+    local -a left_items right_items
+    left_items=(rc change-root user at host path vcs percent)
+    right_items=(sad-smiley)
+
+    prompt_grml_precmd_worker
+}
+
+function prompt_grml-chroot_precmd () {
+    emulate -L zsh
+    local grmltheme=grml-chroot
+    local -a left_items right_items
+    left_items=(grml-chroot user at host path percent)
+    right_items=()
+
+    prompt_grml_precmd_worker
+}
+
+function prompt_grml-large_precmd () {
+    emulate -L zsh
+    local grmltheme=grml-large
+    local -a left_items right_items
+    left_items=(rc jobs history shell-level change-root time date newline
+                user at host path vcs percent)
+    right_items=(sad-smiley)
+
+    prompt_grml_precmd_worker
+}
+
+function prompt_grml_precmd_worker () {
+    emulate -L zsh
+    local -i vcscalled=0
+
+    grml_prompt_addto PS1 "${left_items[@]}"
+    if zstyle -T ":prompt:${grmltheme}:right:setup" use-rprompt; then
+        grml_prompt_addto RPS1 "${right_items[@]}"
+    fi
+}
+
+grml_prompt_fallback() {
+    setopt prompt_subst
+    precmd() {
+        (( ${+functions[vcs_info]} )) && vcs_info
+    }
+
+    p0="${RED}%(?..%? )${WHITE}${debian_chroot:+($debian_chroot)}"
+    p1="${BLUE}%n${NO_COLOR}@%m %40<...<%B%~%b%<< "'${vcs_info_msg_0_}'"%# "
+    if (( EUID == 0 )); then
+        PROMPT="${BLUE}${p0}${RED}${p1}"
+    else
+        PROMPT="${RED}${p0}${BLUE}${p1}"
+    fi
+    unset p0 p1
+}
+
+if zrcautoload promptinit && promptinit 2>/dev/null ; then
+    # Since we define the required functions in here and not in files in
+    # $fpath, we need to stick the theme's name into `$prompt_themes'
+    # ourselves, since promptinit does not pick them up otherwise.
+    prompt_themes+=( grml grml-chroot grml-large )
+    # Also, keep the array sorted...
+    prompt_themes=( "${(@on)prompt_themes}" )
+else
+    print 'Notice: no promptinit available :('
+    grml_prompt_fallback
+fi
+
+if is437; then
+    # The prompt themes use modern features of zsh, that require at least
+    # version 4.3.7 of the shell. Use the fallback otherwise.
+    if [[ $BATTERY -gt 0 ]]; then
+        zstyle ':prompt:grml:right:setup' items sad-smiley battery
+        add-zsh-hook precmd battery
+    fi
+    if [[ "$TERM" == dumb ]] ; then
+        zstyle ":prompt:grml(|-large|-chroot):*:items:grml-chroot" pre ''
+        zstyle ":prompt:grml(|-large|-chroot):*:items:grml-chroot" post ' '
+        for i in rc user path jobs history date time shell-level; do
+            zstyle ":prompt:grml(|-large|-chroot):*:items:$i" pre ''
+            zstyle ":prompt:grml(|-large|-chroot):*:items:$i" post ''
+        done
+        unset i
+        zstyle ':prompt:grml(|-large|-chroot):right:setup' use-rprompt false
+    elif (( EUID == 0 )); then
+        zstyle ':prompt:grml(|-large|-chroot):*:items:user' pre '%B%F{red}'
+    fi
+
+    # Finally enable one of the prompts.
+    if [[ -n $GRML_CHROOT ]]; then
+        prompt grml-chroot
+    elif [[ $GRMLPROMPT -gt 0 ]]; then
+        prompt grml-large
+    else
+        prompt grml
+    fi
+else
+    grml_prompt_fallback
+fi
+
+# Terminal-title wizardry
+
+function ESC_print () {
+    info_print $'\ek' $'\e\\' "$@"
+}
+function set_title () {
+    info_print  $'\e]0;' $'\a' "$@"
+}
+
+function info_print () {
+    local esc_begin esc_end
+    esc_begin="$1"
+    esc_end="$2"
+    shift 2
+    printf '%s' ${esc_begin}
+    printf '%s' "$*"
+    printf '%s' "${esc_end}"
+}
+
+function grml_reset_screen_title () {
+    # adjust title of xterm
+    # see http://www.faqs.org/docs/Linux-mini/Xterm-Title.html
+    [[ ${NOTITLE:-} -gt 0 ]] && return 0
+    case $TERM in
+        (xterm*|rxvt*)
+            set_title ${(%):-"%n@%m: %~"}
+            ;;
+    esac
+}
+
+function grml_vcs_to_screen_title () {
+    if [[ $TERM == screen* ]] ; then
+        if [[ -n ${vcs_info_msg_1_} ]] ; then
+            ESC_print ${vcs_info_msg_1_}
+        else
+            ESC_print "zsh"
+        fi
+    fi
+}
+
+function grml_maintain_name () {
+    # set hostname if not running on host with name 'grml'
+    if [[ -n "$HOSTNAME" ]] && [[ "$HOSTNAME" != $(hostname) ]] ; then
+       NAME="@$HOSTNAME"
+    fi
+}
+
+function grml_cmd_to_screen_title () {
+    # get the name of the program currently running and hostname of local
+    # machine set screen window title if running in a screen
+    if [[ "$TERM" == screen* ]] ; then
+        local CMD="${1[(wr)^(*=*|sudo|ssh|-*)]}$NAME"
+        ESC_print ${CMD}
+    fi
+}
+
+function grml_control_xterm_title () {
+    case $TERM in
+        (xterm*|rxvt*)
+            set_title "${(%):-"%n@%m:"}" "$1"
+            ;;
+    esac
+}
+
+zrcautoload add-zsh-hook || add-zsh-hook () { :; }
+if [[ $NOPRECMD -eq 0 ]]; then
+    add-zsh-hook precmd grml_reset_screen_title
+    add-zsh-hook precmd grml_vcs_to_screen_title
+    add-zsh-hook preexec grml_maintain_name
+    add-zsh-hook preexec grml_cmd_to_screen_title
+    if [[ $NOTITLE -eq 0 ]]; then
+        add-zsh-hook preexec grml_control_xterm_title
+    fi
+fi
+
+# 'hash' some often used directories
+#d# start
+hash -d deb=/var/cache/apt/archives
+hash -d doc=/usr/share/doc
+hash -d linux=/lib/modules/$(command uname -r)/build/
+hash -d log=/var/log
+hash -d slog=/var/log/syslog
+hash -d src=/usr/src
+hash -d templ=/usr/share/doc/grml-templates
+hash -d tt=/usr/share/doc/texttools-doc
+hash -d www=/var/www
+#d# end
+
+# some aliases
+if check_com -c screen ; then
+    if [[ $UID -eq 0 ]] ; then
+        if [[ -r /etc/grml/screenrc ]]; then
+            alias screen="${commands[screen]} -c /etc/grml/screenrc"
+        fi
+    elif [[ -r $HOME/.screenrc ]] ; then
+        alias screen="${commands[screen]} -c $HOME/.screenrc"
+    else
+        if [[ -r /etc/grml/screenrc_grml ]]; then
+            alias screen="${commands[screen]} -c /etc/grml/screenrc_grml"
+        else
+            if [[ -r /etc/grml/screenrc ]]; then
+                alias screen="${commands[screen]} -c /etc/grml/screenrc"
+            fi
+        fi
+    fi
+fi
+
+# do we have GNU ls with color-support?
+if [[ "$TERM" != dumb ]]; then
+    #a1# List files with colors (\kbd{ls -b -CF \ldots})
+    alias ls='ls -b -CF '${ls_options:+"${ls_options[*]}"}
+    #a1# List all files, with colors (\kbd{ls -la \ldots})
+    alias la='ls -la '${ls_options:+"${ls_options[*]}"}
+    #a1# List files with long colored list, without dotfiles (\kbd{ls -l \ldots})
+    alias ll='ls -l '${ls_options:+"${ls_options[*]}"}
+    #a1# List files with long colored list, human readable sizes (\kbd{ls -hAl \ldots})
+    alias lh='ls -hAl '${ls_options:+"${ls_options[*]}"}
+    #a1# List files with long colored list, append qualifier to filenames (\kbd{ls -lF \ldots})\\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...)
+    alias l='ls -lF '${ls_options:+"${ls_options[*]}"}
+else
+    alias ls='ls -b -CF'
+    alias la='ls -la'
+    alias ll='ls -l'
+    alias lh='ls -hAl'
+    alias l='ls -lF'
+fi
+
+alias mdstat='cat /proc/mdstat'
+alias ...='cd ../../'
+
+# generate alias named "$KERNELVERSION-reboot" so you can use boot with kexec:
+if [[ -x /sbin/kexec ]] && [[ -r /proc/cmdline ]] ; then
+    alias "$(uname -r)-reboot"="kexec -l --initrd=/boot/initrd.img-"$(uname -r)" --command-line=\"$(cat /proc/cmdline)\" /boot/vmlinuz-"$(uname -r)""
+fi
+
+# see http://www.cl.cam.ac.uk/~mgk25/unicode.html#term for details
+alias term2iso="echo 'Setting terminal to iso mode' ; print -n '\e%@'"
+alias term2utf="echo 'Setting terminal to utf-8 mode'; print -n '\e%G'"
+
+# make sure it is not assigned yet
+[[ -n ${aliases[utf2iso]} ]] && unalias utf2iso
+utf2iso() {
+    if isutfenv ; then
+        for ENV in $(env | command grep -i '.utf') ; do
+            eval export "$(echo $ENV | sed 's/UTF-8/iso885915/ ; s/utf8/iso885915/')"
+        done
+    fi
+}
+
+# make sure it is not assigned yet
+[[ -n ${aliases[iso2utf]} ]] && unalias iso2utf
+iso2utf() {
+    if ! isutfenv ; then
+        for ENV in $(env | command grep -i '\.iso') ; do
+            eval export "$(echo $ENV | sed 's/iso.*/UTF-8/ ; s/ISO.*/UTF-8/')"
+        done
+    fi
+}
+
+# especially for roadwarriors using GNU screen and ssh:
+if ! check_com asc &>/dev/null ; then
+  asc() { autossh -t "$@" 'screen -RdU' }
+  compdef asc=ssh
+fi
+
+#f1# Hints for the use of zsh on grml
+zsh-help() {
+    print "$bg[white]$fg[black]
+zsh-help - hints for use of zsh on grml
+=======================================$reset_color"
+
+    print '
+Main configuration of zsh happens in /etc/zsh/zshrc.
+That file is part of the package grml-etc-core, if you want to
+use them on a non-grml-system just get the tar.gz from
+http://deb.grml.org/ or (preferably) get it from the git repository:
+
+  http://git.grml.org/f/grml-etc-core/etc/zsh/zshrc
+
+This version of grml'\''s zsh setup does not use skel/.zshrc anymore.
+The file is still there, but it is empty for backwards compatibility.
+
+For your own changes use these two files:
+    $HOME/.zshrc.pre
+    $HOME/.zshrc.local
+
+The former is sourced very early in our zshrc, the latter is sourced
+very lately.
+
+System wide configuration without touching configuration files of grml
+can take place in /etc/zsh/zshrc.local.
+
+For information regarding zsh start at http://grml.org/zsh/
+
+Take a look at grml'\''s zsh refcard:
+% xpdf =(zcat /usr/share/doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)
+
+Check out the main zsh refcard:
+% '$BROWSER' http://www.bash2zsh.com/zsh_refcard/refcard.pdf
+
+And of course visit the zsh-lovers:
+% man zsh-lovers
+
+You can adjust some options through environment variables when
+invoking zsh without having to edit configuration files.
+Basically meant for bash users who are not used to the power of
+the zsh yet. :)
+
+  "NOCOR=1    zsh" => deactivate automatic correction
+  "NOMENU=1   zsh" => do not use auto menu completion
+                      (note: use ctrl-d for completion instead!)
+  "NOPRECMD=1 zsh" => disable the precmd + preexec commands (set GNU screen title)
+  "NOTITLE=1  zsh" => disable setting the title of xterms without disabling
+                      preexec() and precmd() completely
+  "BATTERY=1  zsh" => activate battery status (via acpi) on right side of prompt
+  "COMMAND_NOT_FOUND=1 zsh"
+                   => Enable a handler if an external command was not found
+                      The command called in the handler can be altered by setting
+                      the GRML_ZSH_CNF_HANDLER variable, the default is:
+                      "/usr/share/command-not-found/command-not-found"
+
+A value greater than 0 is enables a feature; a value equal to zero
+disables it. If you like one or the other of these settings, you can
+add them to ~/.zshrc.pre to ensure they are set when sourcing grml'\''s
+zshrc.'
+
+    print "
+$bg[white]$fg[black]
+Please report wishes + bugs to the grml-team: http://grml.org/bugs/
+Enjoy your grml system with the zsh!$reset_color"
+}
+
+# debian stuff
+if [[ -r /etc/debian_version ]] ; then
+    #a3# Execute \kbd{apt-cache search}
+    alias acs='apt-cache search'
+    #a3# Execute \kbd{apt-cache show}
+    alias acsh='apt-cache show'
+    #a3# Execute \kbd{apt-cache policy}
+    alias acp='apt-cache policy'
+    #a3# Execute \kbd{apt-get dist-upgrade}
+    salias adg="apt-get dist-upgrade"
+    #a3# Execute \kbd{apt-get install}
+    salias agi="apt-get install"
+    #a3# Execute \kbd{aptitude install}
+    salias ati="aptitude install"
+    #a3# Execute \kbd{apt-get upgrade}
+    salias ag="apt-get upgrade"
+    #a3# Execute \kbd{apt-get update}
+    salias au="apt-get update"
+    #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade}
+    salias -a up="aptitude update ; aptitude safe-upgrade"
+    #a3# Execute \kbd{dpkg-buildpackage}
+    alias dbp='dpkg-buildpackage'
+    #a3# Execute \kbd{grep-excuses}
+    alias ge='grep-excuses'
+
+    # get a root shell as normal user in live-cd mode:
+    if isgrmlcd && [[ $UID -ne 0 ]] ; then
+       alias su="sudo su"
+     fi
+
+    #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog}
+    salias llog="$PAGER /var/log/syslog"     # take a look at the syslog
+    #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog}
+    salias tlog="tail -f /var/log/syslog"    # follow the syslog
+fi
+
+# sort installed Debian-packages by size
+if check_com -c dpkg-query ; then
+    #a3# List installed Debian-packages sorted by size
+    alias debs-by-size="dpkg-query -Wf 'x \${Installed-Size} \${Package} \${Status}\n' | sed -ne '/^x  /d' -e '/^x \(.*\) install ok installed$/s//\1/p' | sort -nr"
+fi
+
+# if cdrecord is a symlink (to wodim) or isn't present at all warn:
+if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord; then
+    if check_com -c wodim; then
+        cdrecord() {
+            cat <\n' "$0" && return 1
+    for file in "$@" ; do
+        while [[ -h "$file" ]] ; do
+            ls -l $file
+            file=$(readlink "$file")
+        done
+    done
+}
+
+# TODO: Is it supported to use pager settings like this?
+#   PAGER='less -Mr' - If so, the use of $PAGER here needs fixing
+# with respect to wordsplitting. (ie. ${=PAGER})
+if check_com -c $PAGER ; then
+    #f3# View Debian's changelog of a given package
+    dchange() {
+        emulate -L zsh
+        if [[ -r /usr/share/doc/$1/changelog.Debian.gz ]] ; then
+            $PAGER /usr/share/doc/$1/changelog.Debian.gz
+        elif [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
+            $PAGER /usr/share/doc/$1/changelog.gz
+        else
+            if check_com -c aptitude ; then
+                echo "No changelog for package $1 found, using aptitude to retrieve it."
+                if isgrml ; then
+                    aptitude -t unstable changelog $1
+                else
+                    aptitude changelog $1
+                fi
+            else
+                echo "No changelog for package $1 found, sorry."
+                return 1
+            fi
+        fi
+    }
+    _dchange() { _files -W /usr/share/doc -/ }
+    compdef _dchange dchange
+
+    #f3# View Debian's NEWS of a given package
+    dnews() {
+        emulate -L zsh
+        if [[ -r /usr/share/doc/$1/NEWS.Debian.gz ]] ; then
+            $PAGER /usr/share/doc/$1/NEWS.Debian.gz
+        else
+            if [[ -r /usr/share/doc/$1/NEWS.gz ]] ; then
+                $PAGER /usr/share/doc/$1/NEWS.gz
+            else
+                echo "No NEWS file for package $1 found, sorry."
+                return 1
+            fi
+        fi
+    }
+    _dnews() { _files -W /usr/share/doc -/ }
+    compdef _dnews dnews
+
+    #f3# View Debian's copyright of a given package
+    dcopyright() {
+        emulate -L zsh
+        if [[ -r /usr/share/doc/$1/copyright ]] ; then
+            $PAGER /usr/share/doc/$1/copyright
+        else
+            echo "No copyright file for package $1 found, sorry."
+            return 1
+        fi
+    }
+    _dcopyright() { _files -W /usr/share/doc -/ }
+    compdef _dcopyright dcopyright
+
+    #f3# View upstream's changelog of a given package
+    uchange() {
+        emulate -L zsh
+        if [[ -r /usr/share/doc/$1/changelog.gz ]] ; then
+            $PAGER /usr/share/doc/$1/changelog.gz
+        else
+            echo "No changelog for package $1 found, sorry."
+            return 1
+        fi
+    }
+    _uchange() { _files -W /usr/share/doc -/ }
+    compdef _uchange uchange
+fi
+
+# zsh profiling
+profile() {
+    ZSH_PROFILE_RC=1 $SHELL "$@"
+}
+
+#f1# Edit an alias via zle
+edalias() {
+    [[ -z "$1" ]] && { echo "Usage: edalias " ; return 1 } || vared aliases'[$1]' ;
+}
+compdef _aliases edalias
+
+#f1# Edit a function via zle
+edfunc() {
+    [[ -z "$1" ]] && { echo "Usage: edfunc " ; return 1 } || zed -f "$1" ;
+}
+compdef _functions edfunc
+
+# use it e.g. via 'Restart apache2'
+#m# f6 Start() \kbd{/etc/init.d/\em{process}}\quad\kbd{start}
+#m# f6 Restart() \kbd{/etc/init.d/\em{process}}\quad\kbd{restart}
+#m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop}
+#m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload}
+#m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload}
+#m# f6 Status() \kbd{/etc/init.d/\em{process}}\quad\kbd{status}
+if [[ -d /etc/init.d || -d /etc/service ]] ; then
+    __start_stop() {
+        local action_="${1:l}"  # e.g Start/Stop/Restart
+        local service_="$2"
+        local param_="$3"
+
+        local service_target_="$(readlink /etc/init.d/$service_)"
+        if [[ $service_target_ == "/usr/bin/sv" ]]; then
+            # runit
+            case "${action_}" in
+                start) if [[ ! -e /etc/service/$service_ ]]; then
+                           $SUDO ln -s "/etc/sv/$service_" "/etc/service/"
+                       else
+                           $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
+                       fi ;;
+                # there is no reload in runits sysv emulation
+                reload) $SUDO "/etc/init.d/$service_" "force-reload" "$param_" ;;
+                *) $SUDO "/etc/init.d/$service_" "${action_}" "$param_" ;;
+            esac
+        else
+            # sysvinit
+            $SUDO "/etc/init.d/$service_" "${action_}" "$param_"
+        fi
+    }
+
+    _grmlinitd() {
+        local -a scripts
+        scripts=( /etc/init.d/*(x:t) )
+        _describe "service startup script" scripts
+    }
+
+    for i in Start Restart Stop Force-Reload Reload Status ; do
+        eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }"
+        compdef _grmlinitd $i
+    done
+fi
+
+#f1# Provides useful information on globbing
+H-Glob() {
+    echo -e "
+    /      directories
+    .      plain files
+    @      symbolic links
+    =      sockets
+    p      named pipes (FIFOs)
+    *      executable plain files (0100)
+    %      device files (character or block special)
+    %b     block special files
+    %c     character special files
+    r      owner-readable files (0400)
+    w      owner-writable files (0200)
+    x      owner-executable files (0100)
+    A      group-readable files (0040)
+    I      group-writable files (0020)
+    E      group-executable files (0010)
+    R      world-readable files (0004)
+    W      world-writable files (0002)
+    X      world-executable files (0001)
+    s      setuid files (04000)
+    S      setgid files (02000)
+    t      files with the sticky bit (01000)
+
+  print *(m-1)          # Files modified up to a day ago
+  print *(a1)           # Files accessed a day ago
+  print *(@)            # Just symlinks
+  print *(Lk+50)        # Files bigger than 50 kilobytes
+  print *(Lk-50)        # Files smaller than 50 kilobytes
+  print **/*.c          # All *.c files recursively starting in \$PWD
+  print **/*.c~file.c   # Same as above, but excluding 'file.c'
+  print (foo|bar).*     # Files starting with 'foo' or 'bar'
+  print *~*.*           # All Files that do not contain a dot
+  chmod 644 *(.^x)      # make all plain non-executable files publically readable
+  print -l *(.c|.h)     # Lists *.c and *.h
+  print **/*(g:users:)  # Recursively match all files that are owned by group 'users'
+  echo /proc/*/cwd(:h:t:s/self//) # Analogous to >ps ax | awk '{print $1}'<"
+}
+alias help-zshglob=H-Glob
+
+# grep for running process, like: 'any vim'
+any() {
+    emulate -L zsh
+    unsetopt KSH_ARRAYS
+    if [[ -z "$1" ]] ; then
+        echo "any - grep for process(es) by keyword" >&2
+        echo "Usage: any " >&2 ; return 1
+    else
+        ps xauwww | grep -i "${grep_options[@]}" "[${1[1]}]${1[2,-1]}"
+    fi
+}
+
+
+# After resuming from suspend, system is paging heavily, leading to very bad interactivity.
+# taken from $LINUX-KERNELSOURCE/Documentation/power/swsusp.txt
+[[ -r /proc/1/maps ]] && \
+deswap() {
+    print 'Reading /proc/[0-9]*/maps and sending output to /dev/null, this might take a while.'
+    cat $(sed -ne 's:.* /:/:p' /proc/[0-9]*/maps | sort -u | grep -v '^/dev/')  > /dev/null
+    print 'Finished, running "swapoff -a; swapon -a" may also be useful.'
+}
+
+# a wrapper for vim, that deals with title setting
+#   VIM_OPTIONS
+#       set this array to a set of options to vim you always want
+#       to have set when calling vim (in .zshrc.local), like:
+#           VIM_OPTIONS=( -p )
+#       This will cause vim to send every file given on the
+#       commandline to be send to it's own tab (needs vim7).
+if check_com vim; then
+    vim() {
+        VIM_PLEASE_SET_TITLE='yes' command vim ${VIM_OPTIONS} "$@"
+    }
+fi
+
+# make a backup of a file
+bk() {
+    cp -a "$1" "${1}_$(date --iso-8601=seconds)"
+}
+
+ssl_hashes=( sha512 sha256 sha1 md5 )
+
+for sh in ${ssl_hashes}; do
+    eval 'ssl-cert-'${sh}'() {
+        emulate -L zsh
+        if [[ -z $1 ]] ; then
+            printf '\''usage: %s \n'\'' "ssh-cert-'${sh}'"
+            return 1
+        fi
+        openssl x509 -noout -fingerprint -'${sh}' -in $1
+    }'
+done; unset sh
+
+ssl-cert-fingerprints() {
+    emulate -L zsh
+    local i
+    if [[ -z $1 ]] ; then
+        printf 'usage: ssl-cert-fingerprints \n'
+        return 1
+    fi
+    for i in ${ssl_hashes}
+        do ssl-cert-$i $1;
+    done
+}
+
+ssl-cert-info() {
+    emulate -L zsh
+    if [[ -z $1 ]] ; then
+        printf 'usage: ssl-cert-info \n'
+        return 1
+    fi
+    openssl x509 -noout -text -in $1
+    ssl-cert-fingerprints $1
+}
+
+# make sure our environment is clean regarding colors
+for color in BLUE RED GREEN CYAN YELLOW MAGENTA WHITE ; unset $color
+
+# "persistent history"
+# just write important commands you always need to ~/.important_commands
+if [[ -r ~/.important_commands ]] ; then
+    fc -R ~/.important_commands
+fi
+
+# load the lookup subsystem if it's available on the system
+zrcautoload lookupinit && lookupinit
+
+# variables
+
+# set terminal property (used e.g. by msgid-chooser)
+export COLORTERM="yes"
+
+# aliases
+
+# general
+#a2# Execute \kbd{du -sch}
+alias da='du -sch'
+#a2# Execute \kbd{jobs -l}
+alias j='jobs -l'
+
+# listing stuff
+#a2# Execute \kbd{ls -lSrah}
+alias dir="ls -lSrah"
+#a2# Only show dot-directories
+alias lad='ls -d .*(/)'
+#a2# Only show dot-files
+alias lsa='ls -a .*(.)'
+#a2# Only files with setgid/setuid/sticky flag
+alias lss='ls -l *(s,S,t)'
+#a2# Only show symlinks
+alias lsl='ls -l *(@)'
+#a2# Display only executables
+alias lsx='ls -l *(*)'
+#a2# Display world-{readable,writable,executable} files
+alias lsw='ls -ld *(R,W,X.^ND/)'
+#a2# Display the ten biggest files
+alias lsbig="ls -flh *(.OL[1,10])"
+#a2# Only show directories
+alias lsd='ls -d *(/)'
+#a2# Only show empty directories
+alias lse='ls -d *(/^F)'
+#a2# Display the ten newest files
+alias lsnew="ls -rtlh *(D.om[1,10])"
+#a2# Display the ten oldest files
+alias lsold="ls -rtlh *(D.Om[1,10])"
+#a2# Display the ten smallest files
+alias lssmall="ls -Srl *(.oL[1,10])"
+#a2# Display the ten newest directories and ten newest .directories
+alias lsnewdir="ls -rthdl *(/om[1,10]) .*(D/om[1,10])"
+#a2# Display the ten oldest directories and ten oldest .directories
+alias lsolddir="ls -rthdl *(/Om[1,10]) .*(D/Om[1,10])"
+
+# some useful aliases
+#a2# Remove current empty directory. Execute \kbd{cd ..; rmdir \$OLDCWD}
+alias rmcdir='cd ..; rmdir $OLDPWD || cd $OLDPWD'
+
+#a2# ssh with StrictHostKeyChecking=no \\&\quad and UserKnownHostsFile unset
+alias insecssh='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
+#a2# scp with StrictHostKeyChecking=no \\&\quad and UserKnownHostsFile unset
+alias insecscp='scp -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
+
+# work around non utf8 capable software in utf environment via $LANG and luit
+if check_com isutfenv && check_com luit ; then
+    if check_com -c mrxvt ; then
+        isutfenv && [[ -n "$LANG" ]] && \
+            alias mrxvt="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit mrxvt"
+    fi
+
+    if check_com -c aterm ; then
+        isutfenv && [[ -n "$LANG" ]] && \
+            alias aterm="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit aterm"
+    fi
+
+    if check_com -c centericq ; then
+        isutfenv && [[ -n "$LANG" ]] && \
+            alias centericq="LANG=${LANG/(#b)(*)[.@]*/$match[1].iso885915} luit centericq"
+    fi
+fi
+
+# useful functions
+
+#f5# Backup \kbd{file {\rm to} file\_timestamp}
+bk() {
+    emulate -L zsh
+    cp -b $1 $1_`date --iso-8601=m`
+}
+
+#f5# cd to directoy and list files
+cl() {
+    emulate -L zsh
+    cd $1 && ls -a
+}
+
+# smart cd function, allows switching to /etc when running 'cd /etc/fstab'
+cd() {
+    if (( ${#argv} == 1 )) && [[ -f ${1} ]]; then
+        [[ ! -e ${1:h} ]] && return 1
+        print "Correcting ${1} to ${1:h}"
+        builtin cd ${1:h}
+    else
+        builtin cd "$@"
+    fi
+}
+
+#f5# Create Directoy and \kbd{cd} to it
+mkcd() {
+    if (( ARGC != 1 )); then
+        printf 'usage: mkcd \n'
+        return 1;
+    fi
+    if [[ ! -d "$1" ]]; then
+        command mkdir -p "$1"
+    else
+        printf '`%s'\'' already exists: cd-ing.\n' "$1"
+    fi
+    builtin cd "$1"
+}
+
+#f5# Create temporary directory and \kbd{cd} to it
+cdt() {
+    local t
+    t=$(mktemp -d)
+    echo "$t"
+    builtin cd "$t"
+}
+
+#f5# List files which have been accessed within the last {\it n} days, {\it n} defaults to 1
+accessed() {
+    emulate -L zsh
+    print -l -- *(a-${1:-1})
+}
+
+#f5# List files which have been changed within the last {\it n} days, {\it n} defaults to 1
+changed() {
+    emulate -L zsh
+    print -l -- *(c-${1:-1})
+}
+
+#f5# List files which have been modified within the last {\it n} days, {\it n} defaults to 1
+modified() {
+    emulate -L zsh
+    print -l -- *(m-${1:-1})
+}
+# modified() was named new() in earlier versions, add an alias for backwards compatibility
+check_com new || alias new=modified
+
+# use colors when GNU grep with color-support
+#a2# Execute \kbd{grep -{}-color=auto}
+(( $#grep_options > 0 )) && alias grep='grep '${grep_options:+"${grep_options[*]}"}
+
+# Translate DE<=>EN
+# 'translate' looks up fot a word in a file with language-to-language
+# translations (field separator should be " : "). A typical wordlist looks
+# like at follows:
+#  | english-word : german-transmission
+# It's also only possible to translate english to german but not reciprocal.
+# Use the following oneliner to turn back the sort order:
+#  $ awk -F ':' '{ print $2" : "$1" "$3 }' \
+#    /usr/local/lib/words/en-de.ISO-8859-1.vok > ~/.translate/de-en.ISO-8859-1.vok
+#f5# Translates a word
+trans() {
+    emulate -L zsh
+    case "$1" in
+        -[dD]*)
+            translate -l de-en $2
+            ;;
+        -[eE]*)
+            translate -l en-de $2
+            ;;
+        *)
+            echo "Usage: $0 { -D | -E }"
+            echo "         -D == German to English"
+            echo "         -E == English to German"
+    esac
+}
+
+# Usage: simple-extract 
+# Using option -d deletes the original archive file.
+#f5# Smart archive extractor
+simple-extract() {
+    emulate -L zsh
+    setopt extended_glob noclobber
+    local DELETE_ORIGINAL DECOMP_CMD USES_STDIN USES_STDOUT GZTARGET WGET_CMD
+    local RC=0
+    zparseopts -D -E "d=DELETE_ORIGINAL"
+    for ARCHIVE in "${@}"; do
+        case $ARCHIVE in
+            *(tar.bz2|tbz2|tbz))
+                DECOMP_CMD="tar -xvjf -"
+                USES_STDIN=true
+                USES_STDOUT=false
+                ;;
+            *(tar.gz|tgz))
+                DECOMP_CMD="tar -xvzf -"
+                USES_STDIN=true
+                USES_STDOUT=false
+                ;;
+            *(tar.xz|txz|tar.lzma))
+                DECOMP_CMD="tar -xvJf -"
+                USES_STDIN=true
+                USES_STDOUT=false
+                ;;
+            *tar)
+                DECOMP_CMD="tar -xvf -"
+                USES_STDIN=true
+                USES_STDOUT=false
+                ;;
+            *rar)
+                DECOMP_CMD="unrar x"
+                USES_STDIN=false
+                USES_STDOUT=false
+                ;;
+            *lzh)
+                DECOMP_CMD="lha x"
+                USES_STDIN=false
+                USES_STDOUT=false
+                ;;
+            *7z)
+                DECOMP_CMD="7z x"
+                USES_STDIN=false
+                USES_STDOUT=false
+                ;;
+            *(zip|jar))
+                DECOMP_CMD="unzip"
+                USES_STDIN=false
+                USES_STDOUT=false
+                ;;
+            *deb)
+                DECOMP_CMD="ar -x"
+                USES_STDIN=false
+                USES_STDOUT=false
+                ;;
+            *bz2)
+                DECOMP_CMD="bzip2 -d -c -"
+                USES_STDIN=true
+                USES_STDOUT=true
+                ;;
+            *(gz|Z))
+                DECOMP_CMD="gzip -d -c -"
+                USES_STDIN=true
+                USES_STDOUT=true
+                ;;
+            *(xz|lzma))
+                DECOMP_CMD="xz -d -c -"
+                USES_STDIN=true
+                USES_STDOUT=true
+                ;;
+            *)
+                print "ERROR: '$ARCHIVE' has unrecognized archive type." >&2
+                RC=$((RC+1))
+                continue
+                ;;
+        esac
+
+        if ! check_com ${DECOMP_CMD[(w)1]}; then
+            echo "ERROR: ${DECOMP_CMD[(w)1]} not installed." >&2
+            RC=$((RC+2))
+            continue
+        fi
+
+        GZTARGET="${ARCHIVE:t:r}"
+        if [[ -f $ARCHIVE ]] ; then
+
+            print "Extracting '$ARCHIVE' ..."
+            if $USES_STDIN; then
+                if $USES_STDOUT; then
+                    ${=DECOMP_CMD} < "$ARCHIVE" > $GZTARGET
+                else
+                    ${=DECOMP_CMD} < "$ARCHIVE"
+                fi
+            else
+                if $USES_STDOUT; then
+                    ${=DECOMP_CMD} "$ARCHIVE" > $GZTARGET
+                else
+                    ${=DECOMP_CMD} "$ARCHIVE"
+                fi
+            fi
+            [[ $? -eq 0 && -n "$DELETE_ORIGINAL" ]] && rm -f "$ARCHIVE"
+
+        elif [[ "$ARCHIVE" == (#s)(https|http|ftp)://* ]] ; then
+            if check_com curl; then
+                WGET_CMD="curl -L -k -s -o -"
+            elif check_com wget; then
+                WGET_CMD="wget -q -O - --no-check-certificate"
+            else
+                print "ERROR: neither wget nor curl is installed" >&2
+                RC=$((RC+4))
+                continue
+            fi
+            print "Downloading and Extracting '$ARCHIVE' ..."
+            if $USES_STDIN; then
+                if $USES_STDOUT; then
+                    ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD} > $GZTARGET
+                    RC=$((RC+$?))
+                else
+                    ${=WGET_CMD} "$ARCHIVE" | ${=DECOMP_CMD}
+                    RC=$((RC+$?))
+                fi
+            else
+                if $USES_STDOUT; then
+                    ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE") > $GZTARGET
+                else
+                    ${=DECOMP_CMD} =(${=WGET_CMD} "$ARCHIVE")
+                fi
+            fi
+
+        else
+            print "ERROR: '$ARCHIVE' is neither a valid file nor a supported URI." >&2
+            RC=$((RC+8))
+        fi
+    done
+    return $RC
+}
+
+__archive_or_uri()
+{
+    _alternative \
+        'files:Archives:_files -g "*.(#l)(tar.bz2|tbz2|tbz|tar.gz|tgz|tar.xz|txz|tar.lzma|tar|rar|lzh|7z|zip|jar|deb|bz2|gz|Z|xz|lzma)"' \
+        '_urls:Remote Archives:_urls'
+}
+
+_simple_extract()
+{
+    _arguments \
+        '-d[delete original archivefile after extraction]' \
+        '*:Archive Or Uri:__archive_or_uri'
+}
+compdef _simple_extract simple-extract
+alias se=simple-extract
+
+#f5# Set all ulimit parameters to \kbd{unlimited}
+allulimit() {
+    ulimit -c unlimited
+    ulimit -d unlimited
+    ulimit -f unlimited
+    ulimit -l unlimited
+    ulimit -n unlimited
+    ulimit -s unlimited
+    ulimit -t unlimited
+}
+
+#f5# Change the xterm title from within GNU-screen
+xtrename() {
+    emulate -L zsh
+    if [[ $1 != "-f" ]] ; then
+        if [[ -z ${DISPLAY} ]] ; then
+            printf 'xtrename only makes sense in X11.\n'
+            return 1
+        fi
+    else
+        shift
+    fi
+    if [[ -z $1 ]] ; then
+        printf 'usage: xtrename [-f] "title for xterm"\n'
+        printf '  renames the title of xterm from _within_ screen.\n'
+        printf '  also works without screen.\n'
+        printf '  will not work if DISPLAY is unset, use -f to override.\n'
+        return 0
+    fi
+    print -n "\eP\e]0;${1}\C-G\e\\"
+    return 0
+}
+
+# Create small urls via http://goo.gl using curl(1).
+# API reference: https://code.google.com/apis/urlshortener/
+function zurl() {
+    emulate -L zsh
+    setopt extended_glob
+
+    if [[ -z $1 ]]; then
+        print "USAGE: zurl "
+        return 1
+    fi
+
+    local PN url prog api json contenttype item
+    local -a data
+    PN=$0
+    url=$1
+
+    # Prepend 'http://' to given URL where necessary for later output.
+    if [[ ${url} != http(s|)://* ]]; then
+        url='http://'${url}
+    fi
+
+    if check_com -c curl; then
+        prog=curl
+    else
+        print "curl is not available, but mandatory for ${PN}. Aborting."
+        return 1
+    fi
+    api='https://www.googleapis.com/urlshortener/v1/url'
+    contenttype="Content-Type: application/json"
+    json="{\"longUrl\": \"${url}\"}"
+    data=(${(f)"$($prog --silent -H ${contenttype} -d ${json} $api)"})
+    # Parse the response
+    for item in "${data[@]}"; do
+        case "$item" in
+            ' '#'"id":'*)
+                item=${item#*: \"}
+                item=${item%\",*}
+                printf '%s\n' "$item"
+                return 0
+                ;;
+        esac
+    done
+    return 1
+}
+
+#f2# Find history events by search pattern and list them by date.
+whatwhen()  {
+    emulate -L zsh
+    local usage help ident format_l format_s first_char remain first last
+    usage='USAGE: whatwhen [options]  '
+    help='Use `whatwhen -h'\'' for further explanations.'
+    ident=${(l,${#${:-Usage: }},, ,)}
+    format_l="${ident}%s\t\t\t%s\n"
+    format_s="${format_l//(\\t)##/\\t}"
+    # Make the first char of the word to search for case
+    # insensitive; e.g. [aA]
+    first_char=[${(L)1[1]}${(U)1[1]}]
+    remain=${1[2,-1]}
+    # Default search range is `-100'.
+    first=${2:-\-100}
+    # Optional, just used for ` ' given.
+    last=$3
+    case $1 in
+        ("")
+            printf '%s\n\n' 'ERROR: No search string specified. Aborting.'
+            printf '%s\n%s\n\n' ${usage} ${help} && return 1
+        ;;
+        (-h)
+            printf '%s\n\n' ${usage}
+            print 'OPTIONS:'
+            printf $format_l '-h' 'show help text'
+            print '\f'
+            print 'SEARCH RANGE:'
+            printf $format_l "'0'" 'the whole history,'
+            printf $format_l '-' 'offset to the current history number; (default: -100)'
+            printf $format_s '<[-]first> []' 'just searching within a give range'
+            printf '\n%s\n' 'EXAMPLES:'
+            printf ${format_l/(\\t)/} 'whatwhen grml' '# Range is set to -100 by default.'
+            printf $format_l 'whatwhen zsh -250'
+            printf $format_l 'whatwhen foo 1 99'
+        ;;
+        (\?)
+            printf '%s\n%s\n\n' ${usage} ${help} && return 1
+        ;;
+        (*)
+            # -l list results on stout rather than invoking $EDITOR.
+            # -i Print dates as in YYYY-MM-DD.
+            # -m Search for a - quoted - pattern within the history.
+            fc -li -m "*${first_char}${remain}*" $first $last
+        ;;
+    esac
+}
+
+# mercurial related stuff
+if check_com -c hg ; then
+    # gnu like diff for mercurial
+    # http://www.selenic.com/mercurial/wiki/index.cgi/TipsAndTricks
+    #f5# GNU like diff for mercurial
+    hgdi() {
+        emulate -L zsh
+        for i in $(hg status -marn "$@") ; diff -ubwd <(hg cat "$i") "$i"
+    }
+
+    # build debian package
+    #a2# Alias for \kbd{hg-buildpackage}
+    alias hbp='hg-buildpackage'
+
+    # execute commands on the versioned patch-queue from the current repos
+    alias mq='hg -R $(readlink -f $(hg root)/.hg/patches)'
+
+    # diffstat for specific version of a mercurial repository
+    #   hgstat      => display diffstat between last revision and tip
+    #   hgstat 1234 => display diffstat between revision 1234 and tip
+    #f5# Diffstat for specific version of a mercurial repos
+    hgstat() {
+        emulate -L zsh
+        [[ -n "$1" ]] && hg diff -r $1 -r tip | diffstat || hg export tip | diffstat
+    }
+
+fi # end of check whether we have the 'hg'-executable
+
+# grml-small cleanups
+
+# The following is used to remove zsh-config-items that do not work
+# in grml-small by default.
+# If you do not want these adjustments (for whatever reason), set
+# $GRMLSMALL_SPECIFIC to 0 in your .zshrc.pre file (which this configuration
+# sources if it is there).
+
+if (( GRMLSMALL_SPECIFIC > 0 )) && isgrmlsmall ; then
+
+    unset abk[V]
+    unalias    'V'      &> /dev/null
+    unfunction vman     &> /dev/null
+    unfunction viless   &> /dev/null
+    unfunction 2html    &> /dev/null
+
+    # manpages are not in grmlsmall
+    unfunction manzsh   &> /dev/null
+    unfunction man2     &> /dev/null
+
+fi
+
+zrclocal
+
+## genrefcard.pl settings
+
+### doc strings for external functions from files
+#m# f5 grml-wallpaper() Sets a wallpaper (try completion for possible values)
+
+### example: split functions-search 8,16,24,32
+#@# split functions-search 8
+
+## END OF FILE #################################################################
+# vim:filetype=zsh foldmethod=marker autoindent expandtab shiftwidth=4
+# Local variables:
+# mode: sh
+# End:
+  prompt fade red
+export PS1="%UDomain:%u %B%F{yellow}iteas.local $PS1"
+echo "HELLO ADMINISTRATOR!"
diff --git a/etc/apcupsd.conf b/etc/apcupsd.conf
new file mode 100644
index 0000000..f54b9fc
--- /dev/null
+++ b/etc/apcupsd.conf
@@ -0,0 +1,334 @@
+## apcupsd.conf v1.1 ##
+# 
+#  for apcupsd release 3.14.12 (29 March 2014) - debian
+#
+# "apcupsd" POSIX config file
+
+#
+# ========= General configuration parameters ============
+#
+
+# UPSNAME xxx
+#   Use this to give your UPS a name in log files and such. This
+#   is particulary useful if you have multiple UPSes. This does not
+#   set the EEPROM. It should be 8 characters or less.
+UPSNAME usv01
+
+# UPSCABLE 
+#   Defines the type of cable connecting the UPS to your computer.
+#
+#   Possible generic choices for  are:
+#     simple, smart, ether, usb
+#
+#   Or a specific cable model number may be used:
+#     940-0119A, 940-0127A, 940-0128A, 940-0020B,
+#     940-0020C, 940-0023A, 940-0024B, 940-0024C,
+#     940-1524C, 940-0024G, 940-0095A, 940-0095B,
+#     940-0095C, 940-0625A, M-04-02-2000
+#
+#UPSCABLE smart
+
+# To get apcupsd to work, in addition to defining the cable
+# above, you must also define a UPSTYPE, which corresponds to
+# the type of UPS you have (see the Description for more details).
+# You must also specify a DEVICE, sometimes referred to as a port.
+# For USB UPSes, please leave the DEVICE directive blank. For
+# other UPS types, you must specify an appropriate port or address.
+#
+# UPSTYPE   DEVICE           Description
+# apcsmart  /dev/tty**       Newer serial character device, appropriate for 
+#                            SmartUPS models using a serial cable (not USB).
+#
+# usb                 Most new UPSes are USB. A blank DEVICE
+#                            setting enables autodetection, which is
+#                            the best choice for most installations.
+#
+# net       hostname:port    Network link to a master apcupsd through apcupsd's 
+#                            Network Information Server. This is used if the
+#                            UPS powering your computer is connected to a 
+#                            different computer for monitoring.
+#
+# snmp      hostname:port:vendor:community
+#                            SNMP network link to an SNMP-enabled UPS device.
+#                            Hostname is the ip address or hostname of the UPS 
+#                            on the network. Vendor can be can be "APC" or 
+#                            "APC_NOTRAP". "APC_NOTRAP" will disable SNMP trap 
+#                            catching; you usually want "APC". Port is usually 
+#                            161. Community is usually "private".
+#
+# netsnmp   hostname:port:vendor:community
+#                            OBSOLETE
+#                            Same as SNMP above but requires use of the 
+#                            net-snmp library. Unless you have a specific need
+#                            for this old driver, you should use 'snmp' instead.
+#
+# dumb      /dev/tty**       Old serial character device for use with 
+#                            simple-signaling UPSes.
+#
+# pcnet     ipaddr:username:passphrase:port
+#                            PowerChute Network Shutdown protocol which can be 
+#                            used as an alternative to SNMP with the AP9617 
+#                            family of smart slot cards. ipaddr is the IP 
+#                            address of the UPS management card. username and 
+#                            passphrase are the credentials for which the card 
+#                            has been configured. port is the port number on 
+#                            which to listen for messages from the UPS, normally 
+#                            3052. If this parameter is empty or missing, the 
+#                            default of 3052 will be used.
+#
+# modbus    /dev/tty**       Serial device for use with newest SmartUPS models
+#                            supporting the MODBUS protocol.
+#
+#UPSTYPE apcsmart
+#DEVICE /dev/ttyS0
+
+UPSTYPE usb
+
+# POLLTIME 
+#   Interval (in seconds) at which apcupsd polls the UPS for status. This
+#   setting applies both to directly-attached UPSes (UPSTYPE apcsmart, usb, 
+#   dumb) and networked UPSes (UPSTYPE net, snmp). Lowering this setting
+#   will improve apcupsd's responsiveness to certain events at the cost of
+#   higher CPU utilization. The default of 60 is appropriate for most
+#   situations.
+#POLLTIME 60
+
+# LOCKFILE 
+#   Path for device lock file. Not used on Win32.
+LOCKFILE /var/lock
+
+# SCRIPTDIR 
+#   Directory in which apccontrol and event scripts are located.
+SCRIPTDIR /etc/apcupsd
+
+# PWRFAILDIR 
+#   Directory in which to write the powerfail flag file. This file
+#   is created when apcupsd initiates a system shutdown and is
+#   checked in the OS halt scripts to determine if a killpower
+#   (turning off UPS output power) is required.
+PWRFAILDIR /etc/apcupsd
+
+# NOLOGINDIR 
+#   Directory in which to write the nologin file. The existence
+#   of this flag file tells the OS to disallow new logins.
+NOLOGINDIR /etc
+
+
+#
+# ======== Configuration parameters used during power failures ==========
+#
+
+# The ONBATTERYDELAY is the time in seconds from when a power failure
+#   is detected until we react to it with an onbattery event.
+#
+#   This means that, apccontrol will be called with the powerout argument
+#   immediately when a power failure is detected.  However, the
+#   onbattery argument is passed to apccontrol only after the 
+#   ONBATTERYDELAY time.  If you don't want to be annoyed by short
+#   powerfailures, make sure that apccontrol powerout does nothing
+#   i.e. comment out the wall.
+ONBATTERYDELAY 6
+
+# 
+# Note: BATTERYLEVEL, MINUTES, and TIMEOUT work in conjunction, so
+# the first that occurs will cause the initation of a shutdown.
+#
+
+# If during a power failure, the remaining battery percentage
+# (as reported by the UPS) is below or equal to BATTERYLEVEL, 
+# apcupsd will initiate a system shutdown.
+BATTERYLEVEL 20
+
+# If during a power failure, the remaining runtime in minutes 
+# (as calculated internally by the UPS) is below or equal to MINUTES,
+# apcupsd, will initiate a system shutdown.
+MINUTES 10
+
+# If during a power failure, the UPS has run on batteries for TIMEOUT
+# many seconds or longer, apcupsd will initiate a system shutdown.
+# A value of 0 disables this timer.
+#
+#  Note, if you have a Smart UPS, you will most likely want to disable
+#    this timer by setting it to zero. That way, you UPS will continue
+#    on batteries until either the % charge remaing drops to or below BATTERYLEVEL,
+#    or the remaining battery runtime drops to or below MINUTES.  Of course,
+#    if you are testing, setting this to 60 causes a quick system shutdown
+#    if you pull the power plug.   
+#  If you have an older dumb UPS, you will want to set this to less than
+#    the time you know you can run on batteries.
+TIMEOUT 0
+
+#  Time in seconds between annoying users to signoff prior to
+#  system shutdown. 0 disables.
+ANNOY 300
+
+# Initial delay after power failure before warning users to get
+# off the system.
+ANNOYDELAY 60
+
+# The condition which determines when users are prevented from
+# logging in during a power failure.
+# NOLOGON  [ disable | timeout | percent | minutes | always ]
+NOLOGON disable
+
+# If KILLDELAY is non-zero, apcupsd will continue running after a
+# shutdown has been requested, and after the specified time in
+# seconds attempt to kill the power. This is for use on systems
+# where apcupsd cannot regain control after a shutdown.
+# KILLDELAY   0 disables
+KILLDELAY 0
+
+#
+# ==== Configuration statements for Network Information Server ====
+#
+
+# NETSERVER [ on | off ] on enables, off disables the network
+#  information server. If netstatus is on, a network information
+#  server process will be started for serving the STATUS and
+#  EVENT data over the network (used by CGI programs).
+NETSERVER on
+
+# NISIP 
+#  IP address on which NIS server will listen for incoming connections.
+#  This is useful if your server is multi-homed (has more than one
+#  network interface and IP address). Default value is 0.0.0.0 which
+#  means any incoming request will be serviced. Alternatively, you can
+#  configure this setting to any specific IP address of your server and 
+#  NIS will listen for connections only on that interface. Use the
+#  loopback address (127.0.0.1) to accept connections only from the
+#  local machine.
+NISIP 127.0.0.1
+
+# NISPORT  default is 3551 as registered with the IANA
+#  port to use for sending STATUS and EVENTS data over the network.
+#  It is not used unless NETSERVER is on. If you change this port,
+#  you will need to change the corresponding value in the cgi directory
+#  and rebuild the cgi programs.
+NISPORT 3551
+
+# If you want the last few EVENTS to be available over the network
+# by the network information server, you must define an EVENTSFILE.
+EVENTSFILE /var/log/apcupsd.events
+
+# EVENTSFILEMAX 
+#  By default, the size of the EVENTSFILE will be not be allowed to exceed
+#  10 kilobytes.  When the file grows beyond this limit, older EVENTS will
+#  be removed from the beginning of the file (first in first out).  The
+#  parameter EVENTSFILEMAX can be set to a different kilobyte value, or set
+#  to zero to allow the EVENTSFILE to grow without limit.
+EVENTSFILEMAX 10
+
+#
+# ========== Configuration statements used if sharing =============
+#            a UPS with more than one machine
+
+#
+# Remaining items are for ShareUPS (APC expansion card) ONLY
+#
+
+# UPSCLASS [ standalone | shareslave | sharemaster ]
+#   Normally standalone unless you share an UPS using an APC ShareUPS
+#   card.
+UPSCLASS standalone
+
+# UPSMODE [ disable | share ]
+#   Normally disable unless you share an UPS using an APC ShareUPS card.
+UPSMODE disable
+
+#
+# ===== Configuration statements to control apcupsd system logging ========
+#
+
+# Time interval in seconds between writing the STATUS file; 0 disables
+STATTIME 0
+
+# Location of STATUS file (written to only if STATTIME is non-zero)
+STATFILE /var/log/apcupsd.status
+
+# LOGSTATS [ on | off ] on enables, off disables
+# Note! This generates a lot of output, so if         
+#       you turn this on, be sure that the
+#       file defined in syslog.conf for LOG_NOTICE is a named pipe.
+#  You probably do not want this on.
+LOGSTATS off
+
+# Time interval in seconds between writing the DATA records to
+#   the log file. 0 disables.
+DATATIME 0
+
+# FACILITY defines the logging facility (class) for logging to syslog. 
+#          If not specified, it defaults to "daemon". This is useful 
+#          if you want to separate the data logged by apcupsd from other
+#          programs.
+#FACILITY DAEMON
+
+#
+# ========== Configuration statements used in updating the UPS EPROM =========
+#
+
+#
+# These statements are used only by apctest when choosing "Set EEPROM with conf
+# file values" from the EEPROM menu. THESE STATEMENTS HAVE NO EFFECT ON APCUPSD.
+#
+
+# UPS name, max 8 characters 
+#UPSNAME UPS_IDEN
+
+# Battery date - 8 characters
+#BATTDATE mm/dd/yy
+
+# Sensitivity to line voltage quality (H cause faster transfer to batteries)  
+# SENSITIVITY H M L        (default = H)
+#SENSITIVITY H
+
+# UPS delay after power return (seconds)
+# WAKEUP 000 060 180 300   (default = 0)
+#WAKEUP 60
+
+# UPS Grace period after request to power off (seconds)
+# SLEEP 020 180 300 600    (default = 20)
+#SLEEP 180
+
+# Low line voltage causing transfer to batteries
+# The permitted values depend on your model as defined by last letter 
+#  of FIRMWARE or APCMODEL. Some representative values are:
+#    D 106 103 100 097
+#    M 177 172 168 182
+#    A 092 090 088 086
+#    I 208 204 200 196     (default = 0 => not valid)
+#LOTRANSFER  208
+
+# High line voltage causing transfer to batteries
+# The permitted values depend on your model as defined by last letter 
+#  of FIRMWARE or APCMODEL. Some representative values are:
+#    D 127 130 133 136
+#    M 229 234 239 224
+#    A 108 110 112 114
+#    I 253 257 261 265     (default = 0 => not valid)
+#HITRANSFER 253
+
+# Battery charge needed to restore power
+# RETURNCHARGE 00 15 50 90 (default = 15)
+#RETURNCHARGE 15
+
+# Alarm delay 
+# 0 = zero delay after pwr fail, T = power fail + 30 sec, L = low battery, N = never
+# BEEPSTATE 0 T L N        (default = 0)
+#BEEPSTATE T
+
+# Low battery warning delay in minutes
+# LOWBATT 02 05 07 10      (default = 02)
+#LOWBATT 2
+
+# UPS Output voltage when running on batteries
+# The permitted values depend on your model as defined by last letter 
+#  of FIRMWARE or APCMODEL. Some representative values are:
+#    D 115
+#    M 208
+#    A 100
+#    I 230 240 220 225     (default = 0 => not valid)
+#OUTPUTVOLTS 230
+
+# Self test interval in hours 336=2 weeks, 168=1 week, ON=at power on
+# SELFTEST 336 168 ON OFF  (default = 336)
+#SELFTEST 336
diff --git a/etc/pve-usb-automount/main.conf b/etc/pve-usb-automount/main.conf
new file mode 100644
index 0000000..d252c37
--- /dev/null
+++ b/etc/pve-usb-automount/main.conf
@@ -0,0 +1,2 @@
+[MAIN]
+MAX_FILES = 3
\ No newline at end of file
diff --git a/etc/rc.local b/etc/rc.local
new file mode 100755
index 0000000..03208da
--- /dev/null
+++ b/etc/rc.local
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# USB-Automount
+( devmon --no-gui --sync --mount-options "noexec,nosuid,noatime" \
+    --exec-on-drive '/usr/local/bin/mount_drive.py "%f" "%d"' \
+    --exec-on-remove '/usr/local/bin/umount_drive.py "%f"' > /dev/null 2>&1 ) &
+
+exit 0
diff --git a/etc/sddm.conf-user-autologon b/etc/sddm.conf-user-autologon
new file mode 100644
index 0000000..defe9f2
--- /dev/null
+++ b/etc/sddm.conf-user-autologon
@@ -0,0 +1,16 @@
+[Autologin]
+Relogin=true
+Session=plasma.desktop
+User=user
+
+[General]
+HaltCommand=
+RebootCommand=
+
+[Theme]
+Current=breeze
+CursorTheme=Adwaita
+
+[Users]
+MaximumUid=60000
+MinimumUid=1000
\ No newline at end of file
diff --git a/proxmox_install.py b/proxmox_install.py
new file mode 100644
index 0000000..04bc290
--- /dev/null
+++ b/proxmox_install.py
@@ -0,0 +1,812 @@
+#!/usr/bin/python2
+# -*- coding: utf-8 -*-
+
+#
+# (c) Rene Hadler, Mario Loderer, iteas IT Services GmbH
+# support@iteas.at
+# www.iteas.at
+#
+
+import sys
+import time
+import socket
+import subprocess
+import re
+
+# Globale Variablen
+VERSION = "0.7.0"
+TITLE = "iteas Proxmox Installer " + VERSION
+CHECK_INTERNET_IP = "77.235.68.39"
+VM_TEMPLATE_NFS = "10.70.99.28:/rpool/sicherung"
+SMB_ADMIN_PASSWD = "backmode123"
+
+try:
+    CONSOLE_ROWS, CONSOLE_COLS = subprocess.check_output(['stty', 'size']).split()
+except:
+    CONSOLE_ROWS = 40
+    CONSOLE_COLS = 100
+
+GUI_WIN_WIDTH = 100 if int(CONSOLE_COLS) > 110 else (int(CONSOLE_COLS) - 10)
+
+class Logger:
+    def __init__(self):
+        self.f = fr = open("proxmox_install.log", "w+")
+
+    def log(self, text):
+        self.f.write(text)
+
+    def close(self):
+        self.f.close()
+
+logger = Logger()
+
+# Befehle ausfĂĽhren
+def run_cmd(command, argShell=False):
+    try:
+        return subprocess.call(command.split(" ") if argShell == False else command, shell=argShell)
+    except:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Fehler", "Befehl <%s> war nicht erfolgreich, Fehlermeldung: %s -- Installation abbrechen?" % (command, e))
+        if retval[0] == 1:
+            exit(1)
+
+def run_cmd_output(command, argShell=False):
+    p = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read(), p.stderr.read())
+
+def run_cmd_stdout(command, argShell=False):
+    p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read())
+
+def run_cmd_stderr(command, argShell=False):
+    p = subprocess.Popen(command, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stderr.read())
+
+def run_cmd_stdin(command, argShell=False):
+    p = subprocess.Popen(command, stdin=subprocess.PIPE, shell=argShell)
+    return p
+
+# Oberflächen / GUI
+def gui_message_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--msgbox", text, "--title", title, "8", str(GUI_WIN_WIDTH)])
+
+def gui_text_box(file):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--textbox", file, "20", str(GUI_WIN_WIDTH)])
+
+def gui_input_box(title, text, default=""):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--inputbox", text, "8", str(GUI_WIN_WIDTH), default, "--title", title])
+
+def gui_yesno_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--yesno", text, "--title", title, "8", str(GUI_WIN_WIDTH)])
+
+def gui_password_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--passwordbox", text, "8", str(GUI_WIN_WIDTH), "--title", title])
+
+def gui_menu_box(title, text, menu):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--menu", text, "--title", title, "24", str(GUI_WIN_WIDTH), "18"] + menu)
+
+def gui_checklist_box(title, text, checklist):
+    ret = run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--checklist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + checklist)
+    return (ret[0], [] if ret[1] == "" else [x.replace('"', "") for x in ret[1].split(" ")])
+
+def gui_radiolist_box(title, text, radiolist):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--radiolist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + radiolist)
+
+class gui_progress_box():
+    def __init__(self, text, progress):
+        self.p = run_cmd_stdin(["whiptail", "--backtitle", TITLE, "--gauge", text, "6", "50", str(progress)])
+
+    def update(self, prog):
+        self.p.stdin.write(str(prog) + "\n")
+
+    def finish(self):
+        self.p.stdin.close()
+
+def gui_password_verify_box(title, text, text2):
+    password = ""
+    while password == "":
+        retval = gui_password_box(title, text)
+        if retval[1] == "":
+            continue
+
+        retval2 = gui_password_box(title, text2)
+        if retval2[1] == "":
+            continue
+
+        if retval[1] == retval2[1]:
+            password = retval[1]
+        else:
+            gui_message_box(title, "Fehler bei der Passworteingabe, die Passwoerter stimmen nicht ueberein!")
+
+    return password
+
+# Sonstige Funktionen
+def check_internet():
+    try:
+        s = socket.create_connection((CHECK_INTERNET_IP, 80), 5)
+        return True
+    except:
+        return False
+
+def check_filesystem():
+    try:
+        zfsc = run_cmd_output('zfs list')
+        if zfsc[2].find('no datasets') != -1:
+            return 'standard'
+        else:
+            return 'zfs'
+    except:
+        return 'standard'
+
+def check_systemip(show_prefix = True):
+    zfsc = run_cmd_stdout("ip addr show vmbr0 | grep 'inet' | grep -v 'inet6' | cut -d' ' -f6", argShell=True)
+    if show_prefix == True:
+        return zfsc[1].strip()
+    else:
+        return zfsc[1].strip().split("/")[0]
+
+def check_systemipnet():
+    try:
+        zfsc = check_systemip()
+        if zfsc == '':
+            return ''
+        else:
+            # Nicht immer true
+            ipf = zfsc.split(".")
+            return "%s.%s.%s.0/%s" % (ipf[0], ipf[1], ipf[2], ipf[3].split("/")[1])
+    except:
+        return ''
+
+def file_replace_line(file, findstr, replstr):
+    fp = open(file, "r+")
+    buf = ""
+    for line in fp.readlines():
+        if line.find(findstr) != -1:
+            line = replstr + "\n"
+
+        buf += line
+
+    fp.close()
+    fr = open(file, "w+")
+    fr.write(buf)
+    fr.close()
+
+def file_create(file, str):
+    fr = open(file, "w+")
+    fr.write(str + "\n")
+    fr.close()
+
+def file_append(file, str):
+    fr = open(file, "a")
+    fr.write(str + "\n")
+    fr.close()
+
+# Installer Start
+class Installer():
+    def __init__(self):
+        self.internet = False
+        self.fqdn = socket.getfqdn()
+        try:
+            self.domain = self.fqdn.split(".")[1] + "." + self.fqdn.split(".")[2]
+            self.hostname = socket.gethostname()
+        except:
+            gui_message_box("Installer", "FQDN ist nicht richtig gesetzt, Installation wird abgebrochen!")
+            exit(1)
+
+        self.machine_vendor = "other"
+        self.machine_type = "virt"
+        self.environment = "stable"
+        self.monitoring = "nagios"
+        self.license = ""
+        self.filesystem = ""
+        self.mgmt_ip = ""
+        self.backuppc = False
+        self.vm_import = []
+        self.share_clients = []
+        self.proxy = True
+
+        # Installer Variablen
+        self.MACHINE_VENDORS = {"hp": "HP", "dell": "Dell", "other": "Andere"}
+        self.MACHINE_TYPES = {"virt": "Virtualisierung", "backup": "Backup"}
+        self.ENVIRONMENTS = {"stable": "Stabile Proxmox Enterprise Updates", "test": "Proxmox Testing Updates", "noupdate": "Keine Proxmox Updates"}
+        self.MONITORINGS = {"nagios": "Nagios NRPE", "checkmk": "CheckMK Agent"}
+        self.FILESYSTEMS = {"standard": "Standard (ext3/4, reiserfs, xfs)", "zfs": "ZFS"}
+        self.VM_IMPORTS = {
+                            "114": {"name": "vsrv-itmgmt", "template": False},
+                            "139": {"name": "Windows 7 Pro", "template": True},
+                            "115": {"name": "Windows 8.1 Pro", "template": True},
+                            "125": {"name": "Windows 10 Pro", "template": True},
+                            "117": {"name": "Windows 2008 r2", "template": True},
+                            "120": {"name": "Windows 2012 r2", "template": True},
+                            "130": {"name": "Windows 2016", "template": True}
+                           }
+
+    def start(self):
+        gui_message_box("Installer", "Willkommen beim iteas Proxmox Installer!")
+        self.internet = check_internet()
+        self.filesystem = check_filesystem()
+        if check_systemipnet() != '':
+            self.share_clients.append(check_systemipnet())
+        self.step1()
+
+    def step1(self):
+        step1_val = gui_menu_box("Schritt 1", "Kontrollieren bzw. konfigurieren Sie die entsprechenden Werte und gehen Sie dann auf 'Weiter'.",
+                                    ["Internet", "JA" if self.internet == True else "NEIN",
+                                     "Hostname", self.hostname,
+                                     "Domain", self.domain,
+                                     "Dateisystem", self.FILESYSTEMS[self.filesystem],
+                                     " ", " ",
+                                     "Maschinenhersteller", self.MACHINE_VENDORS[self.machine_vendor],
+                                     "Maschinentyp", self.MACHINE_TYPES[self.machine_type],
+                                     "BackupPC", "Nein" if self.backuppc == False else "Ja",
+                                     "Proxmox-Umgebung", self.ENVIRONMENTS[self.environment],
+                                     "Proxmox-Lizenz", "Keine" if self.license == "" else self.license,
+                                     "VM-Template-Import", ",".join([self.VM_IMPORTS[x]["name"] for x in self.vm_import]) if len(self.vm_import) > 0 else "Keine",
+                                     "Freigabe-Clients", ",".join([x for x in self.share_clients]) if len(self.share_clients) > 0 else "Alle",
+                                     "Mgmt-IP", "Keine" if self.mgmt_ip == "" else self.mgmt_ip,
+                                     "apt-Proxy", "Nein" if self.proxy == False else "Ja",
+                                     "Monitoring-Agent", self.MONITORINGS[self.monitoring],
+                                     " ", " ",
+                                     "Weiter", "Installation fortsetzen"])
+
+        # Abbrechen
+        if step1_val[0] == 1 or step1_val[0] == 255:
+            exit(0)
+
+        # Eintrag wurde gewählt
+        if step1_val[1] == "Maschinenhersteller":
+            self.step1_machine_vendor()
+
+        elif step1_val[1] == "Maschinentyp":
+            self.step1_machine_type()
+
+        elif step1_val[1] == "Proxmox-Umgebung":
+            self.step1_environment()
+
+        elif step1_val[1] == "Monitoring-Agent":
+            self.step1_monitoring()
+
+        elif step1_val[1] == "Proxmox-Lizenz":
+            self.step1_license()
+
+        elif step1_val[1] == "Mgmt-IP":
+            self.step1_mgmtip()
+
+        elif step1_val[1] == "apt-Proxy":
+            self.step1_aptproxy()
+
+        elif step1_val[1] == "BackupPC":
+            self.step1_backuppc()
+
+        elif step1_val[1] == "VM-Template-Import":
+            self.step1_vmtemplateimport()
+
+        elif step1_val[1] == "Internet":
+            check_internet()
+            self.step1()
+
+        elif step1_val[1] == "Freigabe-Clients":
+            self.step1_shareclients()
+
+        elif step1_val[1] == "Weiter":
+            self.step2()
+
+        else:
+            self.step1()
+
+    def step1_machine_vendor(self):
+        list = []
+        for key, val in self.MACHINE_VENDORS.iteritems():
+            list += [key, val, "ON" if self.machine_vendor == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Maschinenhersteller", "Waehlen sie den passenden Maschinenhersteller", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_vendor = retval[1]
+        self.step1()
+
+    def step1_machine_type(self):
+        list = []
+        for key, val in self.MACHINE_TYPES.iteritems():
+            list += [key, val, "ON" if self.machine_type == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Maschinentyp", "Waehlen sie den passenden Maschinentyp", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_type = retval[1]
+        self.step1()
+
+    def step1_environment(self):
+        list = []
+        for key, val in self.ENVIRONMENTS.iteritems():
+            list += [key, val, "ON" if self.environment == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Proxmox-Umgebung", "Waehlen sie die Proxmox-Umgebung", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.environment = retval[1]
+        self.step1()
+
+    def step1_monitoring(self):
+        list = []
+        for key, val in self.MONITORINGS.iteritems():
+            list += [key, val, "ON" if self.monitoring == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Monitoring-Agent", "Waehlen sie den Monitoring-Agenten", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.monitoring = retval[1]
+        self.step1()
+
+    def step1_license(self):
+        retval = gui_input_box("Schritt 1: Proxmox-Lizenz", "Geben Sie den Proxmox-Schluessel ein", self.license)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.license = retval[1]
+        self.step1()
+
+    def step1_mgmtip(self):
+        retval = gui_input_box("Schritt 1: Mgmt-IP", "Geben Sie die IP des Managementservers ein", self.mgmt_ip)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.mgmt_ip = retval[1]
+        self.step1()
+
+    def step1_aptproxy(self):
+        retval = gui_yesno_box("Installer", "Mochten Sie den iteas apt-Proxy benutzen?")
+        if retval[0] == 0:
+            self.proxy = True
+        elif retval[0] == 1:
+            self.proxy = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1()
+            return
+
+        self.step1()
+
+    def step1_backuppc(self):
+        retval = gui_yesno_box("Installer", "Mochten Sie BackupPC dazuinstallieren?")
+        if retval[0] == 0:
+            self.backuppc = True
+        elif retval[0] == 1:
+            self.backuppc = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1()
+            return
+
+        self.step1()
+
+    def step1_vmtemplateimport(self):
+        list = []
+        for key, val in self.VM_IMPORTS.iteritems():
+            list += [key, val["name"], "ON" if key in self.vm_import else "OFF"]
+
+        retval = gui_checklist_box("Schritt 1: VM-Template-Import", "Waehlen sie die VMs die importiert werden sollen", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.vm_import = []
+        for val in retval[1]:
+            self.vm_import += [val]
+
+        self.step1()
+
+    def step1_shareclients(self):
+        retval = gui_input_box("Schritt 1: Freigabe-Clients", "Geben Sie die Clients/Netze an, die Zugriffe auf die Freigaben haben sollen. Mehrere Eintraege muessen durch Leerzeichen getrennt sein.", " ".join(self.share_clients))
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.share_clients = retval[1].split(" ")
+        self.step1()
+
+    def step2(self):
+        if self.environment == "stable" and self.license == "":
+            gui_message_box("Installer", "Sie muessen eine Lizenz angeben wenn Enterprise Updates ausgewaehlt wurden!")
+            self.step1()
+            return
+
+        if self.internet == False:
+            gui_message_box("Installer", "Es muss eine Internetverbindung bestehen um fortzufahren!")
+            self.step1()
+            return
+
+        ############ Allgemeine Konfiguration
+        if self.license != "":
+            retval = run_cmd_output('pvesubscription set ' + self.license)
+            if retval[0] == 255:
+                gui_message_box("Proxmox Lizenzinstallation", "Die Lizenz konnte nicht installiert werden, bitte pruefen Sie Ihre Lizenznummer. Fehler: " + retval[2])
+                self.step1()
+                return
+
+            print "Warte auf Registrierung der Proxmox-Subscription..."
+            time.sleep(30)
+
+        # Proxmox Testing Quellen aktivieren
+        if self.environment == "test":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian jessie pve-enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "deb http://download.proxmox.com/debian jessie pve-no-subscription")
+        elif self.environment == "noupdate":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian jessie pve-enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "# deb http://download.proxmox.com/debian jessie pve-no-subscription")
+
+        # If lvm-thin convert to standard file storage if backup-machine
+        if self.machine_type == "backup" and run_cmd('pvesh get /storage | grep -i lvmthin', argShell=True) == 0:
+            run_cmd('pvesh delete /storage/local-lvm')
+            run_cmd('lvremove /dev/pve/data -f')
+            run_cmd('lvcreate -Wy -l100%FREE -ndata pve')
+            run_cmd('mkfs.ext4 -m1 /dev/pve/data')
+            run_cmd('mount /dev/pve/data /var/lib/vz')
+            file_append("/etc/fstab", "/dev/pve/data /var/lib/vz ext4 defaults 0 1")
+
+        # Mount Template NFS-Share und importiere VMs
+        storage = "local"
+        if run_cmd('pvesh get /storage | grep -i lvmthin', argShell=True) == 0:
+            storage = "local-lvm"
+
+        if len(self.vm_import) > 0:
+            if run_cmd('mount ' + VM_TEMPLATE_NFS + ' /mnt') == 0:
+                for vm_id in self.vm_import:
+                    (ret, filename) = run_cmd_stdout("ls -t /mnt/dump/vzdump-qemu-%s*vma* | head -n1" % vm_id, argShell=True)
+                    if filename != "":
+                        run_cmd("qmrestore %s %s -storage %s" % (filename.strip(), vm_id, storage))
+                        if self.VM_IMPORTS[vm_id]["template"] == True:
+                            run_cmd("qm template %s" % vm_id)
+
+                run_cmd('umount /mnt')
+            else:
+                gui_message_box("Installer", "NFS konnte nicht gemounted werden, VMs werden nicht importiert!")
+
+        # Apt-Proxy Cache
+        if self.proxy == True:
+            file_create("/etc/apt/apt.conf.d/01proxy", 'Acquire::http { Proxy "http://10.69.99.10:3142"; };')
+
+        # Installieren allgemeine Tools und Monitoring-Agent
+        file_create("/etc/apt/sources.list.d/styrion.list", "deb [trusted=yes] http://styrion.at/apt ./")
+        run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 2FAB19E7CCB7F415')
+        run_cmd('apt-get update')
+        run_cmd('apt-get dist-upgrade -y')
+        run_cmd('apt-get install htop elinks unp postfix sudo screen zsh tmux bwm-ng pigz sysstat ethtool nload apcupsd ntfs-3g usbmount sl -y')
+        if self.monitoring == "nagios":
+            run_cmd('apt-get install nagios-nrpe-server -y')
+        elif self.monitoring == "checkmk":
+            run_cmd('apt-get install xinetd check-mk-agent -y')
+
+        # SUDOers
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /usr/bin/rsync")
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /bin/tar")
+
+        # Monitoring Konfiguration
+        if self.monitoring == "nagios":
+
+            # SUDOers
+            file_append("/etc/sudoers", "nagios      ALL=(ALL) NOPASSWD: /usr/lib/nagios/plugins/")
+            file_append("/etc/sudoers", "nagios      ALL=(ALL) NOPASSWD: /usr/sbin/hpssacli")
+            file_append("/etc/sudoers", "nagios      ALL=(ALL) NOPASSWD: /sbin/hpasmcli")
+            file_append("/etc/sudoers", "#nagios      ALL=(ALL) NOPASSWD: /bin/su")
+            file_append("/etc/sudoers", "#nagios    ALL=(backuppc) NOPASSWD: ALL")
+
+            if self.mgmt_ip != "":
+                file_replace_line("/etc/nagios/nrpe.cfg", "allowed_hosts=", "allowed_hosts=127.0.0.1,%s" % self.mgmt_ip)
+
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_vg_size https://ftp.iteas.at/public/nagios/plugins/check_vg_size')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_zpool-1.sh https://ftp.iteas.at/public/nagios/plugins/check_zpool-1.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_zpool.sh https://ftp.iteas.at/public/nagios/plugins/check_zpool.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_backuppc https://ftp.iteas.at/public/nagios/plugins/check_backuppc')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_proc_backuppc.sh https://ftp.iteas.at/public/nagios/plugins/check_proc_backuppc.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_smb https://ftp.iteas.at/public/nagios/plugins/check_smb')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_apcupsd https://ftp.iteas.at/public/nagios/plugins/check_apcupsd')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_vg_size')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_zpool-1.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_zpool.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_backuppc')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_proc_backuppc.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_smb')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_apcupsd')
+
+            file_append("/etc/nagios/nrpe.cfg", "command[check_disk1]=/usr/lib/nagios/plugins/check_disk -w 7% -c 3% -p / -p /var/lib/vz")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_swap]=/usr/lib/nagios/plugins/check_swap -w 80% -c 70%")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_uptime]=/usr/lib/nagios/plugins/check_uptime")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_smtp]=/usr/lib/nagios/plugins/check_smtp -H localhost")
+
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_hddtemp_ssd1]=sudo /usr/lib/nagios/plugins/check_hddtemp.sh /dev/disk/by-id/ata-xxx 63 65")
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_smart_ssd2]=sudo /usr/lib/nagios/plugins/check_smart -d /dev/disk/by-id/ata-xxx -i ata")
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_smart_hdd1]=sudo /usr/lib/nagios/plugins/check_smart -d /dev/disk/by-id/ata-xxx -i scsi")
+
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_zpool-1]=sudo /usr/lib/nagios/plugins/check_zpool-1.sh")
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_zpool]=sudo /usr/lib/nagios/plugins/check_zpool.sh -p ALL -w 95 -c 98")
+
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_bcharge]=/usr/lib/nagios/plugins/check_apcupsd -c 50 -w 70 bcharge")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_loadpct]=/usr/lib/nagios/plugins/check_apcupsd -c 90 -w 80 loadpct")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_timeleft]=/usr/lib/nagios/plugins/check_apcupsd -c 5 -w 10 timeleft")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_itemp]=/usr/lib/nagios/plugins/check_apcupsd -c 45 -w 35 itemp")
+
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_Core_0]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "Core 0"=57,62')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_Core_2]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "Core 2"=57,62')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_systin]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "SYSTIN"=45,50')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_cputin]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "CPUTIN"=45,50')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_auxtin]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "AUXTIN"=35,40')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_fan1]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -l "fan1"=3000,2500')
+
+            file_append("/etc/nagios/nrpe.cfg", "command[check_backuppc_hosts]=sudo -u backuppc /usr/lib/nagios/plugins/check_backuppc")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_backuppc]=/usr/lib/nagios/plugins/check_proc_backuppc.sh")
+
+            file_replace_line("/etc/nagios/nrpe.cfg", "check_total_procs", "command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 600 -c 650")
+
+        elif self.monitoring == "checkmk":
+
+            if self.mgmt_ip != "":
+                file_replace_line("/etc/xinetd.d/check_mk", "only_from", "only_from = %s" % self.mgmt_ip)
+
+            # Check-MK-Agent Config
+            run_cmd('wget -O /tmp/mk_smart https://git.styrion.net/iteas/check_mk-smart-plugin/raw/master/smart')
+            run_cmd('mv /tmp/mk_smart /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_apcupsd https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_apcupsd')
+            run_cmd('mv /tmp/mk_apcupsd /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_dmi_sysinfo https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_dmi_sysinfo')
+            run_cmd('mv /tmp/mk_dmi_sysinfo /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_inventory https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_inventory')
+            run_cmd('mv /tmp/mk_inventory /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_lmsensors https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_lmsensors')
+            run_cmd('mv /tmp/mk_lmsensors /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_logins https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_logins')
+            run_cmd('mv /tmp/mk_logins /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_nfsexports https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_nfsexports')
+            run_cmd('mv /tmp/mk_nfsexports /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_netstat https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_netstat')
+            run_cmd('mv /tmp/mk_netstat /usr/lib/check_mk_agent/plugins/')
+            run_cmd('chmod +x /usr/lib/check_mk_agent/plugins/mk_*', argShell=True)
+
+        # APC
+        run_cmd('wget -O /etc/apcupsd/apcupsd.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/etc/apcupsd.conf')
+        file_replace_line("/etc/default/apcupsd", "ISCONFIGURED", "ISCONFIGURED=yes")
+        run_cmd('systemctl enable apcupsd.service')
+
+        # Nano
+        run_cmd('wget -O /tmp/nano.tar https://ftp.iteas.at/public/hp/proxmox/nano.tar')
+        run_cmd('tar -xf /tmp/nano.tar -C /root')
+        run_cmd('rm /tmp/nano.tar')
+
+        # ZSH
+        run_cmd('wget -O /tmp/zshrc_root https://ftp.iteas.at/public/hp/proxmox/zshrc_root')
+        run_cmd('mv /tmp/zshrc_root /root/.zshrc')
+        file_replace_line("/root/.zshrc", "iteas.local", 'export PS1="%UDomain:%u %B%F{yellow}' + self.domain + ' $PS1"')
+        run_cmd('usermod -s /bin/zsh root')
+
+        # Postfix
+        file_replace_line("/etc/postfix/main.cf", "myhostname=", "myhostname=" + self.fqdn + ".monitoring.iteas.at")
+        file_replace_line("/etc/postfix/main.cf", "relayhost =", "relayhost = smtp.styrion.net")
+        run_cmd('systemctl restart postfix.service')
+
+        # PIGZ
+        run_cmd('mv /bin/gzip /bin/gzip_backup')
+        run_cmd('ln -s /usr/bin/pigz /bin/gzip')
+
+        # SystemD
+        run_cmd('wget -O /etc/systemd/system/rc.local.shutdown.service https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown.service')
+        run_cmd('wget -O /etc/rc.local.shutdown https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown')
+        run_cmd('systemctl enable rc.local.shutdown.service')
+        
+        # FĂĽge USB Storgage fĂĽr Automount hinzu
+        run_cmd('pvesm add dir USB -path /media/usb0 -maxfiles 0 -content vztmpl,iso,backup')
+
+        # SysCTL
+        file_append("/etc/sysctl.conf", "vm.swappiness=0")
+        file_append("/etc/sysctl.conf", "fs.inotify.max_user_watches=1048576")
+
+        # BackupPC
+        if self.backuppc == True:
+            run_cmd('apt-get install backuppc -y')
+            run_cmd('setcap cap_net_raw+ep /bin/ping6')
+            run_cmd('setcap cap_net_raw+ep /bin/ping')
+
+            if self.filesystem == "zfs":
+                run_cmd('zfs create rpool/ROOT/pve-1/backuppc')
+                run_cmd("cp -a /var/lib/backuppc/* /backuppc/.", argShell=True)
+                run_cmd("chown -R backuppc:backuppc /backuppc")
+                file_replace_line("/etc/backuppc/config.pl", "$Conf{TopDir}      =", "$Conf{TopDir}      = '/backuppc';")
+                file_replace_line("/etc/backuppc/config.pl", "$Conf{LogDir}      =", "$Conf{LogDir}      = '/backuppc/log';")
+            else:
+                run_cmd('mkdir /var/lib/vz/backuppc')
+                run_cmd("cp -a /var/lib/backuppc/* /var/lib/vz/backuppc/.", argShell=True)
+                run_cmd("chown -R backuppc:backuppc /var/lib/vz/backuppc")
+                file_replace_line("/etc/backuppc/config.pl", "$Conf{TopDir}      =", "$Conf{TopDir}      = '/var/lib/vz/backuppc';")
+                file_replace_line("/etc/backuppc/config.pl", "$Conf{LogDir}      =", "$Conf{LogDir}      = '/var/lib/vz/backuppc/log';")
+
+            run_cmd('systemctl restart backuppc.service')
+
+            file_replace_line("/root/.zshrc", "prompt fade red", "prompt fade blue")
+            file_replace_line("/root/.zshrc", 'echo "HELLO ADMINISTRATOR!"', 'echo "HELLO SERVICEUSER!"')
+
+        ############ Konfiguration fĂĽr Backup-Server
+        if self.machine_type == "backup":
+            # NFS, Samba & ZFS
+            run_cmd('apt-get install nfs-kernel-server samba -y')
+            file_create("/etc/exports", "/export 	*(acl,sync,no_subtree_check,fsid=0,rw)")
+            clients = ""
+            for client in self.share_clients:
+                clients += "%s(sync,no_subtree_check,no_root_squash,rw) " % client
+
+            #password = gui_password_verify_box("Samba Passwort", "Geben Sie das Passwort fuer den Samba Benutzer 'admin' an:", "Geben Sie das Passwort fuer den Samba Benutzer 'admin' erneut an:")
+            password = SMB_ADMIN_PASSWD
+            run_cmd("useradd backup -m -G sambashare -p '%s'" % password, argShell=True)
+            run_cmd("(echo '%s'; echo '%s') | smbpasswd -a backup" % (password, password), argShell=True)
+            run_cmd('wget -O /etc/samba/smb.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/samba/backup_default_smb.conf')
+
+            backup_root = ""
+            if self.filesystem == "zfs":
+                run_cmd('zfs create rpool/ROOT/pve-1/sicherung')
+                run_cmd('zfs create rpool/ROOT/pve-1/Backup')
+                file_append("/etc/zfs/zed.d/zed.rc", 'ZED_EMAIL_ADDR="root"')
+                file_replace_line("/etc/samba/smb.conf", "path = /var/lib/vz/Backup", "path = /Backup")
+                file_replace_line("/etc/nagios/nrpe.cfg", "check_total_procs", "command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 800 -c 1000")
+
+                file_append("/etc/exports", "/sicherung     %s" % clients)
+                file_append("/etc/exports", "/Backup     %s" % clients)
+
+                backup_root = "/Backup"
+            else:
+                run_cmd('mkdir /var/lib/vz/sicherung')
+                run_cmd('mkdir /var/lib/vz/Backup')
+                file_append("/etc/exports", "/var/lib/vz/sicherung     %s" % clients)
+                file_append("/etc/exports", "/var/lib/vz/Backup     %s" % clients)
+                backup_root = "/var/lib/vz/Backup"
+
+            # Folders for backupassist
+            run_cmd('mkdir %s/Daten' % backup_root, argShell=True)
+            run_cmd('mkdir %s/Exchange' % backup_root, argShell=True)
+            run_cmd('mkdir %s/Image' % backup_root, argShell=True)
+            run_cmd('mkdir "%s/Image/Buero PCs"' % backup_root, argShell=True)
+            run_cmd('mkdir "%s/Image/Produktion PCs"' % backup_root, argShell=True)
+            run_cmd('mkdir "%s/Recovery ISO"' % backup_root, argShell=True)
+            run_cmd('mkdir %s/SQL' % backup_root, argShell=True)
+            run_cmd("chown -R backup:sambashare %s" % backup_root)
+
+            file_replace_line("/etc/samba/smb.conf", "workgroup = iteas.local", "\tworkgroup = %s" % self.domain)
+
+            run_cmd('systemctl enable nfs-kernel-server')
+            run_cmd('systemctl start nfs-kernel-server')
+
+            run_cmd('systemctl enable smbd')
+            run_cmd('systemctl start smbd')
+
+            # Webmin
+            run_cmd('apt-get install perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl apt-show-versions python -y')
+            run_cmd('wget -O /tmp/webmin_1.840_all.deb http://downloads.sourceforge.net/project/webadmin/webmin/1.840/webmin_1.840_all.deb')
+            run_cmd('dpkg --install /tmp/webmin_1.840_all.deb')
+            file_append("/etc/webmin/config", "lang_root=de")
+            file_append("/etc/webmin/config", "theme_root=authentic-theme")
+            file_append("/etc/webmin/miniserv.conf", "preroot_root=authentic-theme")
+            run_cmd('mkdir /etc/webmin/authentic-theme')
+            run_cmd('wget -O /etc/webmin/authentic-theme/favorites.json https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/webmin/favorites.json')
+            run_cmd('/etc/init.d/webmin restart')
+
+
+        ############ Konfiguration fĂĽr HP
+        if self.machine_vendor == "hp":
+            # HP-Tools
+            file_create("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP jessie/current non-free")
+            file_append("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP/debian jessie/current non-free")
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 527BC53A2689B887')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com FADD8D64B1275EA3')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C208ADDE26C2B797')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 26C2B797')
+            run_cmd('apt-get update')
+            run_cmd('apt-get install hp-health hpssacli hponcfg -y')
+            run_cmd('ln -s /usr/sbin/hpssacli /usr/sbin/hpacucli')
+            run_cmd('/etc/init.d/hp-asrd stop')
+            run_cmd('/etc/init.d/hp-health stop')
+
+            # Monitoring-Agent
+            if self.monitoring == "nagios":
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hparray http://ftp.iteas.at/public/nagios/plugins/check_hparray')
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hpasm http://ftp.iteas.at/public/nagios/plugins/check_hpasm')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hparray')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hpasm')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_cciss]=sudo /usr/lib/nagios/plugins/check_hparray -s 0 -v")
+                file_append("/etc/nagios/nrpe.cfg", "command[check_hpasm]=/usr/lib/nagios/plugins/check_hpasm --perfdata=short")
+
+        elif self.machine_vendor == "dell":
+            # Dell-Tools
+            file_create("/etc/apt/sources.list.d/linux.dell.com.sources.list", "deb http://linux.dell.com/repo/community/ubuntu wheezy openmanage")
+            run_cmd('gpg --keyserver pool.sks-keyservers.net --recv-key 1285491434D8786F')
+            run_cmd('gpg -a --export 1285491434D8786F | apt-key add -', argShell=True)
+            run_cmd('apt-get update')
+            run_cmd('apt-get install srvadmin-hapi srvadmin-isvc srvadmin-storageservices srvadmin-base srvadmin-omcommon srvadmin-sysfsutils srvadmin-server-cli dcism -y --force-yes')
+            run_cmd('apt-get install srvadmin-idrac srvadmin-idrac-ivmcli srvadmin-idrac-vmcli srvadmin-idrac7 srvadmin-idracadm srvadmin-idracadm7 -y --force-yes')
+            run_cmd_output('systemctl enable dcismeng.service')
+            run_cmd_output('systemctl enable instsvcdrv.service')
+
+            # Monitoring-Agent
+            if self.monitoring == "nagios":
+                run_cmd('wget -O /tmp/check-openmanage_3.7.12-1_all.deb https://ftp.iteas.at/public/nagios/plugins/check-openmanage_3.7.12-1_all.deb')
+                run_cmd('dpkg -i /tmp/check-openmanage_3.7.12-1_all.deb')
+
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_openmanage https://ftp.iteas.at/public/nagios/plugins/check_openmanage')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_openmanage')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_openmanage]=/usr/lib/nagios/plugins/check_openmanage -p -I")
+
+
+        run_cmd('apt-get install -f')
+        if self.proxy == True:
+            run_cmd('rm /etc/apt/apt.conf.d/01proxy')
+
+        sum_txt = """-------------------------------------------------------------------------------
+ITEAS Proxmox Installationsbericht
+
+Loginmoeglichkeiten:
+  https://%s:8006 -> Weboberflaeche Virtualisierung
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  https://%s:10000 -> Weboberflaeche Webmin (NFSfreigaben, Samba, etc.)" % check_systemip(show_prefix=False)
+
+
+        sum_txt += """
+  SSH ueber CMD f.e "ssh root@%s"
+
+Folgende lokale Benutzer wurden angelegt:
+  root (Administrator) SSH, Virtualisierung, Webmin
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  backup (fuer den Zugriff auf Freigaben) Samba"
+
+        sum_txt += """
+
+Das Komplette Installationslog ist auf
+  /var/log/proxmox_install.log einsehbar.
+-------------------------------------------------------------------------------
+"""
+
+        fr = open("/root/proxmox_report.txt", "w")
+        fr.write(sum_txt)
+        fr.close()
+
+        gui_text_box("/root/proxmox_report.txt")
+
+        # Installation fertig
+        retval = gui_yesno_box("Installer", "Die Installation wurde abgeschlossen! Moechten Sie den PC/Server neustarten?")
+        if retval[0] == 0:
+            pbox = gui_progress_box("PC/Server wird automatisch neugestartet...", 0)
+            for x in range(0, 5):
+                pbox.update(x*20)
+                time.sleep(1)
+
+            pbox.finish()
+            run_cmd('reboot')
+        elif retval[0] == 1:
+            gui_message_box("Installer", "Sie muessen den PC/Server manuell neustarten um die Installation abzuschliessen!")
+
+
+i = Installer()
+i.start()
+logger.close()
diff --git a/proxmox_install_PVE5.py b/proxmox_install_PVE5.py
new file mode 100755
index 0000000..80e2c5b
--- /dev/null
+++ b/proxmox_install_PVE5.py
@@ -0,0 +1,906 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+#
+# (c) Rene Hadler, Mario Loderer, iteas IT Services GmbH
+# support@iteas.at
+# www.iteas.at
+#
+
+import sys
+import time
+import socket
+import subprocess
+import requests
+
+# Globale Variablen
+VERSION = "0.8.8"
+TITLE = "iteas Proxmox Installer " + VERSION
+CHECK_INTERNET_IP = "77.235.68.39"
+VM_TEMPLATE_CIFS_SHARE = "//srv-backup01.iteas.at/archiv-replica"
+VM_TEMPLATE_CIFS_USER = "localbackup"
+SMB_ADMIN_PASSWD = "backmode123"
+
+
+try:
+    CONSOLE_ROWS, CONSOLE_COLS = subprocess.check_output(['stty', 'size']).split()
+except:
+    CONSOLE_ROWS = 40
+    CONSOLE_COLS = 100
+
+GUI_WIN_WIDTH = 100 if int(CONSOLE_COLS) > 110 else (int(CONSOLE_COLS) - 10)
+
+class Logger:
+    def __init__(self):
+        self.f = fr = open("proxmox_install.log", "w+")
+
+    def log(self, text):
+        self.f.write(text)
+
+    def close(self):
+        self.f.close()
+
+logger = Logger()
+
+# Befehle ausfĂĽhren
+def run_cmd(command, argShell=False):
+    try:
+        return subprocess.call(command.split(" ") if argShell == False else command, shell=argShell)
+    except:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Fehler", "Befehl <%s> war nicht erfolgreich, Fehlermeldung: %s -- Installation abbrechen?" % (command, e))
+        if retval[0] == 0:
+            exit(1)
+
+def run_cmd_output(command, argShell=False):
+    p = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read().decode('UTF-8'), p.stderr.read().decode('UTF-8'))
+
+def run_cmd_stdout(command, argShell=False):
+    p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read().decode('UTF-8'))
+
+def run_cmd_stderr(command, argShell=False):
+    p = subprocess.Popen(command, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stderr.read().decode('UTF-8'))
+
+def run_cmd_stdin(command, argShell=False):
+    p = subprocess.Popen(command, stdin=subprocess.PIPE, shell=argShell)
+    return p
+
+# Oberflächen / GUI
+def gui_message_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--msgbox", text, "--title", title, "8", str(GUI_WIN_WIDTH)])
+
+def gui_text_box(file):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--textbox", file, "20", str(GUI_WIN_WIDTH)])
+
+def gui_input_box(title, text, default=""):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--inputbox", text, "8", str(GUI_WIN_WIDTH), default, "--title", title])
+
+def gui_yesno_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--yesno", text, "--title", title, "8", str(GUI_WIN_WIDTH)])
+
+def gui_password_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--passwordbox", text.encode('UTF-8'), "8", str(GUI_WIN_WIDTH), "--title", title.encode('UTF-8')])
+
+def gui_menu_box(title, text, menu):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--menu", text, "--title", title, "24", str(GUI_WIN_WIDTH), "18"] + menu)
+
+def gui_checklist_box(title, text, checklist):
+    ret = run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--checklist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + checklist)
+    return (ret[0], [] if ret[1] == "" else [x.replace('"', "") for x in ret[1].split(" ")])
+
+def gui_radiolist_box(title, text, radiolist):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--radiolist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + radiolist)
+
+class gui_progress_box():
+    def __init__(self, text, progress):
+        self.p = run_cmd_stdin(["whiptail", "--backtitle", TITLE, "--gauge", text, "6", "50", str(progress)])
+
+    def update(self, prog):
+        upd = "%s\n" % prog
+        self.p.stdin.write(upd.encode('utf-8'))
+        self.p.stdin.flush()
+
+    def finish(self):
+        self.p.stdin.close()
+
+def gui_password_verify_box(title, text, text2):
+    password = ""
+    while password == "":
+        retval = gui_password_box(title, text)
+        if retval[1] == "":
+            continue
+
+        retval2 = gui_password_box(title, text2)
+        if retval2[1] == "":
+            continue
+
+        if retval[1] == retval2[1]:
+            password = retval[1]
+        else:
+            gui_message_box(title, "Fehler bei der Passworteingabe, die Passwoerter stimmen nicht ueberein!")
+
+    return password
+
+# Sonstige Funktionen
+def check_internet():
+    try:
+        s = socket.create_connection((CHECK_INTERNET_IP, 80), 5)
+        return True
+    except:
+        return False
+
+def check_filesystem():
+    try:
+        zfsc = run_cmd_output('zfs list')
+        if zfsc[0] == 1 or zfsc[2].find('no datasets') != -1:
+            return 'standard'
+        else:
+            return 'zfs'
+    except:
+        return 'standard'
+
+def check_systemip(show_prefix = True):
+    zfsc = run_cmd_stdout("ip addr show vmbr0 | grep 'inet' | grep -v 'inet6' | cut -d' ' -f6", argShell=True)
+    if show_prefix == True:
+        return zfsc[1].strip()
+    else:
+        return zfsc[1].strip().split("/")[0]
+
+def check_systemipnet():
+    try:
+        zfsc = check_systemip()
+        if zfsc == '':
+            return ''
+        else:
+            # Nicht immer true
+            ipf = zfsc.split(".")
+            return "%s.%s.%s.0/%s" % (ipf[0], ipf[1], ipf[2], ipf[3].split("/")[1])
+    except:
+        return ''
+
+def file_replace_line(file, findstr, replstr, encoding='utf-8'):
+    fp = open(file, "r+", encoding=encoding)
+    buf = ""
+    for line in fp.readlines():
+        if line.find(findstr) != -1:
+            line = replstr + "\n"
+
+        buf += line
+
+    fp.close()
+    fr = open(file, "w+", encoding=encoding)
+    fr.write(buf)
+    fr.close()
+
+def file_create(file, str):
+    fr = open(file, "w+")
+    fr.write(str + "\n")
+    fr.close()
+
+def file_append(file, str):
+    fr = open(file, "a")
+    fr.write(str + "\n")
+    fr.close()
+
+# Installer Start
+class Installer():
+    def __init__(self):
+        self.internet = False
+        self.fqdn = socket.getfqdn()
+        try:
+            self.domain = self.fqdn.split(".")[1] + "." + self.fqdn.split(".")[2]
+            self.hostname = socket.gethostname()
+        except:
+            gui_message_box("Installer", "FQDN ist nicht richtig gesetzt, Installation wird abgebrochen!")
+            exit(1)
+
+        self.machine_vendor = "other"
+        self.machine_type = "virt"
+        self.environment = "stable"
+        self.monitoring = "nagios"
+        self.license = ""
+        self.filesystem = ""
+        self.mgmt_ip = ""
+        self.backuppc = False
+        self.vm_import = []
+        self.share_clients = []
+        self.proxy = True
+        self.desktop = "kein"
+
+        # Installer Variablen
+        self.MACHINE_VENDORS = {"hp": "HP < Gen 10", "hp10": "HP Gen 10", "dell": "Dell iDRAC < 9", "dell9": "Dell iDRAC 9", "other": "Andere"}
+        self.MACHINE_TYPES = {"virt": "Virtualisierung", "backup": "Backup"}
+        self.ENVIRONMENTS = {"stable": "Stabile Proxmox Enterprise Updates", "test": "Proxmox Testing Updates", "noupdate": "Keine Proxmox Updates"}
+        self.MONITORINGS = {"nagios": "Nagios NRPE", "checkmk": "CheckMK Agent"}
+        self.FILESYSTEMS = {"standard": "Standard (ext3/4, reiserfs, xfs)", "zfs": "ZFS"}
+        self.DESKTOPS = {"kein": "Nein", "plasma": "KDE5-Plasma", "i3": "i3-WM (testing)"}
+        self.VM_IMPORTS = {
+                            "114": {"name": "ITEAS Managementserver", "template": False},
+                            "139": {"name": "Windows 7 Pro", "template": True},
+                            "125": {"name": "Windows 10 Pro EDBS alter Updatestand", "template": True},
+                            "166": {"name": "Windows 10 Pro", "template": True},
+                            "117": {"name": "Windows Server 2008 r2", "template": True},
+                            "120": {"name": "Windows Server 2012 r2", "template": True},
+                            "162": {"name": "Windows Server 2016", "template": True},
+                            "169": {"name": "Windows Server 2019", "template": True},
+                            "131": {"name": "CentOS Server Standard", "template": True},
+                            "152": {"name": "CentOS Server StyrionLDAP", "template": True},
+                            "145": {"name": "CentOS Mailserver", "template": True},
+                            "129": {"name": "Ubuntu Server Standard", "template": True},
+                            "101": {"name": "Ubuntu Server StyrionLDAP", "template": True}
+                           }
+
+    def start(self):
+        gui_message_box("Installer", "Willkommen beim iteas Proxmox Installer!")
+        self.internet = check_internet()
+        self.filesystem = check_filesystem()
+        if check_systemipnet() != '':
+            self.share_clients.append(check_systemipnet())
+        self.step1()
+
+    def step1(self):
+        step1_val = gui_menu_box("Schritt 1", "Kontrollieren bzw. konfigurieren Sie die entsprechenden Werte und gehen Sie dann auf 'Weiter'.",
+                                    ["Internet", "JA" if self.internet == True else "NEIN",
+                                     "Hostname", self.hostname,
+                                     "Domain", self.domain,
+                                     "Dateisystem", self.FILESYSTEMS[self.filesystem],
+                                     " ", " ",
+                                     "Maschinenhersteller", self.MACHINE_VENDORS[self.machine_vendor],
+                                     "Maschinentyp", self.MACHINE_TYPES[self.machine_type],
+                                     "BackupPC-LXC", "Nein" if self.backuppc == False else "Ja",
+                                     "Proxmox-Umgebung", self.ENVIRONMENTS[self.environment],
+                                     "Proxmox-Lizenz", "Keine" if self.license == "" else self.license,
+                                     "VM-Template-Import", ",".join([self.VM_IMPORTS[x]["name"] for x in self.vm_import]) if len(self.vm_import) > 0 else "Keine",
+                                     "Freigabe-Clients", ",".join([x for x in self.share_clients]) if len(self.share_clients) > 0 else "Alle",
+                                     "Mgmt-IP", "Keine" if self.mgmt_ip == "" else self.mgmt_ip,
+                                     "apt-Proxy", "Nein" if self.proxy == False else "Ja",
+                                     "Desktop", self.DESKTOPS[self.desktop],
+                                     "Monitoring-Agent", self.MONITORINGS[self.monitoring],
+                                     " ", " ",
+                                     "Weiter", "Installation fortsetzen"])
+
+        # Abbrechen
+        if step1_val[0] == 1 or step1_val[0] == 255:
+            exit(0)
+
+        # Eintrag wurde gewählt
+        if step1_val[1] == "Maschinenhersteller":
+            self.step1_machine_vendor()
+
+        elif step1_val[1] == "Maschinentyp":
+            self.step1_machine_type()
+
+        elif step1_val[1] == "Proxmox-Umgebung":
+            self.step1_environment()
+
+        elif step1_val[1] == "Monitoring-Agent":
+            self.step1_monitoring()
+
+        elif step1_val[1] == "Proxmox-Lizenz":
+            self.step1_license()
+
+        elif step1_val[1] == "Mgmt-IP":
+            self.step1_mgmtip()
+
+        elif step1_val[1] == "apt-Proxy":
+            self.step1_aptproxy()
+
+        elif step1_val[1] == "Desktop":
+            self.step1_desktop()
+
+        elif step1_val[1] == "BackupPC-LXC":
+            self.step1_backuppc()
+
+        elif step1_val[1] == "VM-Template-Import":
+            self.step1_vmtemplateimport()
+
+        elif step1_val[1] == "Internet":
+            check_internet()
+            self.step1()
+
+        elif step1_val[1] == "Freigabe-Clients":
+            self.step1_shareclients()
+
+        elif step1_val[1] == "Weiter":
+            self.step2()
+
+        else:
+            self.step1()
+
+    def step1_machine_vendor(self):
+        list = []
+        for key, val in self.MACHINE_VENDORS.items():
+            list += [key, val, "ON" if self.machine_vendor == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Maschinenhersteller", "Waehlen sie den passenden Maschinenhersteller", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_vendor = retval[1]
+        self.step1()
+
+    def step1_machine_type(self):
+        list = []
+        for key, val in self.MACHINE_TYPES.items():
+            list += [key, val, "ON" if self.machine_type == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Maschinentyp", "Waehlen sie den passenden Maschinentyp", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_type = retval[1]
+        self.step1()
+
+    def step1_environment(self):
+        list = []
+        for key, val in self.ENVIRONMENTS.items():
+            list += [key, val, "ON" if self.environment == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Proxmox-Umgebung", "Waehlen sie die Proxmox-Umgebung", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.environment = retval[1]
+        self.step1()
+
+    def step1_monitoring(self):
+        list = []
+        for key, val in self.MONITORINGS.items():
+            list += [key, val, "ON" if self.monitoring == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Monitoring-Agent", "Waehlen sie den Monitoring-Agenten", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.monitoring = retval[1]
+        self.step1()
+
+    def step1_license(self):
+        retval = gui_input_box("Schritt 1: Proxmox-Lizenz", "Geben Sie den Proxmox-Schluessel ein", self.license)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.license = retval[1]
+        self.step1()
+
+    def step1_mgmtip(self):
+        retval = gui_input_box("Schritt 1: Mgmt-IP", "Geben Sie die IP des Managementservers ein", self.mgmt_ip)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.mgmt_ip = retval[1]
+        self.step1()
+
+    def step1_aptproxy(self):
+        retval = gui_yesno_box("Installer", "Mochten Sie den iteas apt-Proxy benutzen?")
+        if retval[0] == 0:
+            self.proxy = True
+        elif retval[0] == 1:
+            self.proxy = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1()
+            return
+
+        self.step1()
+
+    def step1_desktop(self):
+        list = []
+        for key, val in self.DESKTOPS.items():
+            list += [key, val, "ON" if self.desktop == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Proxmox-Desktop", "Waehlen sie einen Desktop", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.desktop = retval[1]
+        self.step1()
+
+    def step1_backuppc(self):
+        retval = gui_yesno_box("Installer", "Mochten Sie BackupPC via LXC dazuinstallieren?")
+        if retval[0] == 0:
+            self.backuppc = True
+        elif retval[0] == 1:
+            self.backuppc = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1()
+            return
+
+        self.step1()
+
+    def step1_vmtemplateimport(self):
+        list = []
+        for key, val in self.VM_IMPORTS.items():
+            list += [key, val["name"], "ON" if key in self.vm_import else "OFF"]
+
+        retval = gui_checklist_box("Schritt 1: VM-Template-Import", "Waehlen sie die VMs die importiert werden sollen", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.vm_import = []
+        for val in retval[1]:
+            self.vm_import += [val]
+
+        self.step1()
+
+    def step1_shareclients(self):
+        retval = gui_input_box("Schritt 1: Freigabe-Clients", "Geben Sie die Clients/Netze an, die Zugriffe auf die Freigaben am Proxmox Host haben sollen. Mehrere Eintraege muessen durch Leerzeichen getrennt sein.", " ".join(self.share_clients))
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.share_clients = retval[1].split(" ")
+        self.step1()
+
+    def step2(self):
+        if self.environment == "stable" and self.license == "":
+            gui_message_box("Installer", "Sie muessen eine Lizenz angeben wenn Enterprise Updates ausgewaehlt wurden!")
+            self.step1()
+            return
+
+        if self.internet == False:
+            gui_message_box("Installer", "Es muss eine Internetverbindung bestehen um fortzufahren!")
+            self.step1()
+            return
+
+        ############ Allgemeine Konfiguration
+        if self.license != "":
+            retval = run_cmd_output('pvesubscription set ' + self.license)
+            if retval[0] == 255:
+                gui_message_box("Proxmox Lizenzinstallation", "Die Lizenz konnte nicht installiert werden, bitte pruefen Sie Ihre Lizenznummer. Fehler: " + retval[2])
+                self.step1()
+                return
+
+            time.sleep(30)
+
+            # Warte maximal fĂĽr 5 Minuten fĂĽr Registrierung
+            maxwait = 300
+            curwait = 0
+            lictest = run_cmd_stdout('pvesubscription get', argShell=True)
+            while lictest[1].find('status: Active') == -1 and curwait < maxwait:
+                print("Warte auf Registrierung der Proxmox-Subscription..." + str(curwait))
+                time.sleep(10)
+                lictest = run_cmd_stdout('pvesubscription get', argShell=True)
+                curwait += 10
+
+            # Warte maximal fĂĽr 5 Minuten fĂĽr Enterprise-Repo Zugriff
+            curwait = 0
+            httpuser = run_cmd_stdout("pvesubscription get | grep 'key:.*' | cut -f2 -d:", argShell=True)[1].strip()
+            httppass = run_cmd_stdout("pvesubscription get | grep 'serverid:.*' | cut -f2 -d:", argShell=True)[1].strip()
+
+            repotest = requests.get('https://enterprise.proxmox.com/debian/pve', auth=(httpuser, httppass))
+            while repotest.status_code != requests.codes.ok and curwait < maxwait:
+                print("Warte auf Freischaltung des Enterprise-Repos..." + str(curwait))
+                time.sleep(10)
+                repotest = requests.get('https://enterprise.proxmox.com/debian/pve', auth=(httpuser, httppass))
+                curwait += 10
+
+        # Proxmox Testing Quellen aktivieren
+        if self.environment == "test":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian/pve stretch pve-enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "deb http://download.proxmox.com/debian/pve stretch pve-no-subscription")
+        elif self.environment == "noupdate":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian/pve stretch pve-enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "# deb http://download.proxmox.com/debian/pve stretch pve-no-subscription")
+
+        # If lvm-thin convert to standard file storage if backup-machine
+        if self.machine_type == "backup" and run_cmd('pvesh get /storage | grep -i lvmthin', argShell=True) == 0:
+            run_cmd('pvesh delete /storage/local-lvm')
+            run_cmd('lvremove /dev/pve/data -f')
+            run_cmd('lvcreate -Wy -l100%FREE -ndata pve')
+            run_cmd('mkfs.ext4 -m1 /dev/pve/data')
+            run_cmd('mount /dev/pve/data /var/lib/vz')
+            file_append("/etc/fstab", "/dev/pve/data /var/lib/vz ext4 defaults 0 2")
+
+        # Mount Template NFS-Share und importiere VMs
+        storage = "local"
+        if run_cmd('pvesh get /storage | grep -i lvmthin', argShell=True) == 0:
+            storage = "local-lvm"
+
+        if len(self.vm_import) > 0:
+            retval = gui_password_box("Samba Passwort benötigt", "Bitte das Passwort für Share " + VM_TEMPLATE_CIFS_SHARE + " und Benutzer " + VM_TEMPLATE_CIFS_USER + " eingeben.")
+            VM_TEMPLATE_CIFS_PASS = retval[1]
+            if run_cmd('mount -t cifs -o user=' + VM_TEMPLATE_CIFS_USER + ",password=" + VM_TEMPLATE_CIFS_PASS + " " + VM_TEMPLATE_CIFS_SHARE + ' /mnt') == 0:
+                for vm_id in self.vm_import:
+                    (ret, filename) = run_cmd_stdout("ls -t /mnt/dump/vzdump-qemu-%s*vma* | head -n1" % vm_id, argShell=True)
+                    if filename != "":
+                        run_cmd("qmrestore %s %s -storage %s" % (filename.strip(), vm_id, storage))
+                        if self.VM_IMPORTS[vm_id]["template"] == True:
+                            run_cmd("qm template %s" % vm_id)
+
+                run_cmd('umount /mnt')
+            else:
+                gui_message_box("Installer", "NFS konnte nicht gemounted werden, VMs werden nicht importiert!")
+
+            VM_TEMPLATE_CIFS_PASS = ""
+
+        # Apt-Proxy Cache
+        if self.proxy == True:
+            file_create("/etc/apt/apt.conf.d/01proxy", 'Acquire::http { Proxy "http://10.69.99.10:3142"; };')
+
+        # Installieren allgemeine Tools und Monitoring-Agent
+        run_cmd('apt-get update')
+        run_cmd('apt-get install dirmngr -y')
+        file_create("/etc/apt/sources.list.d/iteas.list", "deb https://apt.iteas.at/iteas stretch main")
+        run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 2FAB19E7CCB7F415', argShell=True)
+        run_cmd('apt-get update')
+        run_cmd('apt-get dist-upgrade -y')
+        run_cmd('apt-get install dirmngr htop unp postfix sudo screen zsh tmux bwm-ng pigz sysstat ethtool nload apcupsd ntfs-3g sl gawk ca-certificates-iteas-enterprise -y')
+        run_cmd('apt install at -y')
+        if self.monitoring == "nagios":
+            run_cmd('apt-get install nagios-nrpe-server -y')
+        elif self.monitoring == "checkmk":
+            run_cmd('apt-get install xinetd check-mk-agent -y')
+
+        # SUDOers
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /usr/bin/rsync")
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /bin/tar")
+
+        # Monitoring Konfiguration
+        if self.monitoring == "nagios":
+
+            # SUDOers
+            file_append("/etc/sudoers", "nagios      ALL=(ALL) NOPASSWD: /usr/lib/nagios/plugins/")
+            file_append("/etc/sudoers", "nagios      ALL=(ALL) NOPASSWD: /usr/sbin/hpssacli")
+            file_append("/etc/sudoers", "nagios      ALL=(ALL) NOPASSWD: /sbin/hpasmcli")
+            file_append("/etc/sudoers", "#nagios      ALL=(ALL) NOPASSWD: /bin/su")
+            file_append("/etc/sudoers", "#nagios    ALL=(backuppc) NOPASSWD: ALL")
+
+            if self.mgmt_ip != "":
+                file_replace_line("/etc/nagios/nrpe.cfg", "allowed_hosts=", "allowed_hosts=127.0.0.1,%s" % self.mgmt_ip)
+
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_vg_size https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_win_disk.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_zpool-1.sh https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_zpool-1.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_zpool.sh https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_zpool.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_backuppc https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_backuppc')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_proc_backuppc.sh https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_proc_backuppc.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_smb https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_smb')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_apcupsd https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_apcupsd')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_vg_size')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_zpool-1.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_zpool.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_backuppc')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_proc_backuppc.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_smb')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_apcupsd')
+
+            file_append("/etc/nagios/nrpe.cfg", "command[check_disk1]=/usr/lib/nagios/plugins/check_disk -w 7% -c 3% -p / -p /var/lib/vz")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_swap]=/usr/lib/nagios/plugins/check_swap -w 30% -c 20%")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_uptime]=/usr/lib/nagios/plugins/check_uptime")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_smtp]=/usr/lib/nagios/plugins/check_smtp -H localhost")
+
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_hddtemp_ssd1]=sudo /usr/lib/nagios/plugins/check_hddtemp.sh /dev/disk/by-id/ata-xxx 63 65")
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_smart_ssd2]=sudo /usr/lib/nagios/plugins/check_smart -d /dev/disk/by-id/ata-xxx -i ata")
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_smart_hdd1]=sudo /usr/lib/nagios/plugins/check_smart -d /dev/disk/by-id/ata-xxx -i scsi")
+
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_zpool-1]=sudo /usr/lib/nagios/plugins/check_zpool-1.sh")
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_zpool]=sudo /usr/lib/nagios/plugins/check_zpool.sh -p ALL -w 95 -c 98")
+
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_bcharge]=/usr/lib/nagios/plugins/check_apcupsd -c 50 -w 70 bcharge")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_loadpct]=/usr/lib/nagios/plugins/check_apcupsd -c 90 -w 80 loadpct")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_timeleft]=/usr/lib/nagios/plugins/check_apcupsd -c 5 -w 10 timeleft")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_itemp]=/usr/lib/nagios/plugins/check_apcupsd -c 45 -w 35 itemp")
+
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_Core_0]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "Core 0"=57,62')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_Core_2]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "Core 2"=57,62')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_systin]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "SYSTIN"=45,50')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_cputin]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "CPUTIN"=45,50')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_auxtin]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "AUXTIN"=35,40')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_fan1]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -l "fan1"=3000,2500')
+
+            file_append("/etc/nagios/nrpe.cfg", "command[check_backuppc_hosts]=sudo -u backuppc /usr/lib/nagios/plugins/check_backuppc")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_backuppc]=/usr/lib/nagios/plugins/check_proc_backuppc.sh")
+
+            file_replace_line("/etc/nagios/nrpe.cfg", "check_total_procs", "command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 600 -c 650")
+
+        elif self.monitoring == "checkmk":
+
+            if self.mgmt_ip != "":
+                file_replace_line("/etc/xinetd.d/check_mk", "only_from", "only_from = %s" % self.mgmt_ip)
+
+            # Check-MK-Agent Config
+            run_cmd('wget -O /tmp/mk_smart https://git.styrion.net/iteas/check_mk-smart-plugin/raw/master/agents/smart')
+            run_cmd('mv /tmp/mk_smart /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_apcupsd https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_apcupsd')
+            run_cmd('mv /tmp/mk_apcupsd /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_dmi_sysinfo https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_dmi_sysinfo')
+            run_cmd('mv /tmp/mk_dmi_sysinfo /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_inventory https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_inventory')
+            run_cmd('mv /tmp/mk_inventory /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_lmsensors https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_lmsensors')
+            run_cmd('mv /tmp/mk_lmsensors /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_logins https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_logins')
+            run_cmd('mv /tmp/mk_logins /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_nfsexports https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_nfsexports')
+            run_cmd('mv /tmp/mk_nfsexports /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_netstat https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_netstat')
+            run_cmd('mv /tmp/mk_netstat /usr/lib/check_mk_agent/plugins/')
+            run_cmd('chmod +x /usr/lib/check_mk_agent/plugins/mk_*', argShell=True)
+
+        # APC
+        run_cmd('wget -O /etc/apcupsd/apcupsd.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/etc/apcupsd.conf')
+        file_replace_line("/etc/default/apcupsd", "ISCONFIGURED", "ISCONFIGURED=yes")
+        run_cmd('systemctl enable apcupsd.service')
+
+        # Nano
+        run_cmd('wget -O /tmp/nano.tar https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fproxmox&files=nano.tar')
+        run_cmd('tar -xf /tmp/nano.tar -C /root')
+        run_cmd('rm /tmp/nano.tar')
+
+        # ZSH
+        run_cmd('wget -O /tmp/zshrc_root https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fproxmox&files=zshrc_root')
+        run_cmd('mv /tmp/zshrc_root /root/.zshrc')
+        file_replace_line("/root/.zshrc", "iteas.local", 'export PS1="%UDomain:%u %B%F{yellow}' + self.domain + ' $PS1"', encoding='iso8859_15')
+        run_cmd('usermod -s /bin/zsh root')
+
+        # Postfix
+        file_replace_line("/etc/postfix/main.cf", "myhostname=", "myhostname=" + self.fqdn + ".monitoring.iteas.at")
+        file_replace_line("/etc/postfix/main.cf", "relayhost =", "relayhost = smtp.styrion.net")
+        run_cmd('systemctl restart postfix.service')
+
+        # PIGZ
+        run_cmd('mv /bin/gzip /bin/gzip_backup')
+        run_cmd('ln -s /usr/bin/pigz /bin/gzip')
+
+        # SystemD
+        run_cmd('wget -O /etc/systemd/system/rc.local.shutdown.service https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown.service')
+        run_cmd('wget -O /etc/rc.local.shutdown https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown')
+        run_cmd('systemctl enable rc.local.shutdown.service')
+        
+        # USB-Automount
+        run_cmd('apt-get install --no-install-recommends pve5-usb-automount -y')
+
+        # Kexec
+        run_cmd('echo "kexec-tools kexec-tools/load_kexec boolean false" | debconf-set-selections', argShell=True)
+        run_cmd('apt-get install kexec-tools -y')
+        run_cmd('wget -O /etc/systemd/system/kexec-pve.service https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/kexec-pve.service')
+        run_cmd('systemctl enable kexec-pve.service')
+
+        # SysCTL
+        file_append("/etc/sysctl.conf", "vm.swappiness=10")
+        file_append("/etc/sysctl.conf", "fs.inotify.max_user_watches=1048576")
+
+        # BackupPC
+        if self.backuppc == True:
+            # TODO Import LXC Template
+            pass
+
+        ############ Konfiguration fĂĽr Backup-Server
+        if self.machine_type == "backup":
+            # NFS, Samba & ZFS
+            run_cmd('apt-get install samba -y')
+
+            #password = gui_password_verify_box("Samba Passwort", "Geben Sie das Passwort fuer den Samba Benutzer 'admin' an:", "Geben Sie das Passwort fuer den Samba Benutzer 'admin' erneut an:")
+            password = SMB_ADMIN_PASSWD
+            run_cmd("groupadd localbackup", argShell=True)
+            run_cmd("useradd localbackup -m -g localbackup -p '%s'" % password, argShell=True)
+            run_cmd("(echo '%s'; echo '%s') | smbpasswd -a localbackup" % (password, password), argShell=True)
+            run_cmd('wget -O /etc/samba/smb.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/samba/backup_default_smb2.conf')
+
+            backup_root = ""
+            if self.filesystem == "zfs":
+                run_cmd('zfs create rpool/sicherung')
+                run_cmd('apt install zfs-zed -y')
+                file_replace_line("/etc/samba/smb.conf", "path = /var/lib/vz/sicherung", "\tpath = /rpool/sicherung")
+                file_replace_line("/etc/nagios/nrpe.cfg", "check_total_procs", "command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 800 -c 1000")
+                backup_root = "/rpool/sicherung"
+            else:
+                run_cmd('mkdir /var/lib/vz/sicherung')
+                backup_root = "/var/lib/vz/sicherung"
+
+            run_cmd("chown -R localbackup:localbackup %s" % backup_root)
+
+            file_replace_line("/etc/samba/smb.conf", "workgroup = kundendomain.local", "\tworkgroup = %s" % self.domain)
+            if len(self.share_clients) > 0:
+                file_replace_line("/etc/samba/smb.conf", "hosts allow =", "\thosts allow = %s" % " ".join(self.share_clients))
+
+            run_cmd('systemctl enable smbd')
+            run_cmd('systemctl start smbd')
+
+            # Webmin
+            file_create("/etc/apt/sources.list.d/webmin.list", "deb https://download.webmin.com/download/repository sarge contrib")
+            run_cmd("cd /tmp && wget http://www.webmin.com/jcameron-key.asc && apt-key add jcameron-key.asc", argShell=True)
+            run_cmd("apt-get install apt-transport-https curl git -y && apt-get update && apt-get install webmin -y", argShell=True)
+            file_append("/etc/webmin/config", "lang_root=de.UTF-8")
+            file_append("/etc/webmin/config", "theme_root=authentic-theme")
+            file_replace_line("/etc/webmin/config", "lang=", "lang=de.UTF-8")
+            file_append("/etc/webmin/miniserv.conf", "preroot_root=authentic-theme")
+            run_cmd('mkdir /etc/webmin/authentic-theme')
+            run_cmd('wget -O /etc/webmin/authentic-theme/favorites.json https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/webmin/favorites.json')
+            run_cmd('/etc/init.d/webmin restart')
+
+
+        ############  Konfiguration fĂĽr HP < Gen10
+        if self.machine_vendor == "hp":
+            # HP-Tools
+            file_create("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP stretch/current non-free")
+            file_append("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP/debian stretch/current non-free")
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 527BC53A2689B887')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com FADD8D64B1275EA3')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C208ADDE26C2B797')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 26C2B797')
+            run_cmd('apt-get update')
+            run_cmd('apt-get install hp-health ssacli hponcfg -y')
+            run_cmd('ln -s /usr/sbin/ssacli /usr/sbin/hpacucli')
+            run_cmd('/etc/init.d/hp-asrd stop')
+            run_cmd('/etc/init.d/hp-health stop')
+
+            # Nagios Monitoring-Agent
+            if self.monitoring == "nagios":
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hparray https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_hparray')
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hpasm https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_hpasm')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hparray')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hpasm')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_cciss]=sudo /usr/lib/nagios/plugins/check_hparray -s 0 -v")
+                file_append("/etc/nagios/nrpe.cfg", "command[check_hpasm]=/usr/lib/nagios/plugins/check_hpasm --perfdata=short")
+
+        ############ Konfiguration fĂĽr HP Gen10
+        elif self.machine_vendor == "hp10":
+            # HP-Tools
+            file_create("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP stretch/current non-free")
+            file_append("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP/debian stretch/current non-free")
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 527BC53A2689B887')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com FADD8D64B1275EA3')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C208ADDE26C2B797')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 26C2B797')
+            run_cmd('apt-get update')
+            run_cmd('apt-get install ssacli hponcfg binutils -y')
+            run_cmd('ln -s /usr/sbin/ssacli /usr/sbin/hpacucli')
+
+            # Nagios Monitoring-Agent
+            if self.monitoring == "nagios":
+                run_cmd('apt-get install libmonitoring-plugin-perl libxml-simple-perl -y')
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hparray https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_hparray')
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hpasm https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_hpasm')
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_ilo2_health.pl https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_ilo2_health.pl')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hparray')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hpasm')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_ilo2_health.pl')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_cciss]=sudo /usr/lib/nagios/plugins/check_hparray -s 0 -v")
+                file_append("/etc/nagios/nrpe.cfg", "command[check_hpasm]=/usr/lib/nagios/plugins/check_ilo2_health.pl -3 -H 1.1.1.1 -u nagios -p 'xxx' -a -c -o -g -d")
+
+        elif self.machine_vendor == "dell":
+            # Dell-Tools
+            file_create("/etc/apt/sources.list.d/linux.dell.com.sources.list", "deb http://linux.dell.com/repo/community/ubuntu jessie openmanage")
+            run_cmd('gpg --keyserver pool.sks-keyservers.net --recv-key 1285491434D8786F')
+            run_cmd('gpg -a --export 1285491434D8786F | apt-key add -', argShell=True)
+            run_cmd('apt-get update')
+            run_cmd('wget -O /tmp/libslp1_1.2.1-10+deb8u1_amd64.deb http://ftp.us.debian.org/debian/pool/main/o/openslp-dfsg/libslp1_1.2.1-10+deb8u1_amd64.deb')
+            run_cmd('wget -O /tmp/libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb http://ftp.us.debian.org/debian/pool/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb')
+            run_cmd('dpkg -i /tmp/libslp1_1.2.1-10+deb8u1_amd64.deb')
+            run_cmd('dpkg -i /tmp/libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb')
+            run_cmd('apt install srvadmin-storageservices rpm srvadmin-base srvadmin-idracadm8 srvadmin-itunnelprovider srvadmin-oslog srvadmin-server-cli -y --force-yes')
+            run_cmd('wget -O /tmp/dcism-2.3.0.deb8.deb http://linux.dell.com/repo/community/ubuntu/pool/jessie/openmanage/830/iSM/dcism-2.3.0.deb8.deb')
+            run_cmd('dpkg -i /tmp/dcism-2.3.0.deb8.deb')
+            run_cmd('ln -s /usr/bin/rpm /bin/rpm')
+
+            # Nagios Monitoring-Agent
+            if self.monitoring == "nagios":
+                run_cmd('wget -O /tmp/check-openmanage_3.7.12-1_all.deb https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check-openmanage_3.7.12-1_all.deb')
+                run_cmd('dpkg -i /tmp/check-openmanage_3.7.12-1_all.deb')
+
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_openmanage https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_openmanage')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_openmanage')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_openmanage]=/usr/lib/nagios/plugins/check_openmanage -p -I")
+
+        elif self.machine_vendor == "dell9":
+            # Dell-Tools
+            #file_create("/etc/apt/sources.list.d/linux.dell.com.sources.list", "deb http://linux.dell.com/repo/community/openmanage/901/trusty trusty main")
+            #run_cmd('gpg --keyserver pool.sks-keyservers.net --recv-key 1285491434D8786F', argShell=True)
+            #run_cmd('gpg -a --export 1285491434D8786F |  apt-key add -', argShell=True)
+            #run_cmd('apt-get update')
+            #run_cmd('apt install srvadmin-storageservices rpm srvadmin-base srvadmin-idracadm8 srvadmin-oslog srvadmin-server-cli syscfg raidcfg rpm -y --force-yes')
+            #run_cmd('wget -O /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 https://ftp.iteas.at/public/dell/idrac9/libcrypto.so.1.0.0')
+            #run_cmd('ln -s /usr/bin/rpm /bin/rpm')
+
+            # Nagios Monitoring-Agent
+            if self.monitoring == "nagios":
+                #run_cmd('wget -O /tmp/check-openmanage_3.7.12-1_all.deb https://ftp.iteas.at/public/nagios/plugins/check-openmanage_3.7.12-1_all.deb')
+                #run_cmd('dpkg -i /tmp/check-openmanage_3.7.12-1_all.deb')
+
+                #run_cmd('wget -O /usr/lib/nagios/plugins/check_openmanage https://ftp.iteas.at/public/nagios/plugins/check_openmanage')
+                #run_cmd('chmod +x /usr/lib/nagios/plugins/check_openmanage')
+                #file_append("/etc/nagios/nrpe.cfg", "#command[check_openmanage]=/usr/lib/nagios/plugins/check_openmanage -p -I")
+
+                run_cmd('apt-get install snmp smistrip -y')
+                run_cmd('wget -O /tmp/snmp-mibs-downloader_1.1+nmu1_all.deb https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fdell%2Fidrac9&files=snmp-mibs-downloader_1.1%2Bnmu1_all.deb')
+                run_cmd('dpkg -i /tmp/snmp-mibs-downloader_1.1+nmu1_all.deb')
+                run_cmd('wget -O /usr/share/snmp/mibs/idrac-smiv2.mib https://git.styrion.net/iteas/nagios-iteas-addons/raw/master/mibs/idrac-smiv2.mib')
+                run_cmd('wget -O /usr/lib/nagios/plugins/idrac_2.2rc4.py https://git.styrion.net/iteas/nagios-iteas-addons/raw/master/plugins/idrac_2.2rc4.py')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/idrac_2.2rc4.py')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_openmanage]=/usr/lib/nagios/plugins/idrac_2.2rc4 -H 10.10.10.10 -v 2c -c public")
+
+        # Desktop Konfiguration
+        if self.desktop == "plasma":
+            run_cmd('apt install -y kde-plasma-desktop sddm kde-config-systemd kde-config-sddm kde-config-screenlocker kde-config-cron kde-wallpapers firefox-esr-l10n-de firefox-esr virt-viewer task-german-kde-desktop kdf software-properties-gtk synaptic namebench konversation speedtest-cli kpat wireshark x2goclient mpv filezilla zenmap gnome-nettool  mysql-workbench okteta mactelnet-client  ksystemlog clementine qapt-deb-installer khelpcenter kate tree gtkterm filelight nomachine task-german-kde-desktop sddm-theme-breeze git libreoffice-writer libreoffice-calc libreoffice-kde libreoffice-l10n-de libreoffice-impress plasma-widgets-addons')
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('useradd iteasadm -c iteasadm -G dialout,cdrom,video,plugdev,games,sudo -m -s /bin/zsh -U -p \'$1$CvBQaSeR$0phJus.ly543oq2fKOtT40\'', argShell=True)
+
+        elif self.desktop == "i3":
+            pass
+
+        run_cmd('apt-get install -f')
+        if self.proxy == True:
+            run_cmd('rm /etc/apt/apt.conf.d/01proxy')
+
+        sum_txt = """-------------------------------------------------------------------------------
+ITEAS Proxmox Installationsbericht
+
+Loginmoeglichkeiten:
+  https://%s:8006 -> Weboberflaeche Virtualisierung
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  https://%s:10000 -> Weboberflaeche Webmin (NFSfreigaben, Samba, etc.)" % check_systemip(show_prefix=False)
+
+
+        sum_txt += """
+  SSH ueber CMD f.e "ssh root@%s"
+
+Folgende lokale Benutzer wurden angelegt:
+  root (Administrator) SSH, Virtualisierung, Webmin
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  backup (fuer den Zugriff auf Freigaben) Samba"
+
+        sum_txt += """
+
+Das Komplette Installationslog ist auf
+  /var/log/proxmox_install.log einsehbar.
+-------------------------------------------------------------------------------
+"""
+
+        fr = open("/root/proxmox_report.txt", "w")
+        fr.write(sum_txt)
+        fr.close()
+
+        gui_text_box("/root/proxmox_report.txt")
+
+        # Installation fertig
+        retval = gui_yesno_box("Installer", "Die Installation wurde abgeschlossen! Moechten Sie den PC/Server neustarten?")
+        if retval[0] == 0:
+            pbox = gui_progress_box("PC/Server wird automatisch neugestartet...", 0)
+            for x in range(0, 5):
+                pbox.update(x*20)
+                time.sleep(1)
+
+            pbox.finish()
+            run_cmd('reboot')
+        elif retval[0] == 1:
+            gui_message_box("Installer", "Sie muessen den PC/Server manuell neustarten um die Installation abzuschliessen!")
+
+
+i = Installer()
+i.start()
+logger.close()
diff --git a/proxmox_install_PVE6.py b/proxmox_install_PVE6.py
new file mode 100755
index 0000000..7513468
--- /dev/null
+++ b/proxmox_install_PVE6.py
@@ -0,0 +1,1218 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+#
+# (c) Rene Hadler, Mario Loderer, iteas IT Services GmbH
+# support@iteas.at
+# www.iteas.at
+#
+
+import sys
+import time
+import socket
+import subprocess
+import requests
+
+# Globale Variablen
+VERSION = "1.1.2"
+TITLE = "iteas Proxmox Installer " + VERSION
+CHECK_INTERNET_IP = "77.235.68.39"
+VM_TEMPLATE_CIFS_SHARE = "//srv-backup01.iteas.at/archiv-replica"
+VM_TEMPLATE_CIFS_USER = "localbackup02"
+SMB_ADMIN_PASSWD = "backmode123"
+
+
+try:
+    CONSOLE_ROWS, CONSOLE_COLS = subprocess.check_output(['stty', 'size']).split()
+except:
+    CONSOLE_ROWS = 40
+    CONSOLE_COLS = 100
+
+GUI_WIN_WIDTH = 100 if int(CONSOLE_COLS) > 110 else (int(CONSOLE_COLS) - 10)
+
+class Logger:
+    def __init__(self):
+        self.f = fr = open("proxmox_install.log", "w+")
+
+    def log(self, text):
+        self.f.write(text)
+
+    def close(self):
+        self.f.close()
+
+logger = Logger()
+
+# Befehle ausfĂĽhren
+def run_cmd(command, argShell=False):
+    try:
+        return subprocess.call(command.split(" ") if argShell == False else command, shell=argShell)
+    except:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Fehler", "Befehl <%s> war nicht erfolgreich, Fehlermeldung: %s -- Installation abbrechen?" % (command, e))
+        if retval[0] == 0:
+            exit(1)
+
+def apt_install(pkgs, argShell=False, force=False):
+    command = "apt-get install -y %s %s" % (pkgs, "--force-yes" if force else "")
+    try:
+        ret = run_cmd_output(command, argShell)
+        if ret[0] != 0:
+            retval = gui_yesno_box("APT-Fehler", 'Befehl <%s> war nicht erfolgreich, Rueckgabewert war nicht 0, Fehlermeldung: \n--\n%s \n--\nInstallation abbrechen?' % (command, ret[2]))
+            if retval[0] == 0:
+                exit(1)
+    except SystemExit:
+        exit(1)
+    except:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Fehler", "Befehl <%s> war nicht erfolgreich, Fehlermeldung: %s -- Installation abbrechen?" % (command, e))
+        if retval[0] == 0:
+            exit(1)
+
+def run_cmd_output(command, argShell=False):
+    p = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read().decode('UTF-8'), p.stderr.read().decode('UTF-8'))
+
+def run_cmd_stdout(command, argShell=False):
+    p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read().decode('UTF-8'))
+
+def run_cmd_stderr(command, argShell=False):
+    p = subprocess.Popen(command, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stderr.read().decode('UTF-8'))
+
+def run_cmd_stdin(command, argShell=False):
+    p = subprocess.Popen(command, stdin=subprocess.PIPE, shell=argShell)
+    return p
+
+# Oberflächen / GUI
+def gui_message_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--msgbox", text, "--title", title, "20", str(GUI_WIN_WIDTH)])
+
+def gui_text_box(file):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--textbox", file, "20", str(GUI_WIN_WIDTH)])
+
+def gui_input_box(title, text, default=""):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--inputbox", text, "20", str(GUI_WIN_WIDTH), default, "--title", title])
+
+def gui_yesno_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--yesno", text, "--title", title, "20", str(GUI_WIN_WIDTH)])
+
+def gui_password_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--passwordbox", text.encode('UTF-8'), "8", str(GUI_WIN_WIDTH), "--title", title.encode('UTF-8')])
+
+def gui_menu_box(title, text, menu):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--menu", text, "--title", title, "28", str(GUI_WIN_WIDTH), "22"] + menu)
+
+def gui_checklist_box(title, text, checklist):
+    ret = run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--checklist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + checklist)
+    return (ret[0], [] if ret[1] == "" else [x.replace('"', "") for x in ret[1].split(" ")])
+
+def gui_radiolist_box(title, text, radiolist):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--radiolist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + radiolist)
+
+class gui_progress_box():
+    def __init__(self, text, progress):
+        self.p = run_cmd_stdin(["whiptail", "--backtitle", TITLE, "--gauge", text, "6", "50", str(progress)])
+
+    def update(self, prog):
+        upd = "%s\n" % prog
+        self.p.stdin.write(upd.encode('utf-8'))
+        self.p.stdin.flush()
+
+    def finish(self):
+        self.p.stdin.close()
+
+def gui_password_verify_box(title, text, text2):
+    password = ""
+    while password == "":
+        retval = gui_password_box(title, text)
+        if retval[1] == "":
+            continue
+
+        retval2 = gui_password_box(title, text2)
+        if retval2[1] == "":
+            continue
+
+        if retval[1] == retval2[1]:
+            password = retval[1]
+        else:
+            gui_message_box(title, "Fehler bei der Passworteingabe, die Passwoerter stimmen nicht ueberein!")
+
+    return password
+
+# Sonstige Funktionen
+def check_internet():
+    try:
+        s = socket.create_connection((CHECK_INTERNET_IP, 80), 5)
+        return True
+    except:
+        return False
+
+def check_filesystem():
+    try:
+        zfsc = run_cmd_output('zfs list')
+        if zfsc[0] == 1 or zfsc[2].find('no datasets') != -1:
+            return 'standard'
+        else:
+            return 'zfs'
+    except:
+        return 'standard'
+
+def check_systemip(show_prefix = True):
+    zfsc = run_cmd_stdout("ip addr show vmbr0 | grep 'inet' | grep -v 'inet6' | cut -d' ' -f6", argShell=True)
+    if show_prefix == True:
+        return zfsc[1].strip()
+    else:
+        return zfsc[1].strip().split("/")[0]
+
+def check_systemipnet():
+    try:
+        zfsc = check_systemip()
+        if zfsc == '':
+            return ''
+        else:
+            # Nicht immer true
+            ipf = zfsc.split(".")
+            return "%s.%s.%s.0/%s" % (ipf[0], ipf[1], ipf[2], ipf[3].split("/")[1])
+    except:
+        return ''
+
+def file_replace_line(file, findstr, replstr, encoding='utf-8'):
+    fp = open(file, "r+", encoding=encoding)
+    buf = ""
+    for line in fp.readlines():
+        if line.find(findstr) != -1:
+            line = replstr + "\n"
+
+        buf += line
+
+    fp.close()
+    fr = open(file, "w+", encoding=encoding)
+    fr.write(buf)
+    fr.close()
+
+def file_create(file, str):
+    fr = open(file, "w+")
+    fr.write(str + "\n")
+    fr.close()
+
+def file_append(file, str):
+    fr = open(file, "a")
+    fr.write(str + "\n")
+    fr.close()
+
+# Installer Start
+class Installer():
+    def __init__(self):
+        self.internet = False
+        self.fqdn = socket.getfqdn()
+        try:
+            self.domain = self.fqdn.split(".")[1] + "." + self.fqdn.split(".")[2]
+            self.hostname = socket.gethostname()
+        except:
+            gui_message_box("Installer", "FQDN ist nicht richtig gesetzt, Installation wird abgebrochen!")
+            exit(1)
+
+        self.machine_vendor = "other"
+        self.machine_type = "virt"
+        self.environment = "stable"
+        self.monitoring = "nagios"
+        self.license = ""
+        self.filesystem = ""
+        self.mgmt_ip = ""
+        self.backuppc = False
+        self.vm_import = []
+        self.lxc_import = []
+        self.share_clients = []
+        self.proxy = True
+        self.desktop = "kein"
+        self.puppet = "kein"
+
+        self.ipmi_config = False
+        self.ipmi_ip = ""
+        self.ipmi_netmask = ""
+        self.ipmi_gateway = ""
+        self.ipmi_dns = ""
+        self.ipmi_user = ""
+        self.ipmi_pass = ""
+
+        # Installer Variablen
+        self.MACHINE_VENDORS = {"hp": "HP < Gen 10", "hp10": "HP Gen 10", "dell": "Dell iDRAC < 9", "dell9": "Dell iDRAC 9", "tk": "Thomas Krenn", "other": "Andere"}
+        self.MACHINE_TYPES = {"virt": "Virtualisierung", "backup": "Backup"}
+        self.ENVIRONMENTS = {"stable": "Stabile Proxmox Enterprise Updates", "test": "Proxmox Testing Updates", "noupdate": "Keine Proxmox Updates"}
+        self.MONITORINGS = {"nagios": "Nagios NRPE", "checkmk": "CheckMK Agent"}
+        self.FILESYSTEMS = {"standard": "Standard (ext3/4, reiserfs, xfs)", "zfs": "ZFS"}
+        self.DESKTOPS = {
+            "kein": "Nein",
+            "plasma": "KDE5-Plasma",
+            "plasma-light": "KDE5-Plasma Light",
+            "plasma-light-win": "KDE5-Plasma Light Windows Workstation",
+            "i3": "i3-WM (testing)"
+        }
+        self.VM_IMPORTS = {
+            "139": {"name": "Windows 7 Pro", "template": True},
+            "166": {"name": "Windows 10 Pro", "template": True},
+            "117": {"name": "Windows Server 2008 r2", "template": True},
+            "162": {"name": "Windows Server 2016", "template": True},
+            "169": {"name": "Windows Server 2019", "template": True},
+            "131": {"name": "CentOS Server Standard", "template": True},
+            "145": {"name": "CentOS Mailserver", "template": True},
+            "114": {"name": "Ubuntu Server Standard", "template": True}
+            
+        }
+        self.LXC_IMPORTS = {
+            "102": {"name": "Samba Backupassist mit ADS Anbindung", "template": True },
+            "121": {"name": "Samba Backupassist ohne ADS Anbindung", "template": True },
+        }
+        self.PUPPETS = {
+            "kein": "Nein",
+            "generic": "Generische Installation",
+            "proxmox-desktop": "Proxmox Desktop"
+        }
+
+    def start(self):
+        gui_message_box("Installer", "Willkommen beim iteas Proxmox Installer!")
+        self.internet = check_internet()
+        self.filesystem = check_filesystem()
+        if check_systemipnet() != '':
+            self.share_clients.append(check_systemipnet())
+        self.step1()
+
+    def step1(self):
+        step1_val = gui_menu_box("Schritt 1", "Kontrollieren bzw. konfigurieren Sie die entsprechenden Werte und gehen Sie dann auf 'Weiter'.",
+                                    ["Internet", "JA" if self.internet == True else "NEIN",
+                                     "Hostname", self.hostname,
+                                     "Domain", self.domain,
+                                     "Dateisystem", self.FILESYSTEMS[self.filesystem],
+                                     " ", " ",
+                                     "Maschinenhersteller", self.MACHINE_VENDORS[self.machine_vendor],
+                                     "Maschinentyp", self.MACHINE_TYPES[self.machine_type],
+                                     "IPMI-Konfiguration", "Ja" if self.ipmi_config == True else "Nein",
+                                     "BackupPC-LXC", "Nein" if self.backuppc == False else "Ja",
+                                     "Proxmox-Umgebung", self.ENVIRONMENTS[self.environment],
+                                     "Proxmox-Lizenz", "Keine" if self.license == "" else self.license,
+                                     "VM-Template-Import", ",".join([self.VM_IMPORTS[x]["name"] for x in self.vm_import]) if len(self.vm_import) > 0 else "Keine",
+                                     "LXC-Template-Import", ",".join([self.LXC_IMPORTS[x]["name"] for x in self.lxc_import]) if len(self.lxc_import) > 0 else "Keine",
+                                     "Freigabe-Clients", ",".join([x for x in self.share_clients]) if len(self.share_clients) > 0 else "Alle",
+                                     "Mgmt-IP", "Keine" if self.mgmt_ip == "" else self.mgmt_ip,
+                                     "apt-Proxy", "Nein" if self.proxy == False else "Ja",
+                                     "Desktop", self.DESKTOPS[self.desktop],
+                                     "Monitoring-Agent", self.MONITORINGS[self.monitoring],
+                                     "Puppet", self.PUPPETS[self.puppet],
+                                     " ", " ",
+                                     "Weiter", "Installation fortsetzen"])
+
+        # Abbrechen
+        if step1_val[0] == 1 or step1_val[0] == 255:
+            exit(0)
+
+        # Eintrag wurde gewählt
+        if step1_val[1] == "Maschinenhersteller":
+            self.step1_machine_vendor()
+
+        elif step1_val[1] == "Maschinentyp":
+            self.step1_machine_type()
+
+        elif step1_val[1] == "Proxmox-Umgebung":
+            self.step1_environment()
+
+        elif step1_val[1] == "Monitoring-Agent":
+            self.step1_monitoring()
+
+        elif step1_val[1] == "Proxmox-Lizenz":
+            self.step1_license()
+
+        elif step1_val[1] == "Mgmt-IP":
+            self.step1_mgmtip()
+
+        elif step1_val[1] == "apt-Proxy":
+            self.step1_aptproxy()
+
+        elif step1_val[1] == "Desktop":
+            self.step1_desktop()
+
+        elif step1_val[1] == "BackupPC-LXC":
+            self.step1_backuppc()
+
+        elif step1_val[1] == "VM-Template-Import":
+            self.step1_vmtemplateimport()
+
+        elif step1_val[1] == "LXC-Template-Import":
+            self.step1_lxctemplateimport()
+
+        elif step1_val[1] == "Internet":
+            check_internet()
+            self.step1()
+
+        elif step1_val[1] == "Freigabe-Clients":
+            self.step1_shareclients()
+
+        elif step1_val[1] == "Weiter":
+            self.step2()
+
+        elif step1_val[1] == "Puppet":
+            self.step1_puppet()
+
+        elif step1_val[1] == "IPMI-Konfiguration":
+            self.step1_ipmi_main()
+
+        else:
+            self.step1()
+
+    def step1_ipmi_main(self):
+        step1_val = gui_menu_box("IPMI-Konfiguration", "Kontrollieren bzw. konfigurieren Sie IPMI 'Weiter'.",
+                                 ["IPMI-Konfiguration ", "Ja" if self.ipmi_config == True else "Nein",
+                                  " ", " ",
+                                  "IP-Adresse", self.ipmi_ip,
+                                  "IP-Subnet", self.ipmi_netmask,
+                                  "Gateway", self.ipmi_gateway,
+                                  "DNS", self.ipmi_dns,
+                                  " ", " ",
+                                  "Benutzername", self.ipmi_user,
+                                  "Passwort", self.ipmi_pass[0:3] + (len(self.ipmi_pass)-3)*"*",
+                                  " ", " ",
+                                  "Zurueck", "Hauptmenu"])
+
+        # Abbrechen
+        if step1_val[0] == 1 or step1_val[0] == 255:
+            self.step1()
+
+        # Eintrag wurde gewählt
+        if step1_val[1] == "IPMI-Konfiguration ":
+            self.step1_ipmi_config()
+
+        elif step1_val[1] == "IP-Adresse":
+            self.step1_ipmi_ip()
+
+        elif step1_val[1] == "IP-Subnet":
+            self.step1_ipmi_netmask()
+
+        elif step1_val[1] == "Gateway":
+            self.step1_ipmi_gateway()
+
+        elif step1_val[1] == "DNS":
+            self.step1_ipmi_dns()
+
+        elif step1_val[1] == "Benutzername":
+            self.step1_ipmi_user()
+
+        elif step1_val[1] == "Passwort":
+            self.step1_ipmi_pass()
+
+        elif step1_val[1] == "Zurueck":
+            self.step1()
+
+        else:
+            self.step1_ipmi_main()
+
+    def step1_ipmi_config(self):
+        retval = gui_yesno_box("IPMI", "Mochten Sie IPMI konfigurieren?")
+        if retval[0] == 0:
+            self.ipmi_config = True
+        elif retval[0] == 1:
+            self.ipmi_config = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.step1_ipmi_main()
+
+    def step1_ipmi_ip(self):
+        retval = gui_input_box("IPMI IP-Adresse", "IP-Adresse eingeben", self.ipmi_ip)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_ip = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_netmask(self):
+        retval = gui_input_box("IPMI IP-Subnet", "IP-Subnet eingeben", self.ipmi_netmask)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_netmask = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_gateway(self):
+        retval = gui_input_box("IPMI Gateway", "Gateway eingeben", self.ipmi_gateway)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_gateway = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_dns(self):
+        retval = gui_input_box("IPMI DNS", "DNS eingeben", self.ipmi_dns)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_dns = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_user(self):
+        retval = gui_input_box("IPMI Benutzer", "Benutzer eingeben", self.ipmi_user)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_user = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_pass(self):
+        retval = gui_password_box("IPMI Passwort", "Passwort eingeben")
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_pass = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_machine_vendor(self):
+        list = []
+        for key, val in self.MACHINE_VENDORS.items():
+            list += [key, val, "ON" if self.machine_vendor == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Maschinenhersteller", "Waehlen sie den passenden Maschinenhersteller", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_vendor = retval[1]
+        self.step1()
+
+    def step1_machine_type(self):
+        list = []
+        for key, val in self.MACHINE_TYPES.items():
+            list += [key, val, "ON" if self.machine_type == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Maschinentyp", "Waehlen sie den passenden Maschinentyp", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_type = retval[1]
+        self.step1()
+
+    def step1_environment(self):
+        list = []
+        for key, val in self.ENVIRONMENTS.items():
+            list += [key, val, "ON" if self.environment == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Proxmox-Umgebung", "Waehlen sie die Proxmox-Umgebung", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.environment = retval[1]
+        self.step1()
+
+    def step1_monitoring(self):
+        list = []
+        for key, val in self.MONITORINGS.items():
+            list += [key, val, "ON" if self.monitoring == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Monitoring-Agent", "Waehlen sie den Monitoring-Agenten", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.monitoring = retval[1]
+        self.step1()
+
+    def step1_license(self):
+        retval = gui_input_box("Schritt 1: Proxmox-Lizenz", "Geben Sie den Proxmox-Schluessel ein", self.license)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.license = retval[1]
+        self.step1()
+
+    def step1_mgmtip(self):
+        retval = gui_input_box("Schritt 1: Mgmt-IP", "Geben Sie die IP des Managementservers ein", self.mgmt_ip)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.mgmt_ip = retval[1]
+        self.step1()
+
+    def step1_aptproxy(self):
+        retval = gui_yesno_box("Installer", "Mochten Sie den iteas apt-Proxy benutzen?")
+        if retval[0] == 0:
+            self.proxy = True
+        elif retval[0] == 1:
+            self.proxy = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1()
+            return
+
+        self.step1()
+
+    def step1_desktop(self):
+        list = []
+        for key, val in self.DESKTOPS.items():
+            list += [key, val, "ON" if self.desktop == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Proxmox-Desktop", "Waehlen sie einen Desktop", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.desktop = retval[1]
+        self.step1()
+
+    def step1_backuppc(self):
+        retval = gui_yesno_box("Installer", "Mochten Sie BackupPC via LXC dazuinstallieren?")
+        if retval[0] == 0:
+            self.backuppc = True
+        elif retval[0] == 1:
+            self.backuppc = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1()
+            return
+
+        self.step1()
+
+    def step1_vmtemplateimport(self):
+        list = []
+        for key, val in self.VM_IMPORTS.items():
+            list += [key, val["name"], "ON" if key in self.vm_import else "OFF"]
+
+        retval = gui_checklist_box("Schritt 1: VM-Template-Import", "Waehlen sie die VMs die importiert werden sollen", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.vm_import = []
+        for val in retval[1]:
+            self.vm_import += [val]
+
+        self.step1()
+
+    def step1_lxctemplateimport(self):
+        list = []
+        for key, val in self.LXC_IMPORTS.items():
+            list += [key, val["name"], "ON" if key in self.lxc_import else "OFF"]
+
+        retval = gui_checklist_box("Schritt 1: LXC-Template-Import", "Waehlen sie die LXC Container die importiert werden sollen", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.lxc_import = []
+        for val in retval[1]:
+            self.lxc_import += [val]
+
+        self.step1()
+
+    def step1_shareclients(self):
+        retval = gui_input_box("Schritt 1: Freigabe-Clients", "Geben Sie die Clients/Netze an, die Zugriffe auf die Freigaben am Proxmox Host haben sollen. Mehrere Eintraege muessen durch Leerzeichen getrennt sein.", " ".join(self.share_clients))
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.share_clients = retval[1].split(" ")
+        self.step1()
+
+    def step1_puppet(self):
+        list = []
+        for key, val in self.PUPPETS.items():
+            list += [key, val, "ON" if self.puppet == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Puppet", "Waehlen sie eine Puppet Installationsart", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.puppet = retval[1]
+        self.step1()
+
+    def step2(self):
+
+        if self.environment == "stable" and self.license == "":
+            gui_message_box("Installer", "Sie muessen eine Lizenz angeben wenn Enterprise Updates ausgewaehlt wurden!")
+            self.step1()
+            return
+
+        if self.internet == False:
+            gui_message_box("Installer", "Es muss eine Internetverbindung bestehen um fortzufahren!")
+            self.step1()
+            return
+
+        # Set locales
+        file_replace_line("/etc/locale.gen", "# de_AT.UTF-8 UTF-8", "de_AT.UTF-8 UTF-8")
+        file_replace_line("/etc/locale.gen", "# de_DE.UTF-8 UTF-8", "de_DE.UTF-8 UTF-8")
+        run_cmd('locale-gen', argShell=True)
+
+        ############ Allgemeine Konfiguration
+        if self.license != "":
+            retval = run_cmd_output('pvesubscription set ' + self.license)
+            if retval[0] == 255:
+                gui_message_box("Proxmox Lizenzinstallation", "Die Lizenz konnte nicht installiert werden, bitte pruefen Sie Ihre Lizenznummer. Fehler: " + retval[2])
+                self.step1()
+                return
+
+            time.sleep(30)
+
+            # Warte maximal fĂĽr 5 Minuten fĂĽr Registrierung
+            maxwait = 300
+            curwait = 0
+            lictest = run_cmd_stdout('pvesubscription get', argShell=True)
+            while lictest[1].find('status: Active') == -1 and curwait < maxwait:
+                print("Warte auf Registrierung der Proxmox-Subscription..." + str(curwait))
+                time.sleep(10)
+                lictest = run_cmd_stdout('pvesubscription get', argShell=True)
+                curwait += 10
+
+            # Warte maximal fĂĽr 5 Minuten fĂĽr Enterprise-Repo Zugriff
+            curwait = 0
+            httpuser = run_cmd_stdout("pvesubscription get | grep 'key:.*' | cut -f2 -d:", argShell=True)[1].strip()
+            httppass = run_cmd_stdout("pvesubscription get | grep 'serverid:.*' | cut -f2 -d:", argShell=True)[1].strip()
+
+            repotest = requests.get('https://enterprise.proxmox.com/debian/pve', auth=(httpuser, httppass))
+            while repotest.status_code != requests.codes.ok and curwait < maxwait:
+                print("Warte auf Freischaltung des Enterprise-Repos..." + str(curwait))
+                time.sleep(10)
+                repotest = requests.get('https://enterprise.proxmox.com/debian/pve', auth=(httpuser, httppass))
+                curwait += 10
+
+        # Proxmox Testing Quellen aktivieren
+        if self.environment == "test":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian/pve buster pve-enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "deb http://download.proxmox.com/debian/pve buster pve-no-subscription")
+        elif self.environment == "noupdate":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian/pve buster pve-enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "# deb http://download.proxmox.com/debian/pve buster pve-no-subscription")
+
+        # If lvm-thin convert to standard file storage if backup-machine
+        if self.machine_type == "backup" and run_cmd('pvesh get /storage | grep -i local-lvm', argShell=True) == 0:
+            run_cmd('pvesh delete /storage/local-lvm')
+            run_cmd('lvremove /dev/pve/data -f')
+            run_cmd('lvcreate -Wy -l100%FREE -ndata pve')
+            run_cmd('mkfs.ext4 -m1 /dev/pve/data')
+            run_cmd('mount /dev/pve/data /var/lib/vz')
+            file_append("/etc/fstab", "/dev/pve/data /var/lib/vz ext4 defaults 0 2")
+
+        # Mount Template CIFS-Share und importiere VMs
+        storage = "local"
+        if run_cmd('pvesh get /storage | grep -i local-lvm', argShell=True) == 0:
+            storage = "local-lvm"
+
+        if len(self.vm_import) > 0 or len(self.lxc_import) > 0:
+            retval = gui_password_box("Samba Passwort benötigt", "Bitte das Passwort für Share " + VM_TEMPLATE_CIFS_SHARE + " und Benutzer " + VM_TEMPLATE_CIFS_USER + " eingeben.")
+            VM_TEMPLATE_CIFS_PASS = retval[1]
+
+            cifscnt = 1
+            cifstest = run_cmd('mount -t cifs -o user=' + VM_TEMPLATE_CIFS_USER + ",password=" + VM_TEMPLATE_CIFS_PASS + " " + VM_TEMPLATE_CIFS_SHARE + ' /mnt')
+            while cifstest != 0 and cifscnt < 3:
+                retval = gui_password_box("Passwort falsch, Samba Passwort benötigt", "Bitte das Passwort für Share " + VM_TEMPLATE_CIFS_SHARE + " und Benutzer " + VM_TEMPLATE_CIFS_USER + " erneut eingeben.")
+                VM_TEMPLATE_CIFS_PASS = retval[1]
+                cifstest = run_cmd('mount -t cifs -o user=' + VM_TEMPLATE_CIFS_USER + ",password=" + VM_TEMPLATE_CIFS_PASS + " " + VM_TEMPLATE_CIFS_SHARE + ' /mnt')
+                if cifstest == 0:
+                    break
+                cifscnt += 1
+
+            if cifstest == 0:
+                # Import selected VMs
+                for vm_id in self.vm_import:
+                    (ret, filename) = run_cmd_stdout("ls -t /mnt/dump/vzdump-qemu-%s*vma.zst | head -n1" % vm_id, argShell=True)
+                    if filename != "":
+                        run_cmd("qmrestore %s %s -storage %s" % (filename.strip(), vm_id, storage))
+                        if self.VM_IMPORTS[vm_id]["template"] == True:
+                            run_cmd("qm template %s" % vm_id)
+
+                # Import selected LXCs
+                for vm_id in self.lxc_import:
+                    (ret, filename) = run_cmd_stdout("ls -t /mnt/dump/vzdump-lxc-%s-*.tar.zst | head -n1" % vm_id, argShell=True)
+                    if filename != "":
+                        run_cmd("pct restore %s %s -storage %s" % (vm_id, filename.strip(), storage))
+                        if self.LXC_IMPORTS[vm_id]["template"] == True:
+                            run_cmd("pct template %s" % vm_id)
+
+                run_cmd('umount /mnt')
+            else:
+                gui_message_box("Installer", "CIFS konnte nicht gemounted werden (Passwort falsch?), VMs werden nicht importiert!")
+
+            VM_TEMPLATE_CIFS_PASS = ""
+
+        # Apt-Proxy Cache
+        if self.proxy == True:
+            file_create("/etc/apt/apt.conf.d/01proxy", 'Acquire::http { Proxy "http://10.69.99.10:3142"; };')
+
+        # Installieren allgemeine Tools und Monitoring-Agent
+        run_cmd('apt-get update')
+        apt_install('dirmngr')
+        file_create("/etc/apt/sources.list.d/iteas.list", "deb https://apt.iteas.at/iteas buster main")
+        run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 2FAB19E7CCB7F415', argShell=True)
+        run_cmd('apt-get update')
+        run_cmd('apt-get dist-upgrade -y')
+        apt_install('dirmngr htop unp postfix sudo screen zsh tmux bwm-ng pigz sysstat ethtool nload apcupsd ntfs-3g sl gawk ca-certificates-iteas-enterprise at lsb-release')
+        # ifupdown2 nur installieren wenn nicht "noupdate" gewählt wurde da das Standard Paket in den Debian Quellen nicht mit Proxmox kompatibel ist
+        if self.environment != "noupdate":
+            apt_install('ifupdown2')
+
+        if self.monitoring == "nagios":
+            apt_install('nagios-nrpe-server')
+        elif self.monitoring == "checkmk":
+            apt_install('xinetd check-mk-agent')
+
+        # Spezielle allgemeine Settings fĂĽr ZFS
+        if self.filesystem == "zfs":
+            file_create("/etc/modprobe.d/zfs.conf", "options zfs zfs_arc_max=10737418240")
+            run_cmd('update-initramfs -u', argShell=True)
+
+        # SUDOers
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /usr/bin/rsync")
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /bin/tar")
+
+        # Monitoring Konfiguration
+        if self.monitoring == "nagios":
+
+            # SUDOers
+            file_append("/etc/sudoers", "nagios      ALL=(ALL) NOPASSWD: /usr/lib/nagios/plugins/")
+            file_append("/etc/sudoers", "nagios      ALL=(ALL) NOPASSWD: /usr/sbin/hpssacli")
+            file_append("/etc/sudoers", "nagios      ALL=(ALL) NOPASSWD: /sbin/hpasmcli")
+            file_append("/etc/sudoers", "#nagios      ALL=(ALL) NOPASSWD: /bin/su")
+            file_append("/etc/sudoers", "#nagios    ALL=(backuppc) NOPASSWD: ALL")
+
+            if self.mgmt_ip != "":
+                file_replace_line("/etc/nagios/nrpe.cfg", "allowed_hosts=", "allowed_hosts=127.0.0.1,%s" % self.mgmt_ip)
+
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_vg_size https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_win_disk.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_zpool-1.sh https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_zpool-1.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_zpool.sh https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_zpool.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_backuppc https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_backuppc')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_proc_backuppc.sh https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_proc_backuppc.sh')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_smb https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_smb')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_apcupsd https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_apcupsd')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_smart https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_smart')
+            run_cmd('wget -O /usr/lib/nagios/plugins/check_hddtemp.sh https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_hddtemp.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_vg_size')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_zpool-1.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_zpool.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_backuppc')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_proc_backuppc.sh')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_smb')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_apcupsd')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_smart')
+            run_cmd('chmod +x /usr/lib/nagios/plugins/check_hddtemp.sh')
+
+            file_append("/etc/nagios/nrpe.cfg", "command[check_disk1]=/usr/lib/nagios/plugins/check_disk -w 7% -c 3% -p / -p /var/lib/vz")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_swap]=/usr/lib/nagios/plugins/check_swap -w 30% -c 20%")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_uptime]=/usr/lib/nagios/plugins/check_uptime")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_smtp]=/usr/lib/nagios/plugins/check_smtp -H localhost")
+
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_hddtemp_ssd1]=sudo /usr/lib/nagios/plugins/check_hddtemp.sh /dev/disk/by-id/ata-xxx 63 65")
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_smart_ssd2]=sudo /usr/lib/nagios/plugins/check_smart -d /dev/disk/by-id/ata-xxx -i ata")
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_smart_hdd1]=sudo /usr/lib/nagios/plugins/check_smart -d /dev/disk/by-id/ata-xxx -i scsi")
+
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_zpool-1]=sudo /usr/lib/nagios/plugins/check_zpool-1.sh")
+            file_append("/etc/nagios/nrpe.cfg", "#command[check_zpool]=sudo /usr/lib/nagios/plugins/check_zpool.sh -p ALL -w 95 -c 98")
+
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_bcharge]=/usr/lib/nagios/plugins/check_apcupsd -c 50 -w 70 bcharge")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_loadpct]=/usr/lib/nagios/plugins/check_apcupsd -c 90 -w 80 loadpct")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_timeleft]=/usr/lib/nagios/plugins/check_apcupsd -c 5 -w 10 timeleft")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_apcupsd_itemp]=/usr/lib/nagios/plugins/check_apcupsd -c 45 -w 35 itemp")
+
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_Core_0]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "Core 0"=57,62')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_Core_2]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "Core 2"=57,62')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_systin]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "SYSTIN"=45,50')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_cputin]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "CPUTIN"=45,50')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_auxtin]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -h "AUXTIN"=35,40')
+            file_append("/etc/nagios/nrpe.cfg", '#command[check_sensors_fan1]=sudo /usr/lib/nagios/plugins/check_lm_sensors  -l "fan1"=3000,2500')
+
+            file_append("/etc/nagios/nrpe.cfg", "command[check_backuppc_hosts]=sudo -u backuppc /usr/lib/nagios/plugins/check_backuppc")
+            file_append("/etc/nagios/nrpe.cfg", "command[check_backuppc]=/usr/lib/nagios/plugins/check_proc_backuppc.sh")
+
+            if self.filesystem == "zfs":
+                file_replace_line("/etc/nagios/nrpe.cfg", "check_total_procs", "command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 800 -c 1000")
+            else:
+                file_replace_line("/etc/nagios/nrpe.cfg", "check_total_procs", "command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 600 -c 650")
+
+        elif self.monitoring == "checkmk":
+
+            if self.mgmt_ip != "":
+                file_replace_line("/etc/xinetd.d/check_mk", "only_from", "only_from = %s" % self.mgmt_ip)
+
+            # Check-MK-Agent Config
+            run_cmd('wget -O /tmp/mk_smart https://git.styrion.net/iteas/check_mk-smart-plugin/raw/master/agents/smart')
+            run_cmd('mv /tmp/mk_smart /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_apcupsd https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_apcupsd')
+            run_cmd('mv /tmp/mk_apcupsd /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_dmi_sysinfo https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_dmi_sysinfo')
+            run_cmd('mv /tmp/mk_dmi_sysinfo /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_inventory https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_inventory')
+            run_cmd('mv /tmp/mk_inventory /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_lmsensors https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_lmsensors')
+            run_cmd('mv /tmp/mk_lmsensors /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_logins https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_logins')
+            run_cmd('mv /tmp/mk_logins /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_nfsexports https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_nfsexports')
+            run_cmd('mv /tmp/mk_nfsexports /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_netstat https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_netstat')
+            run_cmd('mv /tmp/mk_netstat /usr/lib/check_mk_agent/plugins/')
+            run_cmd('chmod +x /usr/lib/check_mk_agent/plugins/mk_*', argShell=True)
+
+        # APC
+        run_cmd('wget -O /etc/apcupsd/apcupsd.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/etc/apcupsd.conf')
+        file_replace_line("/etc/default/apcupsd", "ISCONFIGURED", "ISCONFIGURED=yes")
+        run_cmd('systemctl enable apcupsd.service')
+
+        # Nano
+        run_cmd('wget -O /tmp/nano.tar https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fproxmox&files=nano.tar')
+        run_cmd('tar -xf /tmp/nano.tar -C /root')
+        run_cmd('rm /tmp/nano.tar')
+
+        # ZSH
+        run_cmd('wget -O /tmp/zshrc_root https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fproxmox&files=zshrc_root')
+        run_cmd('mv /tmp/zshrc_root /root/.zshrc')
+        file_replace_line("/root/.zshrc", "iteas.local", 'export PS1="%UDomain:%u %B%F{yellow}' + self.domain + ' $PS1"', encoding='iso8859_15')
+        run_cmd('usermod -s /bin/zsh root')
+
+        # Postfix
+        file_replace_line("/etc/postfix/main.cf", "myhostname=", "myhostname=" + self.fqdn + ".monitoring.iteas.at")
+        file_replace_line("/etc/postfix/main.cf", "relayhost =", "relayhost = smtp.styrion.net")
+        run_cmd('systemctl restart postfix.service')
+
+        # PIGZ
+        run_cmd('mv /bin/gzip /bin/gzip_backup')
+        run_cmd('ln -s /usr/bin/pigz /bin/gzip')
+
+        # SystemD
+        run_cmd('wget -O /etc/systemd/system/rc.local.shutdown.service https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown.service')
+        run_cmd('wget -O /etc/rc.local.shutdown https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown')
+        run_cmd('systemctl enable rc.local.shutdown.service')
+        
+        # USB-Automount
+        apt_install('pve6-usb-automount')
+
+        # Kexec
+        run_cmd('echo "kexec-tools kexec-tools/load_kexec boolean false" | debconf-set-selections', argShell=True)
+        apt_install('kexec-tools')
+        run_cmd('wget -O /etc/systemd/system/kexec-pve.service https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/kexec-pve.service')
+        run_cmd('systemctl enable kexec-pve.service')
+
+        # SysCTL
+        file_append("/etc/sysctl.conf", "vm.swappiness=10")
+        file_append("/etc/sysctl.conf", "fs.inotify.max_user_watches=1048576")
+
+        # BackupPC
+        if self.backuppc == True:
+            # TODO Import LXC Template
+            pass
+
+        ############ Konfiguration fĂĽr Backup-Server
+        if self.machine_type == "backup":
+            # NFS, Samba & ZFS
+            apt_install('samba targetcli-fb')
+
+            #password = gui_password_verify_box("Samba Passwort", "Geben Sie das Passwort fuer den Samba Benutzer 'admin' an:", "Geben Sie das Passwort fuer den Samba Benutzer 'admin' erneut an:")
+            password = SMB_ADMIN_PASSWD
+            run_cmd("groupadd localbackup", argShell=True)
+            run_cmd("useradd localbackup -m -g localbackup -p '%s'" % password, argShell=True)
+            run_cmd("(echo '%s'; echo '%s') | smbpasswd -a localbackup" % (password, password), argShell=True)
+            run_cmd('wget -O /etc/samba/smb.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/samba/backup_default_smb2.conf')
+
+            backup_root = ""
+            if self.filesystem == "zfs":
+                run_cmd('zfs create rpool/sicherung')
+                apt_install('zfs-zed')
+                file_replace_line("/etc/samba/smb.conf", "path = /var/lib/vz/sicherung", "\tpath = /rpool/sicherung")
+                backup_root = "/rpool/sicherung"
+            else:
+                run_cmd('mkdir /var/lib/vz/sicherung')
+                backup_root = "/var/lib/vz/sicherung"
+
+            run_cmd("chown -R localbackup:localbackup %s" % backup_root)
+
+            file_replace_line("/etc/samba/smb.conf", "workgroup = kundendomain.local", "\tworkgroup = %s" % self.domain)
+            if len(self.share_clients) > 0:
+                file_replace_line("/etc/samba/smb.conf", "hosts allow =", "\thosts allow = %s" % " ".join(self.share_clients))
+
+            run_cmd('systemctl enable smbd')
+            run_cmd('systemctl start smbd')
+
+            # Webmin
+            file_create("/etc/apt/sources.list.d/webmin.list", "deb https://download.webmin.com/download/repository sarge contrib")
+            run_cmd("cd /tmp && wget http://www.webmin.com/jcameron-key.asc && apt-key add jcameron-key.asc", argShell=True)
+            apt_install("apt-transport-https curl git")
+            run_cmd("apt-get update", argShell=True)
+            apt_install("webmin")
+            file_append("/etc/webmin/config", "lang_root=de.UTF-8")
+            file_append("/etc/webmin/config", "theme_root=authentic-theme")
+            file_replace_line("/etc/webmin/config", "lang=", "lang=de.UTF-8")
+            file_append("/etc/webmin/miniserv.conf", "preroot_root=authentic-theme")
+            run_cmd('mkdir /etc/webmin/authentic-theme')
+            run_cmd('wget -O /etc/webmin/authentic-theme/favorites.json https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/webmin/favorites.json')
+            run_cmd('/etc/init.d/webmin restart')
+
+
+        ############  Konfiguration fĂĽr HP < Gen10
+        if self.machine_vendor == "hp":
+            # HP-Tools
+            file_create("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP buster/current non-free")
+            file_append("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP/debian buster/current non-free")
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 527BC53A2689B887')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com FADD8D64B1275EA3')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C208ADDE26C2B797')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 26C2B797')
+            run_cmd('apt-get update')
+            apt_install('ssacli hponcfg')
+            run_cmd('ln -s /usr/sbin/ssacli /usr/sbin/hpacucli')
+                     
+            # Nagios Monitoring-Agent
+            if self.monitoring == "nagios":
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hparray https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_hparray')
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hpasm https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_hpasm')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hparray')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hpasm')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_cciss]=sudo /usr/lib/nagios/plugins/check_hparray -s 0 -v")
+                file_append("/etc/nagios/nrpe.cfg", "command[check_hpasm]=/usr/lib/nagios/plugins/check_hpasm --perfdata=short")
+
+        ############ Konfiguration fĂĽr HP Gen10
+        elif self.machine_vendor == "hp10":
+            # HP-Tools
+            file_create("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP buster/current non-free")
+            file_append("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP/debian buster/current non-free")
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 527BC53A2689B887')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com FADD8D64B1275EA3')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C208ADDE26C2B797')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 26C2B797')
+            run_cmd('apt-get update')
+            apt_install('ssacli hponcfg binutils')
+            run_cmd('ln -s /usr/sbin/ssacli /usr/sbin/hpacucli')
+
+            # Nagios Monitoring-Agent
+            if self.monitoring == "nagios":
+                apt_install('libmonitoring-plugin-perl libxml-simple-perl')
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hparray https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_hparray')
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_hpasm https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_hpasm')
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_ilo2_health.pl https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_ilo2_health.pl')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hparray')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_hpasm')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_ilo2_health.pl')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_cciss]=sudo /usr/lib/nagios/plugins/check_hparray -s 0 -v")
+                file_append("/etc/nagios/nrpe.cfg", "command[check_hpasm]=/usr/lib/nagios/plugins/check_ilo2_health.pl -3 -H 1.1.1.1 -u nagios -p 'xxx' -a -c -o -g -d")
+
+        elif self.machine_vendor == "dell":
+            # Dell-Tools
+            file_create("/etc/apt/sources.list.d/linux.dell.com.sources.list", "deb http://linux.dell.com/repo/community/ubuntu jessie openmanage")
+            run_cmd('gpg --keyserver pool.sks-keyservers.net --recv-key 1285491434D8786F')
+            run_cmd('gpg -a --export 1285491434D8786F | apt-key add -', argShell=True)
+            run_cmd('apt-get update')
+            run_cmd('wget -O /tmp/libslp1_1.2.1-10+deb8u1_amd64.deb http://ftp.us.debian.org/debian/pool/main/o/openslp-dfsg/libslp1_1.2.1-10+deb8u1_amd64.deb')
+            run_cmd('wget -O /tmp/libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb http://ftp.us.debian.org/debian/pool/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb')
+            run_cmd('dpkg -i /tmp/libslp1_1.2.1-10+deb8u1_amd64.deb')
+            run_cmd('dpkg -i /tmp/libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb')
+            apt_install('srvadmin-storageservices rpm srvadmin-base srvadmin-idracadm8 srvadmin-itunnelprovider srvadmin-oslog srvadmin-server-cli', force=True)
+            run_cmd('wget -O /tmp/dcism-2.3.0.deb8.deb http://linux.dell.com/repo/community/ubuntu/pool/jessie/openmanage/830/iSM/dcism-2.3.0.deb8.deb')
+            run_cmd('dpkg -i /tmp/dcism-2.3.0.deb8.deb')
+            run_cmd('ln -s /usr/bin/rpm /bin/rpm')
+
+            # Nagios Monitoring-Agent
+            if self.monitoring == "nagios":
+                run_cmd('wget -O /tmp/check-openmanage_3.7.12-1_all.deb https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check-openmanage_3.7.12-1_all.deb')
+                run_cmd('dpkg -i /tmp/check-openmanage_3.7.12-1_all.deb')
+
+                run_cmd('wget -O /usr/lib/nagios/plugins/check_openmanage https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fnagios%2Fplugins&files=check_openmanage')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/check_openmanage')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_openmanage]=/usr/lib/nagios/plugins/check_openmanage -p -I")
+
+        elif self.machine_vendor == "dell9":
+            # Dell-Tools
+            #file_create("/etc/apt/sources.list.d/linux.dell.com.sources.list", "deb http://linux.dell.com/repo/community/openmanage/901/trusty trusty main")
+            #run_cmd('gpg --keyserver pool.sks-keyservers.net --recv-key 1285491434D8786F', argShell=True)
+            #run_cmd('gpg -a --export 1285491434D8786F |  apt-key add -', argShell=True)
+            #run_cmd('apt-get update')
+            #apt_install('srvadmin-storageservices rpm srvadmin-base srvadmin-idracadm8 srvadmin-oslog srvadmin-server-cli syscfg raidcfg rpm', force=True)
+            #run_cmd('wget -O /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 https://ftp.iteas.at/public/dell/idrac9/libcrypto.so.1.0.0')
+            #run_cmd('ln -s /usr/bin/rpm /bin/rpm')
+
+            # Nagios Monitoring-Agent
+            if self.monitoring == "nagios":
+                #run_cmd('wget -O /tmp/check-openmanage_3.7.12-1_all.deb https://ftp.iteas.at/public/nagios/plugins/check-openmanage_3.7.12-1_all.deb')
+                #run_cmd('dpkg -i /tmp/check-openmanage_3.7.12-1_all.deb')
+
+                #run_cmd('wget -O /usr/lib/nagios/plugins/check_openmanage https://ftp.iteas.at/public/nagios/plugins/check_openmanage')
+                #run_cmd('chmod +x /usr/lib/nagios/plugins/check_openmanage')
+                #file_append("/etc/nagios/nrpe.cfg", "#command[check_openmanage]=/usr/lib/nagios/plugins/check_openmanage -p -I")
+
+                apt_install('snmp smistrip')
+                run_cmd('wget -O /tmp/snmp-mibs-downloader_1.1+nmu1_all.deb https://cloud.iteas.at/nextcloud/s/aJqEYa5znggxRsd/download?path=%2Fsoftware%2Fdell%2Fidrac9&files=snmp-mibs-downloader_1.1%2Bnmu1_all.deb')
+                run_cmd('dpkg -i /tmp/snmp-mibs-downloader_1.1+nmu1_all.deb')
+                run_cmd('wget -O /usr/share/snmp/mibs/idrac-smiv2.mib https://git.styrion.net/iteas/nagios-iteas-addons/raw/master/mibs/idrac-smiv2.mib')
+                run_cmd('wget -O /usr/lib/nagios/plugins/idrac_2.2rc4.py https://git.styrion.net/iteas/nagios-iteas-addons/raw/master/plugins/idrac_2.2rc4.py')
+                run_cmd('chmod +x /usr/lib/nagios/plugins/idrac_2.2rc4.py')
+                file_append("/etc/nagios/nrpe.cfg", "command[check_openmanage]=/usr/lib/nagios/plugins/idrac_2.2rc4 -H 10.10.10.10 -v 2c -c public")
+
+        elif self.machine_vendor == "tk":
+            # IPMI Tools
+            apt_install('ipmitool ipmiutil')
+
+        # Configure IPMI
+        if self.ipmi_config:
+            # Thanks TK-Wiki: https://www.thomas-krenn.com/de/wiki/IPMI_Konfiguration_unter_Linux_mittels_ipmitool
+            run_cmd('ipmitool lan set 1 ipsrc static', argShell=True)
+            run_cmd('ipmitool lan set 1 ipaddr "%s"' % self.ipmi_ip, argShell=True)
+            run_cmd('ipmitool lan set 1 netmask "%s"' % self.ipmi_netmask, argShell=True)
+            run_cmd('ipmitool lan set 1 defgw ipaddr "%s"' % self.ipmi_gateway, argShell=True)
+            run_cmd('ipmitool user set name 2 "%s"' % self.ipmi_user, argShell=True)
+            run_cmd('ipmitool user set password 2 "%s"' % self.ipmi_pass, argShell=True)
+            run_cmd('ipmitool channel setaccess 1 2 link=on ipmi=on callin=on privilege=4', argShell=True)
+            run_cmd('ipmitool user enable 2', argShell=True)
+
+        # Install puppet
+        if self.puppet == "generic":
+            run_cmd('wget -O /tmp/install_puppet.sh https://git.styrion.net/iteas/iteas-tools/raw/master/puppet/proxmox_mit_puppet.sh && chmod +x /tmp/install_puppet.sh', argShell=True)
+            run_cmd('echo "\n" | /tmp/install_puppet.sh', argShell=True)
+        elif self.puppet == "proxmox-desktop":
+            run_cmd('wget -O /tmp/install_puppet.sh https://git.styrion.net/iteas/iteas-tools/raw/master/puppet/proxmox_mit_puppet.sh && chmod +x /tmp/install_puppet.sh', argShell=True)
+            run_cmd('echo "\n" | /tmp/install_puppet.sh', argShell=True)
+
+        # Desktop Konfiguration
+        if self.desktop == "plasma-light":
+            apt_install('lm-sensors curl nomachine firefox-esr firefox-esr-l10n-de virt-viewer kde-plasma-desktop qapt-deb-installer filelight khelpcenter mpv curl task-german-kde-desktop task-german hunspell-de-at hunspell-de-ch hyphen-de mythes-de-ch mythes-de git kate')
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('useradd iteasadm -c iteasadm -G dialout,cdrom,video,plugdev,games,sudo -m -s /bin/zsh -U -p \'$1$CvBQaSeR$0phJus.ly543oq2fKOtT40\'', argShell=True)
+
+        elif self.desktop == "plasma-light-win":
+            apt_install('lm-sensors curl nomachine firefox-esr firefox-esr-l10n-de virt-viewer kde-plasma-desktop qapt-deb-installer filelight khelpcenter mpv curl task-german-kde-desktop task-german hunspell-de-at hunspell-de-ch hyphen-de mythes-de-ch mythes-de git kate')
+            run_cmd('apt remove -y konqueror', argShell=True)
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('pveum user add user@pve', argShell=True)
+            run_cmd('echo "123123\n123123" | pveum passwd user@pve', argShell=True)
+            run_cmd('useradd user -c user -G dialout,cdrom,video,plugdev,games -m -s /bin/zsh -U -p \'$1$bXXXRpOf$cLs.kEex6rSD8horkJzru0\'', argShell=True)
+            run_cmd('wget -O /etc/sddm.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/etc/sddm.conf-user-autologon')
+            run_cmd('cd /tmp && git clone https://gitlab+deploy-token-1:-9F-Ty1feEf-9sQy_if4@git.styrion.net/iteas/proxmox-workstation.git && rm -rf /home/user && cp -r proxmox-workstation /home/user && chown -R user:user /home/user', argShell=True)
+            run_cmd('pvesm set local -disable', argShell=True)
+
+        elif self.desktop == "plasma":
+            apt_install('lm-sensors curl nomachine firefox-esr firefox-esr-l10n-de virt-viewer kde-plasma-desktop qapt-deb-installer filelight khelpcenter mpv curl task-german-kde-desktop task-german hunspell-de-at hunspell-de-ch hyphen-de mythes-de-ch mythes-de git kde-standard plasma-desktop task-german-desktop libreoffice-l10n-de mpv muon speedtest-cli x2goclient filezilla mactelnet-client ksystemlog kate gtkterm sddm-theme-debian-breeze')
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('useradd iteasadm -c iteasadm -G dialout,cdrom,video,plugdev,games,sudo -m -s /bin/zsh -U -p \'$1$CvBQaSeR$0phJus.ly543oq2fKOtT40\'', argShell=True)
+
+        elif self.desktop == "i3":
+            pass
+
+        run_cmd('apt-get install -f; apt autoremove --purge -y;')
+        if self.proxy == True:
+            run_cmd('rm /etc/apt/apt.conf.d/01proxy')
+
+        # Install Proxmox Config Backup Script
+        B_SCRIPT = """#!/bin/bash
+
+usage() { echo "Usage: $0 [-p ]" 1>&2; exit 1; }
+
+while getopts ":p:" o; do
+    case "${o}" in
+        p)
+            p=${OPTARG}
+            ;;
+        *)
+            usage
+            ;;
+    esac
+done
+shift $((OPTIND-1))
+
+B_PATH="${p:-/root/}"
+echo "Sichere Backup in $B_PATH"
+tar -cf "$B_PATH`hostname -f`-backup.tar" /etc /root
+"""
+        file_create("/usr/local/bin/backup-proxmox-config", B_SCRIPT)
+        run_cmd('chmod +x /usr/local/bin/backup-proxmox-config')
+
+        sum_txt = """-------------------------------------------------------------------------------
+ITEAS Proxmox Installationsbericht
+
+Loginmoeglichkeiten:
+  https://%s:8006 -> Weboberflaeche Virtualisierung
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  https://%s:10000 -> Weboberflaeche Webmin (NFSfreigaben, Samba, etc.)" % check_systemip(show_prefix=False)
+
+
+        sum_txt += """
+  SSH ueber CMD f.e "ssh root@%s"
+
+Folgende lokale Benutzer wurden angelegt:
+  root (Administrator) SSH, Virtualisierung, Webmin
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  backup (fuer den Zugriff auf Freigaben) Samba"
+
+        sum_txt += """
+
+Das Komplette Installationslog ist auf
+  /var/log/proxmox_install.log einsehbar.
+-------------------------------------------------------------------------------
+"""
+
+        fr = open("/root/proxmox_report.txt", "w")
+        fr.write(sum_txt)
+        fr.close()
+
+        gui_text_box("/root/proxmox_report.txt")
+
+        # Installation fertig
+        retval = gui_yesno_box("Installer", "Die Installation wurde abgeschlossen! Moechten Sie den PC/Server neustarten?")
+        if retval[0] == 0:
+            pbox = gui_progress_box("PC/Server wird automatisch neugestartet...", 0)
+            for x in range(0, 5):
+                pbox.update(x*20)
+                time.sleep(1)
+
+            pbox.finish()
+            run_cmd('reboot')
+        elif retval[0] == 1:
+            gui_message_box("Installer", "Sie muessen den PC/Server manuell neustarten um die Installation abzuschliessen!")
+
+
+i = Installer()
+i.start()
+logger.close()
diff --git a/proxmox_install_PVE7.py b/proxmox_install_PVE7.py
new file mode 100755
index 0000000..0c85b37
--- /dev/null
+++ b/proxmox_install_PVE7.py
@@ -0,0 +1,1077 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+#
+# (c) Rene Hadler, Mario Loderer, iteas IT Services GmbH
+# support@iteas.at
+# www.iteas.at
+#
+
+import sys
+import time
+import socket
+import subprocess
+import requests
+import json
+
+# Globale Variablen
+VERSION = "1.2.6"
+TITLE = "iteas Proxmox Installer " + VERSION
+CHECK_INTERNET_IP = "77.235.68.35"
+VM_TEMPLATE_CIFS_SHARE = "//10.255.18.3/proxmox-install"
+VM_TEMPLATE_CIFS_USER = "localbackup02"
+SMB_ADMIN_PASSWD = "backmode123"
+
+
+try:
+    CONSOLE_ROWS, CONSOLE_COLS = subprocess.check_output(['stty', 'size']).split()
+except:
+    CONSOLE_ROWS = 40
+    CONSOLE_COLS = 100
+
+GUI_WIN_WIDTH = 100 if int(CONSOLE_COLS) > 110 else (int(CONSOLE_COLS) - 10)
+
+class Logger:
+    def __init__(self):
+        self.f = fr = open("proxmox_install.log", "w+")
+
+    def log(self, text):
+        self.f.write(text)
+
+    def close(self):
+        self.f.close()
+
+logger = Logger()
+
+# Befehle ausfĂĽhren
+def run_cmd(command, argShell=False):
+    try:
+        return subprocess.call(command.split(" ") if argShell == False else command, shell=argShell)
+    except:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Fehler", "Befehl <%s> war nicht erfolgreich, Fehlermeldung: %s -- Installation abbrechen?" % (command, e))
+        if retval[0] == 0:
+            exit(1)
+
+def apt_install(pkgs, argShell=False, force=False):
+    command = "apt-get install -y %s %s" % (pkgs, "--force-yes" if force else "")
+    try:
+        print(command)
+        ret = subprocess.call(command.split(" ") if argShell == False else command, shell=argShell)
+        if ret != 0:
+            retval = gui_yesno_box("APT-Fehler", 'Befehl <%s> war nicht erfolgreich, Rueckgabewert war nicht 0, Fehlermeldung: \n--\n%s \n--\nInstallation abbrechen?' % (command, ret[2]))
+            if retval[0] == 0:
+                exit(1)
+    except SystemExit:
+        exit(1)
+    except:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Fehler", "Befehl <%s> war nicht erfolgreich, Fehlermeldung: %s -- Installation abbrechen?" % (command, e))
+        if retval[0] == 0:
+            exit(1)
+
+def run_cmd_output(command, argShell=False):
+    p = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read().decode('UTF-8'), p.stderr.read().decode('UTF-8'))
+
+def run_cmd_stdout(command, argShell=False):
+    p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read().decode('UTF-8'))
+
+def run_cmd_stderr(command, argShell=False):
+    p = subprocess.Popen(command, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stderr.read().decode('UTF-8'))
+
+def run_cmd_stdin(command, argShell=False):
+    p = subprocess.Popen(command, stdin=subprocess.PIPE, shell=argShell)
+    return p
+
+# Oberflächen / GUI
+def gui_message_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--msgbox", text, "--title", title, "20", str(GUI_WIN_WIDTH)])
+
+def gui_text_box(file):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--textbox", file, "20", str(GUI_WIN_WIDTH)])
+
+def gui_input_box(title, text, default=""):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--inputbox", text, "20", str(GUI_WIN_WIDTH), default, "--title", title])
+
+def gui_yesno_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--yesno", text, "--title", title, "20", str(GUI_WIN_WIDTH)])
+
+def gui_password_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--passwordbox", text.encode('UTF-8'), "8", str(GUI_WIN_WIDTH), "--title", title.encode('UTF-8')])
+
+def gui_menu_box(title, text, menu):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--menu", text, "--title", title, "28", str(GUI_WIN_WIDTH), "22"] + menu)
+
+def gui_checklist_box(title, text, checklist):
+    ret = run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--checklist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + checklist)
+    return (ret[0], [] if ret[1] == "" else [x.replace('"', "") for x in ret[1].split(" ")])
+
+def gui_radiolist_box(title, text, radiolist):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--radiolist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + radiolist)
+
+class gui_progress_box():
+    def __init__(self, text, progress):
+        self.p = run_cmd_stdin(["whiptail", "--backtitle", TITLE, "--gauge", text, "6", "50", str(progress)])
+
+    def update(self, prog):
+        upd = "%s\n" % prog
+        self.p.stdin.write(upd.encode('utf-8'))
+        self.p.stdin.flush()
+
+    def finish(self):
+        self.p.stdin.close()
+
+def gui_password_verify_box(title, text, text2):
+    password = ""
+    while password == "":
+        retval = gui_password_box(title, text)
+        if retval[1] == "":
+            continue
+
+        retval2 = gui_password_box(title, text2)
+        if retval2[1] == "":
+            continue
+
+        if retval[1] == retval2[1]:
+            password = retval[1]
+        else:
+            gui_message_box(title, "Fehler bei der Passworteingabe, die Passwoerter stimmen nicht ueberein!")
+
+    return password
+
+# Sonstige Funktionen
+def check_internet():
+    try:
+        s = socket.create_connection((CHECK_INTERNET_IP, 80), 5)
+        return True
+    except:
+        return False
+
+def check_filesystem():
+    try:
+        zfsc = run_cmd_output('zfs list')
+        if zfsc[0] == 1 or zfsc[2].find('no datasets') != -1:
+            return 'standard'
+        else:
+            return 'zfs'
+    except:
+        return 'standard'
+
+def check_systemip(show_prefix = True):
+    zfsc = run_cmd_stdout("ip addr show vmbr0 | grep 'inet' | grep -v 'inet6' | cut -d' ' -f6", argShell=True)
+    if show_prefix == True:
+        return zfsc[1].strip()
+    else:
+        return zfsc[1].strip().split("/")[0]
+
+def check_systemipnet():
+    try:
+        zfsc = check_systemip()
+        if zfsc == '':
+            return ''
+        else:
+            # Nicht immer true
+            ipf = zfsc.split(".")
+            return "%s.%s.%s.0/%s" % (ipf[0], ipf[1], ipf[2], ipf[3].split("/")[1])
+    except:
+        return ''
+
+def file_replace_line(file, findstr, replstr, encoding='utf-8'):
+    try:
+        fp = open(file, "r+", encoding=encoding)
+        buf = ""
+        for line in fp.readlines():
+            if line.find(findstr) != -1:
+                line = replstr + "\n"
+
+            buf += line
+
+        fp.close()
+        fr = open(file, "w+", encoding=encoding)
+        fr.write(buf)
+        fr.close()
+    except FileNotFoundError:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Fehler", "Datei <%s> wurde nicht gefunden, Fehlermeldung: %s -- Installation abbrechen?" % (file, e))
+        if retval[0] == 0:
+            exit(1)
+
+def file_create(file, str):
+    fr = open(file, "w+")
+    fr.write(str + "\n")
+    fr.close()
+
+def file_append(file, str):
+    fr = open(file, "a")
+    fr.write(str + "\n")
+    fr.close()
+
+# Installer Start
+class Installer():
+    def __init__(self):
+        self.internet = False
+        self.fqdn = socket.getfqdn()
+        try:
+            self.domain = self.fqdn.split(".")[1] + "." + self.fqdn.split(".")[2]
+            self.hostname = socket.gethostname()
+        except:
+            gui_message_box("Installer", "FQDN ist nicht richtig gesetzt, Installation wird abgebrochen!")
+            exit(1)
+
+        self.machine_vendor = "other"
+        self.machine_type = "virt"
+        self.environment = "stable"
+        self.monitoring = "checkmk"
+        self.license = ""
+        self.filesystem = ""
+        self.vm_import = []
+        self.lxc_import = []
+        self.storage_import = ""
+        self.share_clients = []
+        self.proxy = False
+        self.desktop = "kein"
+        self.puppet = "kein"
+
+        self.ipmi_config = False
+        self.ipmi_ip = ""
+        self.ipmi_netmask = ""
+        self.ipmi_gateway = ""
+        self.ipmi_dns = ""
+        self.ipmi_user = ""
+        self.ipmi_pass = ""
+
+        # Installer Variablen
+        self.MACHINE_VENDORS = {"hp": "HP < Gen 10", "hp10": "HP Gen 10", "tk": "Thomas Krenn", "other": "Andere"}
+        self.MACHINE_TYPES = {"virt": "Virtualisierung", "backup": "Backup"}
+        self.ENVIRONMENTS = {"stable": "Stabile Proxmox Enterprise Updates", "test": "Proxmox Testing Updates", "noupdate": "Keine Proxmox Updates"}
+        self.MONITORINGS = {"none": "Keine", "checkmk": "CheckMK Agent"}
+        self.FILESYSTEMS = {"standard": "Standard (ext3/4, reiserfs, xfs)", "zfs": "ZFS"}
+        self.DESKTOPS = {
+            "kein": "Nein",
+            "plasma": "KDE5-Plasma",
+            "plasma-light": "KDE5-Plasma Light",
+            "plasma-light-win": "KDE5-Plasma Light Windows Workstation",
+            "i3": "i3-WM (testing)"
+        }
+        self.VM_IMPORTS = {
+            "220": {"name": "Windows 11 Pro", "template": True},
+            "225": {"name": "Windows 10 Pro", "template": True},
+            "169": {"name": "Windows Server 2022 Englisch", "template": True},
+            "148": {"name": "Windows Server 2019 Englisch", "template": True},
+            "222": {"name": "Windows Server 2019 Deutsch", "template": True},
+            "127": {"name": "Rocky9 Standard", "template": True},
+            "170": {"name": "Ubuntu Server Standard 22.04", "template": True}
+            
+        }
+        self.LXC_IMPORTS = {
+            "143": {"name": "ITEAS CT Template Ubuntu 22.04 priv", "template": True },
+            "168": {"name": "ITEAS CT Template Ubuntu 22.04 unpriv", "template": True },
+            "145": {"name": "Iteas Backupsolution Enterprise", "template": False },
+            "123": {"name": "APP-Web-Template", "template": True },
+            "102": {"name": "Samba Backupassist mit ADS Anbindung", "template": True },
+            "121": {"name": "Samba Backupassist ohne ADS Anbindung", "template": True },
+        }
+        self.PUPPETS = {
+            "kein": "Nein",
+            "generic": "Generische Installation",
+            "proxmox-desktop": "Proxmox Desktop"
+        }
+
+    def start(self):
+        gui_message_box("Installer", "Willkommen beim iteas Proxmox Installer!")
+        self.internet = check_internet()
+        self.filesystem = check_filesystem()
+        if check_systemipnet() != '':
+            self.share_clients.append(check_systemipnet())
+        self.step1()
+
+    def step1(self):
+        step1_val = gui_menu_box("Schritt 1", "Kontrollieren bzw. konfigurieren Sie die entsprechenden Werte und gehen Sie dann auf 'Weiter'.",
+                                    ["Internet", "JA" if self.internet == True else "NEIN",
+                                     "Hostname", self.hostname,
+                                     "Domain", self.domain,
+                                     "Dateisystem", self.FILESYSTEMS[self.filesystem],
+                                     " ", " ",
+                                     "Maschinenhersteller", self.MACHINE_VENDORS[self.machine_vendor],
+                                     "Maschinentyp", self.MACHINE_TYPES[self.machine_type],
+                                     "IPMI-Konfiguration", "Ja" if self.ipmi_config == True else "Nein",
+                                     "Proxmox-Umgebung", self.ENVIRONMENTS[self.environment],
+                                     "Proxmox-Lizenz", "Keine" if self.license == "" else self.license,
+                                     "VM-Template-Import", ",".join([self.VM_IMPORTS[x]["name"] for x in self.vm_import]) if len(self.vm_import) > 0 else "Keine",
+                                     "LXC-Template-Import", ",".join([self.LXC_IMPORTS[x]["name"] for x in self.lxc_import]) if len(self.lxc_import) > 0 else "Keine",
+                                     "Import-Storage", "Keine" if self.storage_import == "" else self.storage_import,
+                                     "Freigabe-Clients-SMB", ",".join([x for x in self.share_clients]) if len(self.share_clients) > 0 else "Alle",
+                                     "apt-Proxy", "Nein" if self.proxy == False else "Ja",
+                                     "Desktop", self.DESKTOPS[self.desktop],
+                                     "Monitoring-Agent", self.MONITORINGS[self.monitoring],
+                                     "Puppet", self.PUPPETS[self.puppet],
+                                     " ", " ",
+                                     "Weiter", "Installation fortsetzen"])
+
+        # Abbrechen
+        if step1_val[0] == 1 or step1_val[0] == 255:
+            exit(0)
+
+        # Eintrag wurde gewählt
+        if step1_val[1] == "Maschinenhersteller":
+            self.step1_machine_vendor()
+
+        elif step1_val[1] == "Maschinentyp":
+            self.step1_machine_type()
+
+        elif step1_val[1] == "Proxmox-Umgebung":
+            self.step1_environment()
+
+        elif step1_val[1] == "Monitoring-Agent":
+            self.step1_monitoring()
+
+        elif step1_val[1] == "Proxmox-Lizenz":
+            self.step1_license()
+
+        elif step1_val[1] == "apt-Proxy":
+            self.step1_aptproxy()
+
+        elif step1_val[1] == "Desktop":
+            self.step1_desktop()
+
+        elif step1_val[1] == "VM-Template-Import":
+            self.step1_vmtemplateimport()
+
+        elif step1_val[1] == "LXC-Template-Import":
+            self.step1_lxctemplateimport()
+
+        elif step1_val[1] == "Internet":
+            check_internet()
+            self.step1()
+
+        elif step1_val[1] == "Freigabe-Clients-SMB":
+            self.step1_shareclients()
+
+        elif step1_val[1] == "Weiter":
+            self.step2()
+
+        elif step1_val[1] == "Puppet":
+            self.step1_puppet()
+
+        elif step1_val[1] == "IPMI-Konfiguration":
+            self.step1_ipmi_main()
+
+        elif step1_val[1] == "Import-Storage":
+            self.step1_import_storage()
+
+        else:
+            self.step1()
+
+    def step1_ipmi_main(self):
+        step1_val = gui_menu_box("IPMI-Konfiguration", "Kontrollieren bzw. konfigurieren Sie IPMI 'Weiter'.",
+                                 ["IPMI-Konfiguration ", "Ja" if self.ipmi_config == True else "Nein",
+                                  " ", " ",
+                                  "IP-Adresse", self.ipmi_ip,
+                                  "IP-Subnet", self.ipmi_netmask,
+                                  "Gateway", self.ipmi_gateway,
+                                  "DNS", self.ipmi_dns,
+                                  " ", " ",
+                                  "Benutzername", self.ipmi_user,
+                                  "Passwort", self.ipmi_pass[0:3] + (len(self.ipmi_pass)-3)*"*",
+                                  " ", " ",
+                                  "Zurueck", "Hauptmenu"])
+
+        # Abbrechen
+        if step1_val[0] == 1 or step1_val[0] == 255:
+            self.step1()
+
+        # Eintrag wurde gewählt
+        if step1_val[1] == "IPMI-Konfiguration ":
+            self.step1_ipmi_config()
+
+        elif step1_val[1] == "IP-Adresse":
+            self.step1_ipmi_ip()
+
+        elif step1_val[1] == "IP-Subnet":
+            self.step1_ipmi_netmask()
+
+        elif step1_val[1] == "Gateway":
+            self.step1_ipmi_gateway()
+
+        elif step1_val[1] == "DNS":
+            self.step1_ipmi_dns()
+
+        elif step1_val[1] == "Benutzername":
+            self.step1_ipmi_user()
+
+        elif step1_val[1] == "Passwort":
+            self.step1_ipmi_pass()
+
+        elif step1_val[1] == "Zurueck":
+            self.step1()
+
+        else:
+            self.step1_ipmi_main()
+
+    def step1_ipmi_config(self):
+        retval = gui_yesno_box("IPMI", "Mochten Sie IPMI konfigurieren?")
+        if retval[0] == 0:
+            self.ipmi_config = True
+        elif retval[0] == 1:
+            self.ipmi_config = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.step1_ipmi_main()
+
+    def step1_ipmi_ip(self):
+        retval = gui_input_box("IPMI IP-Adresse", "IP-Adresse eingeben", self.ipmi_ip)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_ip = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_netmask(self):
+        retval = gui_input_box("IPMI IP-Subnet", "IP-Subnet eingeben", self.ipmi_netmask)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_netmask = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_gateway(self):
+        retval = gui_input_box("IPMI Gateway", "Gateway eingeben", self.ipmi_gateway)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_gateway = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_dns(self):
+        retval = gui_input_box("IPMI DNS", "DNS eingeben", self.ipmi_dns)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_dns = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_user(self):
+        retval = gui_input_box("IPMI Benutzer", "Benutzer eingeben", self.ipmi_user)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_user = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_pass(self):
+        retval = gui_password_box("IPMI Passwort", "Passwort eingeben")
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_pass = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_machine_vendor(self):
+        list = []
+        for key, val in self.MACHINE_VENDORS.items():
+            list += [key, val, "ON" if self.machine_vendor == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Maschinenhersteller", "Waehlen sie den passenden Maschinenhersteller", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_vendor = retval[1]
+        self.step1()
+
+    def step1_machine_type(self):
+        list = []
+        for key, val in self.MACHINE_TYPES.items():
+            list += [key, val, "ON" if self.machine_type == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Maschinentyp", "Waehlen sie den passenden Maschinentyp", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_type = retval[1]
+        self.step1()
+
+    def step1_environment(self):
+        list = []
+        for key, val in self.ENVIRONMENTS.items():
+            list += [key, val, "ON" if self.environment == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Proxmox-Umgebung", "Waehlen sie die Proxmox-Umgebung", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.environment = retval[1]
+        self.step1()
+
+    def step1_monitoring(self):
+        list = []
+        for key, val in self.MONITORINGS.items():
+            list += [key, val, "ON" if self.monitoring == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Monitoring-Agent", "Waehlen sie den Monitoring-Agenten", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.monitoring = retval[1]
+        self.step1()
+
+    def step1_license(self):
+        retval = gui_input_box("Schritt 1: Proxmox-Lizenz", "Geben Sie den Proxmox-Schluessel ein", self.license)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.license = retval[1]
+        self.step1()
+
+    def step1_aptproxy(self):
+        retval = gui_yesno_box("Installer", "Mochten Sie den iteas apt-Proxy benutzen?")
+        if retval[0] == 0:
+            self.proxy = True
+        elif retval[0] == 1:
+            self.proxy = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1()
+            return
+
+        self.step1()
+
+    def step1_desktop(self):
+        list = []
+        for key, val in self.DESKTOPS.items():
+            list += [key, val, "ON" if self.desktop == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Proxmox-Desktop", "Waehlen sie einen Desktop", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.desktop = retval[1]
+        self.step1()
+
+    def step1_vmtemplateimport(self):
+        list = []
+        for key, val in self.VM_IMPORTS.items():
+            list += [key, val["name"], "ON" if key in self.vm_import else "OFF"]
+
+        retval = gui_checklist_box("Schritt 1: VM-Template-Import", "Waehlen sie die VMs die importiert werden sollen", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.vm_import = []
+        for val in retval[1]:
+            self.vm_import += [val]
+
+        self.step1()
+
+    def step1_lxctemplateimport(self):
+        list = []
+        for key, val in self.LXC_IMPORTS.items():
+            list += [key, val["name"], "ON" if key in self.lxc_import else "OFF"]
+
+        retval = gui_checklist_box("Schritt 1: LXC-Template-Import", "Waehlen sie die LXC Container die importiert werden sollen", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.lxc_import = []
+        for val in retval[1]:
+            self.lxc_import += [val]
+
+        self.step1()
+
+    def step1_shareclients(self):
+        retval = gui_input_box("Schritt 1: Freigabe-Clients", "Geben Sie die Clients/Netze an, die Zugriffe auf die Freigaben am Proxmox Host haben sollen. Mehrere Eintraege muessen durch Leerzeichen getrennt sein.", " ".join(self.share_clients))
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.share_clients = retval[1].split(" ")
+        self.step1()
+
+    def step1_puppet(self):
+        list = []
+        for key, val in self.PUPPETS.items():
+            list += [key, val, "ON" if self.puppet == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Puppet", "Waehlen sie eine Puppet Installationsart", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.puppet = retval[1]
+        self.step1()
+
+    def step1_import_storage(self):
+        list = []
+        jstorages = json.loads(run_cmd_stdout("pvesh get /storage --output-format json", argShell=True)[1])
+        for storage in jstorages:
+            list += [storage["storage"], storage["content"], "ON" if self.storage_import == storage["storage"] else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Import-Storage", "Waehlen sie ein Storage fĂĽr den Template Import", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.storage_import = retval[1]
+        self.step1()
+
+    def step2(self):
+
+        if self.environment == "stable" and self.license == "":
+            gui_message_box("Installer", "Sie muessen eine Lizenz angeben wenn Enterprise Updates ausgewaehlt wurden!")
+            self.step1()
+            return
+
+        if self.internet == False:
+            gui_message_box("Installer", "Es muss eine Internetverbindung bestehen um fortzufahren!")
+            self.step1()
+            return
+
+        if (len(self.vm_import) > 0 or len(self.lxc_import) > 0) and self.storage_import == "":
+            gui_message_box("Installer", "Sie mĂĽssen ein Import-Storage angeben!")
+            self.step1()
+            return
+
+        # Set locales
+        file_replace_line("/etc/locale.gen", "# de_AT.UTF-8 UTF-8", "de_AT.UTF-8 UTF-8")
+        file_replace_line("/etc/locale.gen", "# de_DE.UTF-8 UTF-8", "de_DE.UTF-8 UTF-8")
+        run_cmd('locale-gen', argShell=True)
+
+        ############ Allgemeine Konfiguration
+        if self.license != "":
+            retval = run_cmd_output('pvesubscription set ' + self.license)
+            if retval[0] == 255:
+                gui_message_box("Proxmox Lizenzinstallation", "Die Lizenz konnte nicht installiert werden, bitte pruefen Sie Ihre Lizenznummer. Fehler: " + retval[2])
+                self.step1()
+                return
+
+            time.sleep(30)
+
+            # Warte maximal fĂĽr 5 Minuten fĂĽr Registrierung
+            maxwait = 300
+            curwait = 0
+            lictest = run_cmd_stdout('pvesubscription get', argShell=True)
+            while lictest[1].find('status: Active') == -1 and curwait < maxwait:
+                print("Warte auf Registrierung der Proxmox-Subscription..." + str(curwait))
+                time.sleep(10)
+                lictest = run_cmd_stdout('pvesubscription get', argShell=True)
+                curwait += 10
+
+            # Warte maximal fĂĽr 5 Minuten fĂĽr Enterprise-Repo Zugriff
+            curwait = 0
+            httpuser = run_cmd_stdout("pvesubscription get | grep 'key:.*' | cut -f2 -d:", argShell=True)[1].strip()
+            httppass = run_cmd_stdout("pvesubscription get | grep 'serverid:.*' | cut -f2 -d:", argShell=True)[1].strip()
+
+            repotest = requests.get('https://enterprise.proxmox.com/debian/pve', auth=(httpuser, httppass))
+            while repotest.status_code != requests.codes.ok and curwait < maxwait:
+                print("Warte auf Freischaltung des Enterprise-Repos..." + str(curwait))
+                time.sleep(10)
+                repotest = requests.get('https://enterprise.proxmox.com/debian/pve', auth=(httpuser, httppass))
+                curwait += 10
+
+        # Proxmox Testing Quellen aktivieren
+        if self.environment == "test":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian/pve bullseye pve-enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription")
+        elif self.environment == "noupdate":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian/pve bullseye pve-enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "# deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription")
+
+        # If lvm-thin convert to standard file storage if backup-machine
+        if self.machine_type == "backup" and run_cmd('pvesh get /storage | grep -i local-lvm', argShell=True) == 0:
+            run_cmd('pvesh delete /storage/local-lvm')
+            run_cmd('lvremove /dev/pve/data -f')
+            run_cmd('lvcreate -Wy -l100%FREE -ndata pve')
+            run_cmd('mkfs.ext4 -m1 /dev/pve/data')
+            run_cmd('mount /dev/pve/data /var/lib/vz')
+            file_append("/etc/fstab", "/dev/pve/data /var/lib/vz ext4 defaults 0 2")
+
+        # Mount Template CIFS-Share und importiere VMs
+        #storage = "local"
+        #if run_cmd('pvesh get /storage | grep -i local-lvm', argShell=True) == 0:
+        #    storage = "local-lvm"
+        #
+        #if self.filesystem == "zfs":
+        #    storage = "local-zfs"
+        storage = self.storage_import
+
+        if len(self.vm_import) > 0 or len(self.lxc_import) > 0:
+            retval = gui_password_box("Samba Passwort benötigt", "Bitte das Passwort für Share " + VM_TEMPLATE_CIFS_SHARE + " und Benutzer " + VM_TEMPLATE_CIFS_USER + " eingeben.")
+            VM_TEMPLATE_CIFS_PASS = retval[1]
+
+            cifscnt = 1
+            run_cmd('mkdir -p /mnt/proxmox-install-import', argShell=True)
+            cifstest = run_cmd('mount -t cifs -o user=' + VM_TEMPLATE_CIFS_USER + ",password=" + VM_TEMPLATE_CIFS_PASS + " " + VM_TEMPLATE_CIFS_SHARE + ' /mnt/proxmox-install-import')
+            while cifstest != 0 and cifscnt < 3:
+                retval = gui_password_box("Passwort falsch, Samba Passwort benötigt", "Bitte das Passwort für Share " + VM_TEMPLATE_CIFS_SHARE + " und Benutzer " + VM_TEMPLATE_CIFS_USER + " erneut eingeben.")
+                VM_TEMPLATE_CIFS_PASS = retval[1]
+                cifstest = run_cmd('mount -t cifs -o user=' + VM_TEMPLATE_CIFS_USER + ",password=" + VM_TEMPLATE_CIFS_PASS + " " + VM_TEMPLATE_CIFS_SHARE + ' /mnt/proxmox-install-import')
+                if cifstest == 0:
+                    break
+                cifscnt += 1
+
+            if cifstest == 0:
+                # Import selected VMs
+                for vm_id in self.vm_import:
+                    (ret, filename) = run_cmd_stdout("ls -t /mnt/proxmox-install-import/vzdump-qemu-%s*vma.zst | head -n1" % vm_id, argShell=True)
+                    if filename != "":
+                        run_cmd("qmrestore %s %s -storage %s" % (filename.strip(), vm_id, storage))
+                        if self.VM_IMPORTS[vm_id]["template"] == True:
+                            run_cmd("qm template %s" % vm_id)
+
+                # Import selected LXCs
+                for vm_id in self.lxc_import:
+                    (ret, filename) = run_cmd_stdout("ls -t /mnt/proxmox-install-import/vzdump-lxc-%s-*.tar.zst | head -n1" % vm_id, argShell=True)
+                    if filename != "":
+                        run_cmd("pct restore %s %s -storage %s" % (vm_id, filename.strip(), storage))
+                        if self.LXC_IMPORTS[vm_id]["template"] == True:
+                            run_cmd("pct template %s" % vm_id)
+
+                run_cmd('umount /mnt/proxmox-install-import')
+            else:
+                gui_message_box("Installer", "CIFS konnte nicht gemounted werden (Passwort falsch?), VMs werden nicht importiert!")
+
+            VM_TEMPLATE_CIFS_PASS = ""
+
+        # Apt-Proxy Cache
+        if self.proxy == True:
+            file_create("/etc/apt/apt.conf.d/01proxy", 'Acquire::http { Proxy "http://10.69.99.10:3142"; };')
+
+        # Installieren allgemeine Tools und Monitoring-Agent
+        run_cmd('apt-get update')
+        apt_install('dirmngr')
+        #file_create("/etc/apt/sources.list.d/iteas.list", "deb https://apt.iteas.at/iteas bullseye main")
+        run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 23CAE45582EB0928', argShell=True)
+        run_cmd('wget https://apt.iteas.at/iteas-keyring.gpg -O /etc/apt/trusted.gpg.d/iteas-keyring.gpg', argShell=True)
+        run_cmd('apt-get update')
+        run_cmd('apt-get dist-upgrade -y')
+        apt_install('dirmngr htop unp postfix sudo screen zsh tmux bwm-ng pigz sysstat ethtool nload apcupsd ntfs-3g sl gawk ca-certificates-iteas-enterprise at lsb-release lshw')
+        # ifupdown2 nur installieren wenn nicht "noupdate" gewählt wurde da das Standard Paket in den Debian Quellen nicht mit Proxmox kompatibel ist
+        if self.environment != "noupdate":
+            apt_install('ifupdown2')
+
+        if self.monitoring == "checkmk":
+            apt_install('xinetd check-mk-agent')
+
+        # Spezielle allgemeine Settings fĂĽr ZFS
+        if self.filesystem == "zfs":
+            file_create("/etc/modprobe.d/zfs.conf", "options zfs zfs_arc_max=10737418240")
+            run_cmd('update-initramfs -u', argShell=True)
+
+        # SUDOers
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /usr/bin/rsync")
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /bin/tar")
+
+        # Monitoring Konfiguration
+        if self.monitoring == "checkmk":
+
+            # Check-MK-Agent Config
+            run_cmd('wget -O /tmp/mk_smart https://git.styrion.net/iteas/check_mk-smart-plugin/raw/master/agents/smart')
+            run_cmd('mv /tmp/mk_smart /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_apcupsd https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_apcupsd')
+            run_cmd('mv /tmp/mk_apcupsd /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_dmi_sysinfo https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_dmi_sysinfo')
+            run_cmd('mv /tmp/mk_dmi_sysinfo /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_inventory https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_inventory')
+            run_cmd('mv /tmp/mk_inventory /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_lmsensors https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_lmsensors')
+            run_cmd('mv /tmp/mk_lmsensors /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_logins https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_logins')
+            run_cmd('mv /tmp/mk_logins /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_nfsexports https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_nfsexports')
+            run_cmd('mv /tmp/mk_nfsexports /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_netstat https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_netstat')
+            run_cmd('mv /tmp/mk_netstat /usr/lib/check_mk_agent/plugins/')
+            run_cmd('chmod +x /usr/lib/check_mk_agent/plugins/mk_*', argShell=True)
+
+        # APC
+        run_cmd('wget -O /etc/apcupsd/apcupsd.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/etc/apcupsd.conf')
+        file_replace_line("/etc/default/apcupsd", "ISCONFIGURED", "ISCONFIGURED=yes")
+        run_cmd('systemctl enable apcupsd.service')
+
+        # Nano
+        run_cmd('wget -O /tmp/nano.tar https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/config/nano.tar')
+        run_cmd('tar -xf /tmp/nano.tar -C /root')
+        run_cmd('rm /tmp/nano.tar')
+
+        # ZSH
+        run_cmd('wget -O /tmp/zshrc_root https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/config/zshrc_root')
+        run_cmd('mv /tmp/zshrc_root /root/.zshrc')
+        file_replace_line("/root/.zshrc", "iteas.local", 'export PS1="%UDomain:%u %B%F{yellow}' + self.domain + ' $PS1"', encoding='iso8859_15')
+        run_cmd('usermod -s /bin/zsh root')
+
+        # Postfix
+        file_replace_line("/etc/postfix/main.cf", "myhostname=", "myhostname=" + self.fqdn + ".monitoring.iteas.at")
+        file_replace_line("/etc/postfix/main.cf", "relayhost =", "relayhost = smtp.styrion.net")
+        run_cmd('systemctl restart postfix.service')
+
+        # SystemD
+        run_cmd('wget -O /etc/systemd/system/rc.local.shutdown.service https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown.service')
+        run_cmd('wget -O /etc/rc.local.shutdown https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown')
+        run_cmd('systemctl enable rc.local.shutdown.service')
+        
+        # USB-Automount (soll zur manuellen Auswahl stehen)
+        # apt_install('pve6-usb-automount')
+
+        # Kexec (funktioniert nicht)
+        # run_cmd('echo "kexec-tools kexec-tools/load_kexec boolean false" | debconf-set-selections', argShell=True)
+        # apt_install('kexec-tools')
+        # run_cmd('wget -O /etc/systemd/system/kexec-pve.service https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/kexec-pve.service')
+        #run_cmd('systemctl enable kexec-pve.service')
+
+        # SysCTL
+        file_create("/etc/sysctl.d/iteas.conf", "fs.inotify.max_user_watches=5242880")
+        file_append("/etc/sysctl.d/iteas.conf", "fs.inotify.max_user_instances=1024")
+
+        ############ Konfiguration fĂĽr Backup-Server
+        if self.machine_type == "backup":
+            # NFS, Samba & ZFS
+            apt_install('samba')
+
+            #password = gui_password_verify_box("Samba Passwort", "Geben Sie das Passwort fuer den Samba Benutzer 'admin' an:", "Geben Sie das Passwort fuer den Samba Benutzer 'admin' erneut an:")
+            password = SMB_ADMIN_PASSWD
+            run_cmd("groupadd localbackup", argShell=True)
+            run_cmd("useradd localbackup -m -g localbackup -p '%s'" % password, argShell=True)
+            run_cmd("(echo '%s'; echo '%s') | smbpasswd -a localbackup" % (password, password), argShell=True)
+            run_cmd('wget -O /etc/samba/smb.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/samba/backup_default_smb2.conf')
+
+            backup_root = ""
+            if self.filesystem == "zfs":
+                run_cmd('zfs create rpool/vollsicherung')
+                apt_install('zfs-zed')
+                file_replace_line("/etc/samba/smb.conf", "path = /var/lib/vz/vollsicherung", "\tpath = /rpool/vollsicherung")
+                backup_root = "/rpool/vollsicherung"
+            else:
+                run_cmd('mkdir /var/lib/vz/vollsicherung')
+                backup_root = "/var/lib/vz/vollsicherung"
+
+            run_cmd("chown -R localbackup:localbackup %s" % backup_root)
+
+            file_replace_line("/etc/samba/smb.conf", "workgroup = kundendomain.local", "\tworkgroup = %s" % self.domain)
+            if len(self.share_clients) > 0:
+                file_replace_line("/etc/samba/smb.conf", "hosts allow =", "\thosts allow = %s" % " ".join(self.share_clients))
+
+            run_cmd('systemctl enable smbd')
+            run_cmd('systemctl start smbd')
+
+            # Webmin
+            file_create("/etc/apt/sources.list.d/webmin.list", "deb https://download.webmin.com/download/repository sarge contrib")
+            run_cmd("cd /tmp && wget http://www.webmin.com/jcameron-key.asc && apt-key add jcameron-key.asc", argShell=True)
+            apt_install("apt-transport-https curl git")
+            run_cmd("apt-get update", argShell=True)
+            apt_install("webmin")
+            file_append("/etc/webmin/config", "lang_root=de.UTF-8")
+            file_append("/etc/webmin/config", "theme_root=authentic-theme")
+            file_replace_line("/etc/webmin/config", "lang=", "lang=de.UTF-8")
+            file_append("/etc/webmin/miniserv.conf", "preroot_root=authentic-theme")
+            run_cmd('mkdir /etc/webmin/authentic-theme')
+            run_cmd('wget -O /etc/webmin/authentic-theme/favorites.json https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/webmin/favorites.json')
+            run_cmd('systemctl restart webmin')
+
+
+        ############  Konfiguration fĂĽr HP < Gen10
+        if self.machine_vendor == "hp":
+            # HP-Tools
+            file_create("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP bullseye/current non-free")
+            file_append("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP/debian bullseye/current non-free")
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 527BC53A2689B887')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com FADD8D64B1275EA3')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C208ADDE26C2B797')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 26C2B797')
+            run_cmd('apt-get update')
+            apt_install('ssacli hponcfg')
+            run_cmd('ln -s /usr/sbin/ssacli /usr/sbin/hpacucli')
+
+        ############ Konfiguration fĂĽr HP Gen10
+        elif self.machine_vendor == "hp10":
+            # HP-Tools
+            file_create("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP buster/current non-free")
+            file_append("/etc/apt/sources.list.d/hp.list", "deb http://downloads.linux.hpe.com/SDR/downloads/MCP/debian buster/current non-free")
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 527BC53A2689B887')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com FADD8D64B1275EA3')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C208ADDE26C2B797')
+            run_cmd('apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 26C2B797')
+            run_cmd('apt-get update')
+            apt_install('ssacli hponcfg binutils')
+            run_cmd('ln -s /usr/sbin/ssacli /usr/sbin/hpacucli')
+
+        elif self.machine_vendor == "tk":
+            # IPMI Tools
+            apt_install('ipmitool ipmiutil')
+
+        # Configure IPMI
+        if self.ipmi_config:
+            # Thanks TK-Wiki: https://www.thomas-krenn.com/de/wiki/IPMI_Konfiguration_unter_Linux_mittels_ipmitool
+            run_cmd('ipmitool lan set 1 ipsrc static', argShell=True)
+            run_cmd('ipmitool lan set 1 ipaddr "%s"' % self.ipmi_ip, argShell=True)
+            run_cmd('ipmitool lan set 1 netmask "%s"' % self.ipmi_netmask, argShell=True)
+            run_cmd('ipmitool lan set 1 defgw ipaddr "%s"' % self.ipmi_gateway, argShell=True)
+            run_cmd('ipmitool user set name 2 "%s"' % self.ipmi_user, argShell=True)
+            run_cmd('ipmitool user set password 2 "%s"' % self.ipmi_pass, argShell=True)
+            run_cmd('ipmitool channel setaccess 1 2 link=on ipmi=on callin=on privilege=4', argShell=True)
+            run_cmd('ipmitool user enable 2', argShell=True)
+
+        # Install puppet
+        if self.puppet == "generic":
+            run_cmd('wget -O /tmp/install_puppet.sh https://git.styrion.net/iteas/iteas-tools/raw/master/puppet/proxmox_mit_puppet.sh && chmod +x /tmp/install_puppet.sh', argShell=True)
+            run_cmd('echo "\n" | /tmp/install_puppet.sh', argShell=True)
+        elif self.puppet == "proxmox-desktop":
+            run_cmd('wget -O /tmp/install_puppet.sh https://git.styrion.net/iteas/iteas-tools/raw/master/puppet/proxmox_mit_puppet.sh && chmod +x /tmp/install_puppet.sh', argShell=True)
+            run_cmd('echo "\n" | /tmp/install_puppet.sh', argShell=True)
+
+        # Desktop Konfiguration
+        if self.desktop == "plasma-light":
+            apt_install('lm-sensors curl nomachine firefox-esr firefox-esr-l10n-de virt-viewer kde-plasma-desktop qapt-deb-installer filelight khelpcenter mpv curl task-german-kde-desktop task-german hunspell-de-at hunspell-de-ch hyphen-de mythes-de-ch mythes-de git kate')
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('useradd iteasadm -c iteasadm -G dialout,cdrom,video,plugdev,games,sudo -m -s /bin/zsh -U -p \'$1$CvBQaSeR$0phJus.ly543oq2fKOtT40\'', argShell=True)
+
+        elif self.desktop == "plasma-light-win":
+            apt_install('lm-sensors curl nomachine firefox-esr firefox-esr-l10n-de virt-viewer kde-plasma-desktop qapt-deb-installer filelight khelpcenter mpv curl task-german-kde-desktop task-german hunspell-de-at hunspell-de-ch hyphen-de mythes-de-ch mythes-de git kate')
+            run_cmd('apt remove -y konqueror', argShell=True)
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('pveum user add user@pve', argShell=True)
+            run_cmd('echo "123123\n123123" | pveum passwd user@pve', argShell=True)
+            run_cmd('useradd user -c user -G dialout,cdrom,video,plugdev,games -m -s /bin/zsh -U -p \'$1$bXXXRpOf$cLs.kEex6rSD8horkJzru0\'', argShell=True)
+            run_cmd('wget -O /etc/sddm.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/etc/sddm.conf-user-autologon')
+            run_cmd('cd /tmp && git clone https://gitlab+deploy-token-1:-9F-Ty1feEf-9sQy_if4@git.styrion.net/iteas/proxmox-workstation.git && rm -rf /home/user && cp -r proxmox-workstation /home/user && chown -R user:user /home/user', argShell=True)
+            run_cmd('pvesm set local -disable', argShell=True)
+
+        elif self.desktop == "plasma":
+            apt_install('lm-sensors curl nomachine firefox-esr firefox-esr-l10n-de virt-viewer kde-plasma-desktop qapt-deb-installer filelight khelpcenter mpv curl task-german-kde-desktop task-german hunspell-de-at hunspell-de-ch hyphen-de mythes-de-ch mythes-de git kde-standard plasma-desktop task-german-desktop libreoffice-l10n-de mpv muon speedtest-cli x2goclient filezilla mactelnet-client ksystemlog kate gtkterm sddm-theme-debian-breeze')
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('useradd iteasadm -c iteasadm -G dialout,cdrom,video,plugdev,games,sudo -m -s /bin/zsh -U -p \'$1$CvBQaSeR$0phJus.ly543oq2fKOtT40\'', argShell=True)
+
+        elif self.desktop == "i3":
+            pass
+
+        run_cmd('apt-get install -f; apt autoremove --purge -y;', argShell=True)
+        if self.proxy == True:
+            run_cmd('rm /etc/apt/apt.conf.d/01proxy')
+
+        # Install Proxmox Config Backup Script
+        B_SCRIPT = """#!/bin/bash
+
+usage() { echo "Usage: $0 [-p ]" 1>&2; exit 1; }
+
+while getopts ":p:" o; do
+    case "${o}" in
+        p)
+            p=${OPTARG}
+            ;;
+        *)
+            usage
+            ;;
+    esac
+done
+shift $((OPTIND-1))
+
+B_PATH="${p:-/root/}"
+echo "Sichere Backup in $B_PATH"
+tar -cf "$B_PATH`hostname -f`-backup.tar" /etc /root
+"""
+        file_create("/usr/local/bin/backup-proxmox-config", B_SCRIPT)
+        run_cmd('chmod +x /usr/local/bin/backup-proxmox-config')
+
+        sum_txt = """-------------------------------------------------------------------------------
+ITEAS Proxmox Installationsbericht
+
+Loginmoeglichkeiten:
+  https://%s:8006 -> Weboberflaeche Virtualisierung
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  https://%s:10000 -> Weboberflaeche Webmin (NFSfreigaben, Samba, etc.)" % check_systemip(show_prefix=False)
+
+
+        sum_txt += """
+  SSH ueber CMD f.e "ssh root@%s"
+
+Folgende lokale Benutzer wurden angelegt:
+  root (Administrator) SSH, Virtualisierung, Webmin
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  backup (fuer den Zugriff auf Freigaben) Samba"
+
+        sum_txt += """
+
+Das Komplette Installationslog ist auf
+  /var/log/proxmox_install.log einsehbar.
+-------------------------------------------------------------------------------
+"""
+
+        fr = open("/root/proxmox_report.txt", "w")
+        fr.write(sum_txt)
+        fr.close()
+
+        gui_text_box("/root/proxmox_report.txt")
+
+        # Installation fertig
+        retval = gui_yesno_box("Installer", "Die Installation wurde abgeschlossen! Moechten Sie den PC/Server neustarten?")
+        if retval[0] == 0:
+            pbox = gui_progress_box("PC/Server wird automatisch neugestartet...", 0)
+            for x in range(0, 5):
+                pbox.update(x*20)
+                time.sleep(1)
+
+            pbox.finish()
+            run_cmd('reboot')
+        elif retval[0] == 1:
+            gui_message_box("Installer", "Sie muessen den PC/Server manuell neustarten um die Installation abzuschliessen!")
+
+
+i = Installer()
+i.start()
+logger.close()
diff --git a/proxmox_install_PVE8.py b/proxmox_install_PVE8.py
new file mode 100755
index 0000000..11b8a7a
--- /dev/null
+++ b/proxmox_install_PVE8.py
@@ -0,0 +1,1085 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+#
+# (c) Rene Hadler, Mario Loderer, iteas IT Services GmbH
+# support@iteas.at
+# www.iteas.at
+#
+
+import sys
+import time
+import socket
+import subprocess
+import requests
+import json
+
+# Global variables
+VERSION = "1.2.7"
+TITLE = "iteas Proxmox Installer " + VERSION
+CHECK_INTERNET_IP = "77.235.68.35"
+VM_TEMPLATE_CIFS_SHARE = "//10.255.18.3/proxmox-install"
+VM_TEMPLATE_CIFS_USER = "localbackup02"
+SMB_ADMIN_PASSWD = "backmode123"
+
+
+try:
+    CONSOLE_ROWS, CONSOLE_COLS = subprocess.check_output(['stty', 'size']).split()
+except:
+    CONSOLE_ROWS = 40
+    CONSOLE_COLS = 100
+
+GUI_WIN_WIDTH = 100 if int(CONSOLE_COLS) > 110 else (int(CONSOLE_COLS) - 10)
+
+class Logger:
+    def __init__(self):
+        self.f = fr = open("proxmox_install.log", "w+")
+
+    def log(self, text):
+        self.f.write(text)
+
+    def close(self):
+        self.f.close()
+
+logger = Logger()
+
+# Befehle ausfĂĽhren
+def run_cmd(command, argShell=False):
+    try:
+        return subprocess.call(command.split(" ") if argShell == False else command, shell=argShell)
+    except:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Fehler", "Command <%s> was not successful, Error message: %s -- Cancel installation?" % (command, e))
+        if retval[0] == 0:
+            exit(1)
+
+def apt_install(pkgs, argShell=False, force=False):
+    command = "apt install -y %s %s" % (pkgs, "--force-yes" if force else "")
+    try:
+        print(command)
+        ret = subprocess.call(command.split(" ") if argShell == False else command, shell=argShell)
+        if ret != 0:
+            retval = gui_yesno_box("APT-Fehler", 'Command <%s> was not successful, Return value was not 0, Error message: \n--\n%s \n--\nCancel installation?' % (command, ret))
+            if retval[0] == 0:
+                exit(1)
+    except SystemExit:
+        exit(1)
+    except:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Fehler", "Command <%s> was not successful, Error message: %s -- Cancel installation?" % (command, e))
+        if retval[0] == 0:
+            exit(1)
+
+def run_cmd_output(command, argShell=False):
+    p = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read().decode('UTF-8'), p.stderr.read().decode('UTF-8'))
+
+def run_cmd_stdout(command, argShell=False):
+    p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stdout.read().decode('UTF-8'))
+
+def run_cmd_stderr(command, argShell=False):
+    p = subprocess.Popen(command, stderr=subprocess.PIPE, shell=argShell)
+    ret = p.wait()
+    return (ret, p.stderr.read().decode('UTF-8'))
+
+def run_cmd_stdin(command, argShell=False):
+    p = subprocess.Popen(command, stdin=subprocess.PIPE, shell=argShell)
+    return p
+
+# Oberflächen / GUI
+def gui_message_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--msgbox", text, "--title", title, "20", str(GUI_WIN_WIDTH)])
+
+def gui_text_box(file):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--textbox", file, "20", str(GUI_WIN_WIDTH)])
+
+def gui_input_box(title, text, default=""):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--inputbox", text, "20", str(GUI_WIN_WIDTH), default, "--title", title])
+
+def gui_yesno_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--yesno", text, "--title", title, "20", str(GUI_WIN_WIDTH)])
+
+def gui_password_box(title, text):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--passwordbox", text.encode('UTF-8'), "8", str(GUI_WIN_WIDTH), "--title", title.encode('UTF-8')])
+
+def gui_menu_box(title, text, menu):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--menu", text, "--title", title, "28", str(GUI_WIN_WIDTH), "22"] + menu)
+
+def gui_checklist_box(title, text, checklist):
+    ret = run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--checklist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + checklist)
+    return (ret[0], [] if ret[1] == "" else [x.replace('"', "") for x in ret[1].split(" ")])
+
+def gui_radiolist_box(title, text, radiolist):
+    return run_cmd_stderr(["whiptail", "--backtitle", TITLE, "--radiolist", text, "--title", title, "24", str(GUI_WIN_WIDTH), "14"] + radiolist)
+
+class gui_progress_box():
+    def __init__(self, text, progress):
+        self.p = run_cmd_stdin(["whiptail", "--backtitle", TITLE, "--gauge", text, "6", "50", str(progress)])
+
+    def update(self, prog):
+        upd = "%s\n" % prog
+        self.p.stdin.write(upd.encode('utf-8'))
+        self.p.stdin.flush()
+
+    def finish(self):
+        self.p.stdin.close()
+
+def gui_password_verify_box(title, text, text2):
+    password = ""
+    while password == "":
+        retval = gui_password_box(title, text)
+        if retval[1] == "":
+            continue
+
+        retval2 = gui_password_box(title, text2)
+        if retval2[1] == "":
+            continue
+
+        if retval[1] == retval2[1]:
+            password = retval[1]
+        else:
+            gui_message_box(title, "Error in password entry, the passwords do not match!")
+
+    return password
+
+# Sonstige Funktionen
+def check_internet():
+    try:
+        s = socket.create_connection((CHECK_INTERNET_IP, 80), 5)
+        return True
+    except:
+        return False
+
+def check_filesystem():
+    try:
+        zfsc = run_cmd_output('zfs list')
+        if zfsc[0] == 1 or zfsc[2].find('no datasets') != -1:
+            return 'standard'
+        else:
+            return 'zfs'
+    except:
+        return 'standard'
+
+def check_systemip(show_prefix = True):
+    zfsc = run_cmd_stdout("ip addr show vmbr0 | grep 'inet' | grep -v 'inet6' | cut -d' ' -f6", argShell=True)
+    if show_prefix == True:
+        return zfsc[1].strip()
+    else:
+        return zfsc[1].strip().split("/")[0]
+
+def check_systemipnet():
+    try:
+        zfsc = check_systemip()
+        if zfsc == '':
+            return ''
+        else:
+            # Nicht immer true
+            ipf = zfsc.split(".")
+            return "%s.%s.%s.0/%s" % (ipf[0], ipf[1], ipf[2], ipf[3].split("/")[1])
+    except:
+        return ''
+
+def file_replace_line(file, findstr, replstr, encoding='utf-8'):
+    try:
+        fp = open(file, "r+", encoding=encoding)
+        buf = ""
+        for line in fp.readlines():
+            if line.find(findstr) != -1:
+                line = replstr + "\n"
+
+            buf += line
+
+        fp.close()
+        fr = open(file, "w+", encoding=encoding)
+        fr.write(buf)
+        fr.close()
+    except FileNotFoundError:
+        e = sys.exc_info()[0]
+        retval = gui_yesno_box("Error", "File <%s> not found, error message: %s -- Cancel installation?" % (file, e))
+        if retval[0] == 0:
+            exit(1)
+
+def file_create(file, str):
+    fr = open(file, "w+")
+    fr.write(str + "\n")
+    fr.close()
+
+def file_append(file, str):
+    fr = open(file, "a")
+    fr.write(str + "\n")
+    fr.close()
+
+# Installer Start
+class Installer():
+    def __init__(self):
+        self.internet = False
+        self.fqdn = socket.getfqdn()
+        try:
+            self.domain = self.fqdn.split(".")[1] + "." + self.fqdn.split(".")[2]
+            self.hostname = socket.gethostname()
+        except:
+            gui_message_box("Installer", "FQDN is not set, Installation will be aborted!")
+            exit(1)
+
+        self.machine_vendor = "other"
+        self.machine_type = "virt"
+        self.environment = "stable"
+        self.monitoring = "checkmk"
+        self.license = ""
+        self.filesystem = ""
+        self.vm_import = []
+        self.lxc_import = []
+        self.storage_import = ""
+        self.share_clients = []
+        self.proxy = False
+        self.desktop = "kein"
+        self.webmin = "no"
+        self.puppet = "kein"
+        self.ipmi_config = False
+        self.ipmi_ip = ""
+        self.ipmi_netmask = ""
+        self.ipmi_gateway = ""
+        self.ipmi_dns = ""
+        self.ipmi_user = ""
+        self.ipmi_pass = ""
+
+        # Installer Variablen
+        self.MACHINE_VENDORS = {"hp": "Hewlett Packard", "tk": "Thomas Krenn", "other": "Andere"}
+        self.MACHINE_TYPES = {"virt": "Virtualization", "backup": "Backup"}
+        self.ENVIRONMENTS = {"stable": "Stable Proxmox Enterprise Updates", "test": "Proxmox Nosubscription Updates", "noupdate": "no Proxmox Updates"}
+        self.MONITORINGS = {"none": "Keine", "checkmk": "CheckMK Agent"}
+        self.FILESYSTEMS = {"standard": "Default (ext3/4, reiserfs, xfs)", "zfs": "ZFS"}
+        self.DESKTOPS = {
+            "kein": "Nein",
+            "plasma": "KDE5-Plasma",
+            "plasma-light": "KDE5-Plasma Light",
+            "plasma-light-win": "KDE5-Plasma Light Windows Workstation",
+            }
+        self.WEBMIN = {"no": "nein", "webmin_installed": "Webmin wird installiert"}
+
+
+        self.VM_IMPORTS = {
+            "220": {"name": "Windows 11 Pro", "template": True},
+            "225": {"name": "Windows 10 Pro", "template": True},
+            "169": {"name": "Windows Server 2022 Englisch", "template": True},
+            "148": {"name": "Windows Server 2019 Englisch", "template": True},
+            "222": {"name": "Windows Server 2019 Deutsch", "template": True},
+            "127": {"name": "Rocky9 Standard", "template": True},
+            "170": {"name": "Ubuntu Server Standard 22.04", "template": True}
+            
+        }
+        self.LXC_IMPORTS = {
+            "143": {"name": "ITEAS CT Template Ubuntu 22.04 priv", "template": True },
+            "168": {"name": "ITEAS CT Template Ubuntu 22.04 unpriv", "template": True },
+            "145": {"name": "BackupPC", "template": True },
+            "123": {"name": "APP-Web-Template", "template": True },
+            #"102": {"name": "Samba Backupassist mit ADS Anbindung", "template": True },
+            #"121": {"name": "Samba Backupassist ohne ADS Anbindung", "template": True },
+        }
+        self.PUPPETS = {
+            "kein": "Nein",
+            "generic": "Generische Installation",
+            "proxmox-desktop": "Proxmox Desktop"
+        }
+
+    def start(self):
+        gui_message_box("Installer", "Welcome to ITEAS Proxmox Enterprise Installer!")
+        self.internet = check_internet()
+        self.filesystem = check_filesystem()
+        if check_systemipnet() != '':
+            self.share_clients.append(check_systemipnet())
+        self.step1()
+
+    def step1(self):
+        step1_val = gui_menu_box("Schritt 1", "Check or configure the corresponding values and then go to 'Next'.",
+                                    ["Internet", "JA" if self.internet == True else "NEIN",
+                                     "Hostname", self.hostname,
+                                     "Domain", self.domain,
+                                     "Filesystem", self.FILESYSTEMS[self.filesystem],
+                                     " ", " ",
+                                     "Machinemanufacturer", self.MACHINE_VENDORS[self.machine_vendor],
+                                     "Machinetype", self.MACHINE_TYPES[self.machine_type],
+                                     "IPMI-Configuration", "Ja" if self.ipmi_config == True else "Nein",
+                                     "Proxmox-Environment", self.ENVIRONMENTS[self.environment],
+                                     "Proxmox-License", "Keine" if self.license == "" else self.license,
+                                     "VM-Template-Import", ",".join([self.VM_IMPORTS[x]["name"] for x in self.vm_import]) if len(self.vm_import) > 0 else "Keine",
+                                     "LXC-Template-Import", ",".join([self.LXC_IMPORTS[x]["name"] for x in self.lxc_import]) if len(self.lxc_import) > 0 else "Keine",
+                                     "Import-Storage", "Keine" if self.storage_import == "" else self.storage_import,
+                                     "Share-Clients-SMB", ",".join([x for x in self.share_clients]) if len(self.share_clients) > 0 else "Alle",
+                                     "apt-Proxy", "Nein" if self.proxy == False else "Ja",
+                                     "Desktop", self.DESKTOPS[self.desktop],
+                                     "Webmin Management", self.WEBMIN[self.webmin],
+                                     "Monitoring-Agent", self.MONITORINGS[self.monitoring],
+                                     "Puppet", self.PUPPETS[self.puppet],
+                                     " ", " ",
+                                     "Next", "Continue installation"])
+
+        # Abbrechen
+        if step1_val[0] == 1 or step1_val[0] == 255:
+            exit(0)
+
+        # Eintrag wurde gewählt
+        if step1_val[1] == "Machinemanufacturer":
+            self.step1_machine_vendor()
+
+        elif step1_val[1] == "Machinetype":
+            self.step1_machine_type()
+
+        elif step1_val[1] == "Proxmox-Environment":
+            self.step1_environment()
+
+        elif step1_val[1] == "Monitoring-Agent":
+            self.step1_monitoring()
+
+        elif step1_val[1] == "Proxmox-License":
+            self.step1_license()
+
+        elif step1_val[1] == "apt-Proxy":
+            self.step1_aptproxy()
+
+        elif step1_val[1] == "Desktop":
+            self.step1_desktop()
+
+        elif step1_val[1] == "Webmin Management":
+            self.step1_webmin()
+
+        elif step1_val[1] == "VM-Template-Import":
+            self.step1_vmtemplateimport()
+
+        elif step1_val[1] == "LXC-Template-Import":
+            self.step1_lxctemplateimport()
+
+        elif step1_val[1] == "Internet":
+            check_internet()
+            self.step1()
+
+        elif step1_val[1] == "Share-Clients-SMB":
+            self.step1_shareclients()
+
+        elif step1_val[1] == "Next":
+            self.step2()
+
+        elif step1_val[1] == "Puppet":
+            self.step1_puppet()
+
+        elif step1_val[1] == "IPMI-Configuration":
+            self.step1_ipmi_main()
+
+        elif step1_val[1] == "Import-Storage":
+            self.step1_import_storage()
+
+        else:
+            self.step1()
+
+    def step1_ipmi_main(self):
+        step1_val = gui_menu_box("IPMI-Configuration", "Check or configure IPMI 'Next'.",
+                                 ["IPMI-Configuration ", "Ja" if self.ipmi_config == True else "Nein",
+                                  " ", " ",
+                                  "IP-Adresse", self.ipmi_ip,
+                                  "IP-Subnet", self.ipmi_netmask,
+                                  "Gateway", self.ipmi_gateway,
+                                  "DNS", self.ipmi_dns,
+                                  " ", " ",
+                                  "Username", self.ipmi_user,
+                                  "Password", self.ipmi_pass[0:3] + (len(self.ipmi_pass)-3)*"*",
+                                  " ", " ",
+                                  "back", "Mainmenu"])
+
+        # Abbrechen
+        if step1_val[0] == 1 or step1_val[0] == 255:
+            self.step1()
+
+        # Eintrag wurde gewählt
+        if step1_val[1] == "IPMI-Configuration ":
+            self.step1_ipmi_config()
+
+        elif step1_val[1] == "IP-Adresse":
+            self.step1_ipmi_ip()
+
+        elif step1_val[1] == "IP-Subnet":
+            self.step1_ipmi_netmask()
+
+        elif step1_val[1] == "Gateway":
+            self.step1_ipmi_gateway()
+
+        elif step1_val[1] == "DNS":
+            self.step1_ipmi_dns()
+
+        elif step1_val[1] == "Username":
+            self.step1_ipmi_user()
+
+        elif step1_val[1] == "Password":
+            self.step1_ipmi_pass()
+
+        elif step1_val[1] == "back":
+            self.step1()
+
+        else:
+            self.step1_ipmi_main()
+
+    def step1_ipmi_config(self):
+        retval = gui_yesno_box("IPMI", "Would you like to configure IPMI?")
+        if retval[0] == 0:
+            self.ipmi_config = True
+        elif retval[0] == 1:
+            self.ipmi_config = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.step1_ipmi_main()
+
+    def step1_ipmi_ip(self):
+        retval = gui_input_box("IPMI IP-address", "Enter IP-address", self.ipmi_ip)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_ip = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_netmask(self):
+        retval = gui_input_box("IPMI IP-Subnet", "Enter IP-Subnet", self.ipmi_netmask)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_netmask = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_gateway(self):
+        retval = gui_input_box("IPMI Gateway", "Enter Gateway", self.ipmi_gateway)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_gateway = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_dns(self):
+        retval = gui_input_box("IPMI DNS", "Enter DNS", self.ipmi_dns)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_dns = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_user(self):
+        retval = gui_input_box("IPMI Username", "Enter Username", self.ipmi_user)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_user = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_ipmi_pass(self):
+        retval = gui_password_box("IPMI Password", "Enter password")
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1_ipmi_main()
+            return
+
+        self.ipmi_pass = retval[1]
+        self.step1_ipmi_main()
+
+    def step1_machine_vendor(self):
+        list = []
+        for key, val in self.MACHINE_VENDORS.items():
+            list += [key, val, "ON" if self.machine_vendor == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Machinemanufacturer", "Select the appropriate machinemanufacturer", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_vendor = retval[1]
+        self.step1()
+
+    def step1_machine_type(self):
+        list = []
+        for key, val in self.MACHINE_TYPES.items():
+            list += [key, val, "ON" if self.machine_type == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Machinetype", "Select the appropriate machinetype", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.machine_type = retval[1]
+        self.step1()
+
+    def step1_environment(self):
+        list = []
+        for key, val in self.ENVIRONMENTS.items():
+            list += [key, val, "ON" if self.environment == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Proxmox-Environment", "Choose the Proxmox-Environment", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.environment = retval[1]
+        self.step1()
+
+    def step1_monitoring(self):
+        list = []
+        for key, val in self.MONITORINGS.items():
+            list += [key, val, "ON" if self.monitoring == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Monitoring-Agent", "Choose the Monitoring-Agenten", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.monitoring = retval[1]
+        self.step1()
+
+    def step1_license(self):
+        retval = gui_input_box("Schritt 1: Proxmox-License", "Enter the Proxmox Subscription Key", self.license)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.license = retval[1]
+        self.step1()
+
+    def step1_aptproxy(self):
+        retval = gui_yesno_box("Installer", "Do you like to use the iteas apt proxy?")
+        if retval[0] == 0:
+            self.proxy = True
+        elif retval[0] == 1:
+            self.proxy = False
+
+        # Abbrechen
+        if retval[0] == 255:
+            self.step1()
+            return
+
+        self.step1()
+
+    def step1_desktop(self):
+        list = []
+        for key, val in self.DESKTOPS.items():
+            list += [key, val, "ON" if self.desktop == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Proxmox-Desktop", "Select one Desktop", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.desktop = retval[1]
+        self.step1()
+
+    def step1_webmin(self):
+        list = []
+        for key, val in self.WEBMIN.items():
+            list += [key, val, "ON" if self.webmin == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Webmin Management", "Activate the Webmin installation", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.webmin = retval[1]
+        self.step1()
+
+    def step1_vmtemplateimport(self):
+        list = []
+        for key, val in self.VM_IMPORTS.items():
+            list += [key, val["name"], "ON" if key in self.vm_import else "OFF"]
+
+        retval = gui_checklist_box("Schritt 1: VM-Template-Import", "Select the VMs you want to imported", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.vm_import = []
+        for val in retval[1]:
+            self.vm_import += [val]
+
+        self.step1()
+
+    def step1_lxctemplateimport(self):
+        list = []
+        for key, val in self.LXC_IMPORTS.items():
+            list += [key, val["name"], "ON" if key in self.lxc_import else "OFF"]
+
+        retval = gui_checklist_box("Schritt 1: LXC-Template-Import", "Select the LXC containers you want to import", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.lxc_import = []
+        for val in retval[1]:
+            self.lxc_import += [val]
+
+        self.step1()
+
+    def step1_shareclients(self):
+        retval = gui_input_box("Schritt 1: Share-Clients", "Specify the clients/networks that should have access to the shares on the Proxmox host. Multiple entries must be separated by spaces.", " ".join(self.share_clients))
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.share_clients = retval[1].split(" ")
+        self.step1()
+
+    def step1_puppet(self):
+        list = []
+        for key, val in self.PUPPETS.items():
+            list += [key, val, "ON" if self.puppet == key else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Puppet", "Choose a Puppet installation type", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.puppet = retval[1]
+        self.step1()
+
+    def step1_import_storage(self):
+        list = []
+        jstorages = json.loads(run_cmd_stdout("pvesh get /storage --output-format json", argShell=True)[1])
+        for storage in jstorages:
+            list += [storage["storage"], storage["content"], "ON" if self.storage_import == storage["storage"] else "OFF"]
+
+        retval = gui_radiolist_box("Schritt 1: Import-Storage", "Choose a storage for the template import", list)
+        # Abbrechen
+        if retval[0] == 1 or retval[0] == 255:
+            self.step1()
+            return
+
+        self.storage_import = retval[1]
+        self.step1()
+
+    def step2(self):
+
+        if self.environment == "stable" and self.license == "":
+            gui_message_box("Installer", "You must specify a license when Enterprise Updates are selected!")
+            self.step1()
+            return
+
+        if self.internet == False:
+            gui_message_box("Installer", "There must be an internet connection to continue!")
+            self.step1()
+            return
+
+        if (len(self.vm_import) > 0 or len(self.lxc_import) > 0) and self.storage_import == "":
+            gui_message_box("Installer", "You must specify an import storage!")
+            self.step1()
+            return
+
+        # Set locales
+        file_replace_line("/etc/locale.gen", "# de_AT.UTF-8 UTF-8", "de_AT.UTF-8 UTF-8")
+        file_replace_line("/etc/locale.gen", "# de_DE.UTF-8 UTF-8", "de_DE.UTF-8 UTF-8")
+        run_cmd('locale-gen', argShell=True)
+
+        ############ generic configuration
+        if self.license != "":
+            retval = run_cmd_output('pvesubscription set ' + self.license)
+            if retval[0] == 255:
+                gui_message_box("Proxmox License installation", "The license could not be installed, please check your license number. Error: " + retval[2])
+                self.step1()
+                return
+
+            time.sleep(30)
+
+            # Wait maximum for 5 minutes for registration
+            maxwait = 300
+            curwait = 0
+            lictest = run_cmd_stdout('pvesubscription get', argShell=True)
+            while lictest[1].find('status: Active') == -1 and curwait < maxwait:
+                print("Activation of the Enterprise-Repos...Please wait... This process can take up to 5 minutes." + str(curwait))
+                time.sleep(10)
+                lictest = run_cmd_stdout('pvesubscription get', argShell=True)
+                curwait += 10
+
+            # Wait maximum for 5 minutes for enterprise repo access
+            curwait = 0
+            httpuser = run_cmd_stdout("pvesubscription get | grep 'key:.*' | cut -f2 -d:", argShell=True)[1].strip()
+            httppass = run_cmd_stdout("pvesubscription get | grep 'serverid:.*' | cut -f2 -d:", argShell=True)[1].strip()
+
+            repotest = requests.get('https://enterprise.proxmox.com/debian/pve', auth=(httpuser, httppass))
+            while repotest.status_code != requests.codes.ok and curwait < maxwait:
+                print("Activation of the Enterprise-Repos...Please wait... This process can take up to 5 minutes." + str(curwait))
+                time.sleep(10)
+                repotest = requests.get('https://enterprise.proxmox.com/debian/pve', auth=(httpuser, httppass))
+                curwait += 10
+
+        # Activate Proxmox Nosubscription Sources
+        if self.environment == "test":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise")
+            file_create("/etc/apt/sources.list.d/ceph.list", "# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription")
+            file_create("/etc/apt/sources.list.d/ceph-no-subscription.list", "deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription")
+        elif self.environment == "noupdate":
+            file_create("/etc/apt/sources.list.d/pve-enterprise.list", "# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise")
+            file_create("/etc/apt/sources.list.d/pve-no-subscription.list", "# deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription")
+            file_create("/etc/apt/sources.list.d/ceph.list", "# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise")
+            file_create("/etc/apt/sources.list.d/ceph-no-subscription.list", "# deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription")
+            
+
+        # If lvm-thin convert to standard file storage if backup-machine
+        if self.machine_type == "backup" and run_cmd('pvesh get /storage | grep -i local-lvm', argShell=True) == 0:
+            run_cmd('pvesh delete /storage/local-lvm')
+            run_cmd('lvremove /dev/pve/data -f')
+            run_cmd('lvcreate -Wy -l100%FREE -ndata pve')
+            run_cmd('mkfs.ext4 -m1 /dev/pve/data')
+            run_cmd('mount /dev/pve/data /var/lib/vz')
+            file_append("/etc/fstab", "/dev/pve/data /var/lib/vz ext4 defaults 0 2")
+
+        # Mount Template CIFS-Share and import VMs
+        #storage = "local"
+        #if run_cmd('pvesh get /storage | grep -i local-lvm', argShell=True) == 0:
+        #    storage = "local-lvm"
+        #
+        #if self.filesystem == "zfs":
+        #    storage = "local-zfs"
+        storage = self.storage_import
+
+        if len(self.vm_import) > 0 or len(self.lxc_import) > 0:
+            retval = gui_password_box("Samba password required", "Please enter the password for Share " + VM_TEMPLATE_CIFS_SHARE + " and Username " + VM_TEMPLATE_CIFS_USER + " enter.")
+            VM_TEMPLATE_CIFS_PASS = retval[1]
+
+            cifscnt = 1
+            run_cmd('mkdir -p /mnt/proxmox-install-import', argShell=True)
+            cifstest = run_cmd('mount -t cifs -o user=' + VM_TEMPLATE_CIFS_USER + ",password=" + VM_TEMPLATE_CIFS_PASS + " " + VM_TEMPLATE_CIFS_SHARE + ' /mnt/proxmox-install-import')
+            while cifstest != 0 and cifscnt < 3:
+                retval = gui_password_box("Passwort falsch, Samba password required", "Please enter the password for Share " + VM_TEMPLATE_CIFS_SHARE + " and Username " + VM_TEMPLATE_CIFS_USER + " enter again.")
+                VM_TEMPLATE_CIFS_PASS = retval[1]
+                cifstest = run_cmd('mount -t cifs -o user=' + VM_TEMPLATE_CIFS_USER + ",password=" + VM_TEMPLATE_CIFS_PASS + " " + VM_TEMPLATE_CIFS_SHARE + ' /mnt/proxmox-install-import')
+                if cifstest == 0:
+                    break
+                cifscnt += 1
+
+            if cifstest == 0:
+                # Import selected VMs
+                for vm_id in self.vm_import:
+                    (ret, filename) = run_cmd_stdout("ls -t /mnt/proxmox-install-import/vzdump-qemu-%s*vma.zst | head -n1" % vm_id, argShell=True)
+                    if filename != "":
+                        run_cmd("qmrestore %s %s -storage %s" % (filename.strip(), vm_id, storage))
+                        if self.VM_IMPORTS[vm_id]["template"] == True:
+                            run_cmd("qm template %s" % vm_id)
+
+                # Import selected LXCs
+                for vm_id in self.lxc_import:
+                    (ret, filename) = run_cmd_stdout("ls -t /mnt/proxmox-install-import/vzdump-lxc-%s-*.tar.zst | head -n1" % vm_id, argShell=True)
+                    if filename != "":
+                        run_cmd("pct restore %s %s -storage %s" % (vm_id, filename.strip(), storage))
+                        if self.LXC_IMPORTS[vm_id]["template"] == True:
+                            run_cmd("pct template %s" % vm_id)
+
+                run_cmd('umount /mnt/proxmox-install-import')
+            else:
+                gui_message_box("Installer", "CIFS could not be mounted (password wrong?), VMs are not imported!")
+
+            VM_TEMPLATE_CIFS_PASS = ""
+
+        # Apt-Proxy Cache
+        if self.proxy == True:
+            file_create("/etc/apt/apt.conf.d/01proxy", 'Acquire::http { Proxy "http://10.69.99.10:3142"; };')
+
+        # Installieren allgemeine Tools und Monitoring-Agent
+        file_create("/etc/apt/sources.list", "deb http://ftp.at.debian.org/debian bookworm main contrib non-free non-free-firmware")
+        run_cmd('echo "deb http://ftp.at.debian.org/debian bookworm-updates main contrib non-free non-free-firmware >> /etc/apt/sources.list')
+        run_cmd('echo "deb http://security.debian.org bookworm-security main contrib non-free non-free-firmware >> /etc/apt/sources.list')
+        
+        run_cmd('gpg -k')
+        
+        file_create("/etc/apt/sources.list.d/iteas.list", "deb [arch=amd64 signed-by=/usr/share/keyrings/iteas-keyring.gpg] http://apt.iteas.at/iteas bookworm main")
+        run_cmd('wget https://apt.iteas.at/iteas-keyring.gpg -O /usr/share/keyrings/iteas-keyring.gpg', argShell=True)
+        run_cmd('apt update')
+        run_cmd('apt dist-upgrade -y')
+        apt_install('htop unp postfix sudo zsh tmux bwm-ng pigz sysstat nload apcupsd sl gawk ca-certificates-iteas-enterprise at lsb-release lshw intel-microcode amd64-microcode')
+        run_cmd('ln -s /usr/games/sl /usr/local/bin/sl')
+        # install ifupdown2 only if "noupdate" is not selected because the default package in the Debian sources is not compatible with proxmox
+        if self.environment != "noupdate":
+            apt_install('ifupdown2')
+
+        if self.monitoring == "checkmk":
+            apt_install('xinetd check-mk-agent')
+
+        # Special general settings for ZFS
+        if self.filesystem == "zfs":
+            file_create("/etc/modprobe.d/zfs.conf", "options zfs zfs_arc_max=10737418240")
+            run_cmd('update-initramfs -u', argShell=True)
+
+        # SUDOers
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /usr/bin/rsync")
+        file_append("/etc/sudoers", "#backuppc      ALL=(ALL) NOPASSWD: /bin/tar")
+
+        # Monitoring Konfiguration
+        if self.monitoring == "checkmk":
+
+            # Check-MK-Agent Config
+            run_cmd('wget -O /tmp/mk_smart https://git.styrion.net/iteas/check_mk-smart-plugin/raw/master/agents/smart')
+            run_cmd('mv /tmp/mk_smart /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_apcupsd https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_apcupsd')
+            run_cmd('mv /tmp/mk_apcupsd /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_dmi_sysinfo https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_dmi_sysinfo')
+            run_cmd('mv /tmp/mk_dmi_sysinfo /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_inventory https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_inventory')
+            run_cmd('mv /tmp/mk_inventory /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_lmsensors https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_lmsensors')
+            run_cmd('mv /tmp/mk_lmsensors /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_logins https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_logins')
+            run_cmd('mv /tmp/mk_logins /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_nfsexports https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_nfsexports')
+            run_cmd('mv /tmp/mk_nfsexports /usr/lib/check_mk_agent/plugins/')
+            run_cmd('wget -O /tmp/mk_netstat https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/usr/lib/check_mk_agent/plugins/mk_netstat')
+            run_cmd('mv /tmp/mk_netstat /usr/lib/check_mk_agent/plugins/')
+            run_cmd('chmod +x /usr/lib/check_mk_agent/plugins/mk_*', argShell=True)
+
+        # APC
+        run_cmd('wget -O /etc/apcupsd/apcupsd.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/etc/apcupsd.conf')
+        file_replace_line("/etc/default/apcupsd", "ISCONFIGURED", "ISCONFIGURED=yes")
+        run_cmd('systemctl enable apcupsd.service')
+
+        # Nano
+        run_cmd('wget -O /tmp/nano.tar https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/config/nano.tar')
+        run_cmd('tar -xf /tmp/nano.tar -C /root')
+        run_cmd('rm /tmp/nano.tar')
+
+        # ZSH
+        run_cmd('wget -O /tmp/zshrc_root https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/config/zshrc_root')
+        run_cmd('mv /tmp/zshrc_root /root/.zshrc')
+        file_replace_line("/root/.zshrc", "iteas.local", 'export PS1="%UDomain:%u %B%F{yellow}' + self.domain + ' $PS1"', encoding='iso8859_15')
+        run_cmd('usermod -s /bin/zsh root')
+
+        # Postfix
+        file_replace_line("/etc/postfix/main.cf", "myhostname=", "myhostname=" + self.fqdn + ".monitoring.iteas.at")
+        file_replace_line("/etc/postfix/main.cf", "relayhost =", "relayhost = smtp.styrion.net")
+        run_cmd('systemctl restart postfix.service')
+
+        # SystemD
+        run_cmd('wget -O /etc/systemd/system/rc.local.shutdown.service https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown.service')
+        run_cmd('wget -O /etc/rc.local.shutdown https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/systemd/rc.local.shutdown')
+        run_cmd('systemctl enable rc.local.shutdown.service')
+        
+        # SysCTL
+        file_create("/etc/sysctl.d/iteas.conf", "fs.inotify.max_user_watches=5242880")
+        file_append("/etc/sysctl.d/iteas.conf", "fs.inotify.max_user_instances=1024")
+
+        ############ Confiuration for Backup-Server
+        if self.machine_type == "backup":
+            # NFS, Samba & ZFS
+            apt_install('samba')
+
+            #password = gui_password_verify_box("Samba Password", "Enter the password for the Samba user 'admin':", "Enter the password for the Samba user 'admin' again:")
+            password = SMB_ADMIN_PASSWD
+            run_cmd("groupadd localbackup", argShell=True)
+            run_cmd("useradd localbackup -m -g localbackup -p '%s'" % password, argShell=True)
+            run_cmd("(echo '%s'; echo '%s') | smbpasswd -a localbackup" % (password, password), argShell=True)
+            run_cmd('wget -O /etc/samba/smb.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/samba/backup_default_smb2.conf')
+
+            backup_root = ""
+            if self.filesystem == "zfs":
+                run_cmd('zfs create rpool/vollsicherung')
+                apt_install('zfs-zed')
+                file_replace_line("/etc/samba/smb.conf", "path = /var/lib/vz/vollsicherung", "\tpath = /rpool/vollsicherung")
+                backup_root = "/rpool/vollsicherung"
+            else:
+                run_cmd('mkdir /var/lib/vz/vollsicherung')
+                backup_root = "/var/lib/vz/vollsicherung"
+
+            run_cmd("chown -R localbackup:localbackup %s" % backup_root)
+
+            file_replace_line("/etc/samba/smb.conf", "workgroup = kundendomain.local", "\tworkgroup = %s" % self.domain)
+            if len(self.share_clients) > 0:
+                file_replace_line("/etc/samba/smb.conf", "hosts allow =", "\thosts allow = %s" % " ".join(self.share_clients))
+
+            run_cmd('systemctl enable smbd')
+            run_cmd('systemctl start smbd')
+
+            ############ Installation Webmin
+        if self.webmin == "webmin_installed":
+            file_create("/etc/apt/sources.list.d/webmin.list", "deb [signed-by=/usr/share/keyrings/debian-webmin-developers.gpg] https://download.webmin.com/download/newkey/repository stable contrib")
+            run_cmd("gpg --no-default-keyring --keyring /usr/share/keyrings/debian-webmin-developers.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2D223B918916F2A2", argShell=True)
+            apt_install("apt-transport-https curl git")
+            run_cmd("apt update", argShell=True)
+            apt_install("webmin")
+            file_append("/etc/webmin/config", "lang_root=de.UTF-8")
+            file_append("/etc/webmin/config", "theme_root=authentic-theme")
+            file_replace_line("/etc/webmin/config", "lang=", "lang=de.UTF-8")
+            file_append("/etc/webmin/miniserv.conf", "preroot_root=authentic-theme")
+            run_cmd('mkdir /etc/webmin/authentic-theme')
+            run_cmd('wget -O /etc/webmin/authentic-theme/favorites.json https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/webmin/favorites.json')
+            run_cmd('systemctl restart webmin')
+
+
+        ############ Configuration for HP
+        elif self.machine_vendor == "hp":
+            # HP-Tools
+            file_create("/etc/apt/sources.list.d/hp.list", "deb [arch=amd64 signed-by=/usr/share/keyrings/HP_Enterprise.gpg] http://downloads.linux.hpe.com/SDR/downloads/MCP bookworm/current non-free")
+            file_append("/etc/apt/sources.list.d/hp.list", "deb [arch=amd64 signed-by=/usr/share/keyrings/HP_Enterprise.gpg] http://downloads.linux.hpe.com/SDR/downloads/MCP/debian bookworm/current non-free")
+            run_cmd('gpg --no-default-keyring --keyring /usr/share/keyrings/HP_Enterprise.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C208ADDE26C2B797')
+            run_cmd('apt update')
+            run_cmd('apt install ssacli hponcfg -y')
+            run_cmd('ln -s /usr/sbin/ssacli /usr/sbin/hpacucli')
+
+        elif self.machine_vendor == "tk":
+            # IPMI Tools
+            apt_install('ipmitool ipmiutil ipmicfg')
+
+        # Configure IPMI
+        if self.ipmi_config:
+            # Thanks TK-Wiki: https://www.thomas-krenn.com/de/wiki/IPMI_Konfiguration_unter_Linux_mittels_ipmitool
+            run_cmd('ipmitool lan set 1 ipsrc static', argShell=True)
+            run_cmd('ipmitool lan set 1 ipaddr "%s"' % self.ipmi_ip, argShell=True)
+            run_cmd('ipmitool lan set 1 netmask "%s"' % self.ipmi_netmask, argShell=True)
+            run_cmd('ipmitool lan set 1 defgw ipaddr "%s"' % self.ipmi_gateway, argShell=True)
+            run_cmd('ipmitool user set name 2 "%s"' % self.ipmi_user, argShell=True)
+            run_cmd('ipmitool user set password 2 "%s"' % self.ipmi_pass, argShell=True)
+            run_cmd('ipmitool channel setaccess 1 2 link=on ipmi=on callin=on privilege=4', argShell=True)
+            run_cmd('ipmitool user enable 2', argShell=True)
+
+        # Install puppet
+        if self.puppet == "generic":
+            run_cmd('wget -O /tmp/install_puppet.sh https://git.styrion.net/iteas/iteas-tools/raw/master/puppet/proxmox_mit_puppet.sh && chmod +x /tmp/install_puppet.sh', argShell=True)
+            run_cmd('echo "\n" | /tmp/install_puppet.sh', argShell=True)
+
+        elif self.puppet == "proxmox-desktop":
+            run_cmd('wget -O /tmp/install_puppet.sh https://git.styrion.net/iteas/iteas-tools/raw/master/puppet/proxmox_mit_puppet.sh && chmod +x /tmp/install_puppet.sh', argShell=True)
+            run_cmd('echo "\n" | /tmp/install_puppet.sh', argShell=True)
+
+
+
+        # Desktop Configuration
+        if self.desktop == "plasma-light":
+            apt_install('lm-sensors curl nomachine firefox-esr firefox-esr-l10n-de virt-viewer kde-plasma-desktop qapt-deb-installer filelight khelpcenter mpv curl task-german-kde-desktop task-german hunspell-de-at hunspell-de-ch hyphen-de mythes-de-ch mythes-de git kate')
+            run_cmd('apt remove -y konqueror', argShell=True)
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('useradd iteasadm -c iteasadm -G dialout,cdrom,video,plugdev,games,sudo -m -s /bin/zsh -U -p \'$1$CvBQaSeR$0phJus.ly543oq2fKOtT40\'', argShell=True)
+
+        elif self.desktop == "plasma-light-win":
+            apt_install('lm-sensors curl nomachine firefox-esr firefox-esr-l10n-de virt-viewer kde-plasma-desktop qapt-deb-installer filelight khelpcenter mpv curl task-german-kde-desktop task-german hunspell-de-at hunspell-de-ch hyphen-de mythes-de-ch mythes-de git kate')
+            run_cmd('apt remove -y konqueror', argShell=True)
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('pveum user add user@pve', argShell=True)
+            run_cmd('echo "123123\n123123" | pveum passwd user@pve', argShell=True)
+            run_cmd('useradd user -c user -G dialout,cdrom,video,plugdev,games -m -s /bin/zsh -U -p \'$1$bXXXRpOf$cLs.kEex6rSD8horkJzru0\'', argShell=True)
+            run_cmd('wget -O /etc/sddm.conf https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/etc/sddm.conf-user-autologon')
+            run_cmd('cd /tmp && git clone https://gitlab+deploy-token-1:-9F-Ty1feEf-9sQy_if4@git.styrion.net/iteas/proxmox-workstation.git && rm -rf /home/user && cp -r proxmox-workstation /home/user && chown -R user:user /home/user', argShell=True)
+            run_cmd('pvesm set local -disable', argShell=True)
+
+        elif self.desktop == "plasma":
+            apt_install('lm-sensors curl nomachine firefox-esr firefox-esr-l10n-de virt-viewer kde-plasma-desktop qapt-deb-installer filelight khelpcenter mpv curl task-german-kde-desktop task-german hunspell-de-at hunspell-de-ch hyphen-de mythes-de-ch mythes-de git kde-standard plasma-desktop task-german-desktop libreoffice-l10n-de mpv speedtest-cli x2goclient filezilla mactelnet-client ksystemlog kate gtkterm sddm-theme-debian-breeze')
+            run_cmd('apt remove -y konqueror', argShell=True)
+            run_cmd('wget -O /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz https://git.styrion.net/iteas/iteas-tools/raw/master/proxmox/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz')
+            run_cmd('rm -rf /etc/skel', argShell=True)
+            run_cmd('tar -xzf /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz -C /etc', argShell=True)
+            run_cmd('mv /etc/KDE_Plasma5_Default_Profile-master /etc/skel', argShell=True)
+            run_cmd('rm /tmp/KDE_Plasma5_Default_Profile-Proxmox5.tar.gz', argShell=True)
+            run_cmd('useradd iteasadm -c iteasadm -G dialout,cdrom,video,plugdev,games,sudo -m -s /bin/zsh -U -p \'$1$CvBQaSeR$0phJus.ly543oq2fKOtT40\'', argShell=True)
+
+
+        run_cmd('apt install -f; apt autoremove --purge -y;', argShell=True)
+        if self.proxy == True:
+            run_cmd('rm /etc/apt/apt.conf.d/01proxy')
+
+        # Install Proxmox Config Backup Script
+        B_SCRIPT = """#!/bin/bash
+
+usage() { echo "Usage: $0 [-p ]" 1>&2; exit 1; }
+
+while getopts ":p:" o; do
+    case "${o}" in
+        p)
+            p=${OPTARG}
+            ;;
+        *)
+            usage
+            ;;
+    esac
+done
+shift $((OPTIND-1))
+
+B_PATH="${p:-/root/}"
+echo "Sichere Backup in $B_PATH"
+tar -cf "$B_PATH`hostname -f`-backup.tar" /etc /root
+"""
+        file_create("/usr/local/bin/backup-proxmox-config", B_SCRIPT)
+        run_cmd('chmod +x /usr/local/bin/backup-proxmox-config')
+
+        sum_txt = """-------------------------------------------------------------------------------
+ITEAS Proxmox Installationsbericht
+
+Loginmoeglichkeiten:
+  https://%s:8006 -> Weboberflaeche Virtualisierung
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  https://%s:10000 -> Weboberflaeche Webmin (NFSfreigaben, Samba, etc.)" % check_systemip(show_prefix=False)
+
+
+        sum_txt += """
+  SSH ueber CMD f.e "ssh root@%s"
+
+The following local users were created:
+  root (Administrator) SSH, Virtualisierung, Webmin
+""" % check_systemip(show_prefix=False)
+
+        if self.machine_type == "backup":
+            sum_txt += "  backup (fuer den Zugriff auf Freigaben) Samba"
+
+        sum_txt += """
+
+Das Komplette Installationslog ist auf
+  /var/log/proxmox_install.log einsehbar.
+-------------------------------------------------------------------------------
+"""
+
+        fr = open("/root/proxmox_report.txt", "w")
+        fr.write(sum_txt)
+        fr.close()
+
+        gui_text_box("/root/proxmox_report.txt")
+
+        # Installation fertig
+        retval = gui_yesno_box("Installer", "Die Installation wurde abgeschlossen! Moechten Sie den PC/Server neustarten?")
+        if retval[0] == 0:
+            pbox = gui_progress_box("PC/Server wird automatisch neugestartet...", 0)
+            for x in range(0, 5):
+                pbox.update(x*20)
+                time.sleep(1)
+
+            pbox.finish()
+            run_cmd('reboot')
+        elif retval[0] == 1:
+            gui_message_box("Installer", "Sie muessen den PC/Server manuell neustarten um die Installation abzuschliessen!")
+
+
+i = Installer()
+i.start()
+logger.close()
diff --git a/samba/backup_default_smb.conf b/samba/backup_default_smb.conf
new file mode 100644
index 0000000..592460c
--- /dev/null
+++ b/samba/backup_default_smb.conf
@@ -0,0 +1,263 @@
+#
+# Sample configuration file for the Samba suite for Debian GNU/Linux.
+#
+#
+# This is the main Samba configuration file. You should read the
+# smb.conf(5) manual page in order to understand the options listed
+# here. Samba has a huge number of configurable options most of which
+# are not shown in this example
+#
+# Some options that are often worth tuning have been included as
+# commented-out examples in this file.
+#  - When such options are commented with ";", the proposed setting
+#    differs from the default Samba behaviour
+#  - When commented with "#", the proposed setting is the default
+#    behaviour of Samba but the option is considered important
+#    enough to be mentioned here
+#
+# NOTE: Whenever you modify this file you should run the command
+# "testparm" to check that you have not made any basic syntactic
+# errors.
+
+#======================= Global Settings =======================
+
+[global]
+	os level = 20
+	usershare allow guests = yes
+	security = user
+	obey pam restrictions = yes
+	pam password change = yes
+	panic action = /usr/share/samba/panic-action %d
+	max log size = 1000
+	server role = standalone server
+	map to guest = bad user
+	log file = /var/log/samba/log.%m
+	passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
+	syslog = 0
+	passdb backend = tdbsam
+	passwd program = /usr/bin/passwd %u
+	workgroup = iteas.local
+	dns proxy = no
+	unix password sync = yes
+	ntlm auth = yes
+
+## Browsing/Identification ###
+
+# Change this to the workgroup/NT-domain name your Samba server will part of
+
+# Windows Internet Name Serving Support Section:
+# WINS Support - Tells the NMBD component of Samba to enable its WINS Server
+#   wins support = no
+
+# WINS Server - Tells the NMBD components of Samba to be a WINS Client
+# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
+
+# This will prevent nmbd to search for NetBIOS names through DNS.
+
+#### Networking ####
+
+# The specific set of interfaces / networks to bind to
+# This can be either the interface name or an IP address/netmask;
+# interface names are normally preferred
+;   interfaces = 127.0.0.0/8 eth0
+
+# Only bind to the named interfaces and/or networks; you must use the
+# 'interfaces' option above to use this.
+# It is recommended that you enable this feature if your Samba machine is
+# not protected by a firewall or is a firewall itself.  However, this
+# option cannot handle dynamic or non-broadcast interfaces correctly.
+;   bind interfaces only = yes
+
+
+
+#### Debugging/Accounting ####
+
+# This tells Samba to use a separate log file for each machine
+# that connects
+
+# Cap the size of the individual log files (in KiB).
+
+# If you want Samba to only log through syslog then set the following
+# parameter to 'yes'.
+#   syslog only = no
+
+# We want Samba to log a minimum amount of information to syslog. Everything
+# should go to /var/log/samba/log.{smbd,nmbd} instead. If you want to log
+# through syslog you should set the following parameter to something higher.
+
+# Do something sensible when Samba crashes: mail the admin a backtrace
+
+
+####### Authentication #######
+
+# Server role. Defines in which mode Samba will operate. Possible
+# values are "standalone server", "member server", "classic primary
+# domain controller", "classic backup domain controller", "active
+# directory domain controller".
+#
+# Most people will want "standalone sever" or "member server".
+# Running as "active directory domain controller" will require first
+# running "samba-tool domain provision" to wipe databases and create a
+# new domain.
+
+# If you are using encrypted passwords, Samba will need to know what
+# password database type you are using.
+
+
+# This boolean parameter controls whether Samba attempts to sync the Unix
+# password with the SMB password when the encrypted SMB password in the
+# passdb is changed.
+
+# For Unix password sync to work on a Debian GNU/Linux system, the following
+# parameters must be set (thanks to Ian Kahan < for
+# sending the correct chat script for the passwd program in Debian Sarge).
+
+# This boolean controls whether PAM will be used for password changes
+# when requested by an SMB client instead of the program listed in
+# 'passwd program'. The default is 'no'.
+
+# This option controls how unsuccessful authentication attempts are mapped
+# to anonymous connections
+
+########## Domains ###########
+
+#
+# The following settings only takes effect if 'server role = primary
+# classic domain controller', 'server role = backup domain controller'
+# or 'domain logons' is set
+#
+
+# It specifies the location of the user's
+# profile directory from the client point of view) The following
+# required a [profiles] share to be setup on the samba server (see
+# below)
+;   logon path = \\%N\profiles\%U
+# Another common choice is storing the profile in the user's home directory
+# (this is Samba's default)
+#   logon path = \\%N\%U\profile
+
+# The following setting only takes effect if 'domain logons' is set
+# It specifies the location of a user's home directory (from the client
+# point of view)
+;   logon drive = H:
+#   logon home = \\%N\%U
+
+# The following setting only takes effect if 'domain logons' is set
+# It specifies the script to run during logon. The script must be stored
+# in the [netlogon] share
+# NOTE: Must be store in 'DOS' file format convention
+;   logon script = logon.cmd
+
+# This allows Unix users to be created on the domain controller via the SAMR
+# RPC pipe.  The example command creates a user account with a disabled Unix
+# password; please adapt to your needs
+; add user script = /usr/sbin/adduser --quiet --disabled-password --gecos "" %u
+
+# This allows machine accounts to be created on the domain controller via the
+# SAMR RPC pipe.
+# The following assumes a "machines" group exists on the system
+; add machine script  = /usr/sbin/useradd -g machines -c "%u machine account" -d /var/lib/samba -s /bin/false %u
+
+# This allows Unix groups to be created on the domain controller via the SAMR
+# RPC pipe.
+; add group script = /usr/sbin/addgroup --force-badname %g
+
+############ Misc ############
+
+# Using the following line enables you to customise your configuration
+# on a per machine basis. The %m gets replaced with the netbios name
+# of the machine that is connecting
+;   include = /home/samba/etc/smb.conf.%m
+
+# Some defaults for winbind (make sure you're not using the ranges
+# for something else.)
+;   idmap uid = 10000-20000
+;   idmap gid = 10000-20000
+;   template shell = /bin/bash
+
+# Setup usershare options to enable non-root users to share folders
+# with the net usershare command.
+
+# Maximum number of usershare. 0 (default) means that usershare is disabled.
+;   usershare max shares = 100
+
+# Allow users who've been granted usershare privileges to create
+# public shares, not just authenticated ones
+
+#======================= Share Definitions =======================
+
+[homes]
+   comment = Home Directories
+   browseable = no
+
+# By default, the home directories are exported read-only. Change the
+# next parameter to 'no' if you want to be able to write to them.
+   read only = yes
+
+# File creation mask is set to 0700 for security reasons. If you want to
+# create files with group=rw permissions, set next parameter to 0775.
+   create mask = 0700
+
+# Directory creation mask is set to 0700 for security reasons. If you want to
+# create dirs. with group=rw permissions, set next parameter to 0775.
+   directory mask = 0700
+
+# By default, \\server\username shares can be connected to by anyone
+# with access to the samba server.
+# The following parameter makes sure that only "username" can connect
+# to \\server\username
+# This might need tweaking when using external authentication schemes
+   valid users = %S
+
+# Un-comment the following and create the netlogon directory for Domain Logons
+# (you need to configure Samba to act as a domain controller too.)
+;[netlogon]
+;   comment = Network Logon Service
+;   path = /home/samba/netlogon
+;   guest ok = yes
+;   read only = yes
+
+# Un-comment the following and create the profiles directory to store
+# users profiles (see the "logon path" option above)
+# (you need to configure Samba to act as a domain controller too.)
+# The path below should be writable by all users so that their
+# profile directory may be created the first time they log on
+;[profiles]
+;   comment = Users profiles
+;   path = /home/samba/profiles
+;   guest ok = no
+;   browseable = no
+;   create mask = 0600
+;   directory mask = 0700
+
+[printers]
+   comment = All Printers
+   browseable = no
+   path = /var/spool/samba
+   printable = yes
+   guest ok = no
+   read only = yes
+   create mask = 0700
+
+# Windows clients look for this share name as a source of downloadable
+# printer drivers
+[print$]
+   comment = Printer Drivers
+   path = /var/lib/samba/printers
+   browseable = yes
+   read only = yes
+   guest ok = no
+# Uncomment to allow remote administration of Windows print drivers.
+# You may need to replace 'lpadmin' with the name of the group your
+# admin users are members of.
+# Please note that you also need to set appropriate Unix permissions
+# to the drivers directory for these users to have write rights in it
+;   write list = root, @lpadmin
+
+
+[Backup]
+	comment = Backupfreigabe fĂĽr Backupassist
+	path = /var/lib/vz/Backup
+	writeable = yes
+    write list = backup
+    valid users = backup
\ No newline at end of file
diff --git a/samba/backup_default_smb2.conf b/samba/backup_default_smb2.conf
new file mode 100644
index 0000000..cac7243
--- /dev/null
+++ b/samba/backup_default_smb2.conf
@@ -0,0 +1,27 @@
+[global]
+        os level = 20
+        usershare allow guests = yes
+        security = user
+        obey pam restrictions = yes
+        pam password change = yes
+        panic action = /usr/share/samba/panic-action %d
+        max log size = 1000
+        server role = standalone server
+        map to guest = bad user
+        log file = /var/log/samba/log.%m
+        passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
+        passdb backend = tdbsam
+        passwd program = /usr/bin/passwd %u
+        workgroup = kundendomain.local
+        dns proxy = no
+        unix password sync = yes
+        ntlm auth = yes
+        #hosts allow = 10.70.10.9 10.70.10.19 10.70.10.29
+
+[vollsicherung]
+        comment = Backupfreigabe fĂĽr Proxmox virtuelle Maschinen
+        path = /var/lib/vz/vollsicherung
+        writeable = yes
+        write list = localbackup
+        valid users = localbackup
+        #allow hosts = 10.100.99.9, 10.100.99.8, 10.100.99.10
diff --git a/systemd/kexec-pve.service b/systemd/kexec-pve.service
new file mode 100644
index 0000000..ff56bf9
--- /dev/null
+++ b/systemd/kexec-pve.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=boot into into the current pve kernel
+Documentation=man:kexec(8)
+DefaultDependencies=no
+Before=shutdown.target umount.target final.target
+
+[Service]
+Type=oneshot
+ExecStart=/sbin/kexec -l /boot/pve/vmlinuz --initrd=/boot/pve/initrd.img --reuse-cmdline
+
+[Install]
+WantedBy=kexec.target
\ No newline at end of file
diff --git a/systemd/rc.local.shutdown b/systemd/rc.local.shutdown
new file mode 100644
index 0000000..236ce8d
--- /dev/null
+++ b/systemd/rc.local.shutdown
@@ -0,0 +1,9 @@
+#!/bin/sh -e
+echo "NFS Laufwerke werden ausgehängt"
+#fusermount -uz /mnt/pve/*
+for dir in /mnt/pve/*
+do
+    dir=${dir%*/}
+    fusermount -uz "/mnt/pve/${dir##*/}"
+done
+exit 0
\ No newline at end of file
diff --git a/systemd/rc.local.shutdown.service b/systemd/rc.local.shutdown.service
new file mode 100644
index 0000000..bc7483b
--- /dev/null
+++ b/systemd/rc.local.shutdown.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=/etc/rc.local.shutdown Compatibility
+Before=shutdown.target
+
+[Service]
+ExecStart=/bin/true
+ExecStop=/etc/rc.local.shutdown
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/usr/lib/check_mk_agent/plugins/mk_apcupsd b/usr/lib/check_mk_agent/plugins/mk_apcupsd
new file mode 100755
index 0000000..9237d30
--- /dev/null
+++ b/usr/lib/check_mk_agent/plugins/mk_apcupsd
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if ! command -v apcacces > /dev/null 2>&1
+then
+echo '<<>>'
+apcaccess status | sed 's/://'
+fi
+
diff --git a/usr/lib/check_mk_agent/plugins/mk_dmi_sysinfo b/usr/lib/check_mk_agent/plugins/mk_dmi_sysinfo
new file mode 100755
index 0000000..8b9f05f
--- /dev/null
+++ b/usr/lib/check_mk_agent/plugins/mk_dmi_sysinfo
@@ -0,0 +1,7 @@
+#/bin/sh
+
+if which dmidecode >/dev/null 2>&1; then
+    echo "<<>>"
+    dmidecode -t 1 -q
+fi
+
diff --git a/usr/lib/check_mk_agent/plugins/mk_inventory b/usr/lib/check_mk_agent/plugins/mk_inventory
new file mode 100755
index 0000000..3b8fd92
--- /dev/null
+++ b/usr/lib/check_mk_agent/plugins/mk_inventory
@@ -0,0 +1,93 @@
+#!/bin/bash
+# +------------------------------------------------------------------+
+# |             ____ _               _        __  __ _  __           |
+# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
+# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
+# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
+# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
+# |                                                                  |
+# | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
+# +------------------------------------------------------------------+
+#
+# This file is part of Check_MK.
+# The official homepage is at http://mathias-kettner.de/check_mk.
+#
+# check_mk is free software;  you can redistribute it and/or modify it
+# under the  terms of the  GNU General Public License  as published by
+# the Free Software Foundation in version 2.  check_mk is  distributed
+# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
+# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
+# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
+# tails. You should have  received  a copy of the  GNU  General Public
+# License along with GNU Make; see the file  COPYING.  If  not,  write
+# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
+# Boston, MA 02110-1301 USA.
+
+# Run and *send* only once every __ seconds
+. $MK_CONFDIR/mk_inventory.cfg 2>/dev/null || true
+
+# Default to four hours
+INTERVAL=${INVENTORY_INTERVAL:-14400}
+
+FLAGFILE=$MK_VARDIR/mk_inventory.last.$REMOTE
+LAST_RUN=$(stat -c %Y $FLAGFILE)
+NOW=$(date +%s)
+UNTIL=$((NOW + INTERVAL + 600))
+
+if [ $(( NOW - LAST_RUN )) -ge $INTERVAL ]
+then
+    touch $FLAGFILE
+
+    # List of DEB packages
+    if type dpkg-query >/dev/null; then
+        echo "<<>>"
+        dpkg-query --show --showformat='${Package}|${Version}|${Architecture}|deb|${Summary}|${Status}\n'
+    fi
+
+    # List of RPM packages in same format
+    if type rpm >/dev/null; then
+        echo "<<>>"
+        rpm -qa --qf '%{NAME}\t%{VERSION}\t%{ARCH}\trpm\t%{SUMMARY}\t-\n'
+    fi
+
+    # Information about distribution
+    echo "<<>>"
+    for f in {/etc/{debian_version,lsb-release,redhat-release,SuSE-release},/usr/share/cma/version} ; do
+        if [ -e $f ] ; then
+            echo -n "$f|" ; tr \\n \| < $f | sed 's/|$//' ; echo
+        fi
+    done
+
+    # CPU Information. We need just the first one
+    if [ -e /proc/cpuinfo ] ; then
+        echo "<<>>"
+        sed 's/[[:space:]]*:[[:space:]]*/:/' < /proc/cpuinfo
+    fi
+
+    # Information about main board, memory, etc.
+    if type dmidecode >/dev/null ; then
+        echo "<<>>"
+        dmidecode -q | sed 's/\t/:/g'
+    fi
+
+    # Information about kernel architecture
+    if type uname >/dev/null ; then
+        echo "<<>>"
+        uname -m
+        uname -r
+    fi
+    if type lspci > /dev/null ; then
+        echo "<<>>"
+        lspci  -v -s  $(lspci | grep VGA | cut -d" " -f 1)
+    fi
+
+    # Some networking information
+    if type ip ; then
+        echo "<<>>"
+        ip a
+        echo "<<>>"
+        ip r
+    fi
+
+fi
+
diff --git a/usr/lib/check_mk_agent/plugins/mk_lmsensors b/usr/lib/check_mk_agent/plugins/mk_lmsensors
new file mode 100755
index 0000000..9d9d34f
--- /dev/null
+++ b/usr/lib/check_mk_agent/plugins/mk_lmsensors
@@ -0,0 +1,13 @@
+#!/bin/sh
+echo '<<>>'
+
+# lmsensors output:
+# in0:         +1.56 V  (min =  +0.00 V, max =  +3.32 V)   
+# agent output style:
+# in0 +1.56 V  min   +0.00 V max   +3.32 V
+
+if [ -x /usr/bin/sensors ]; then
+        # Perl here to get rid of the spaces in the part before ':', then drop some characters that are in the way.
+        /usr/bin/sensors -A | perl -pane 'if (m/^\s*([^:]+)\s*:\s*(.+?)?\s*$/){$k=$1;$v=$2;$k=~s/\s/_/g;$k=~s/[^a-z0-9_\-\.]//ig;$v=~s/[\(\),=]//g;$_=$k." ".$v.$/;}'
+fi
+
diff --git a/usr/lib/check_mk_agent/plugins/mk_logins b/usr/lib/check_mk_agent/plugins/mk_logins
new file mode 100755
index 0000000..c5644bb
--- /dev/null
+++ b/usr/lib/check_mk_agent/plugins/mk_logins
@@ -0,0 +1,30 @@
+#!/bin/bash
+# +------------------------------------------------------------------+
+# |             ____ _               _        __  __ _  __           |
+# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
+# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
+# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
+# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
+# |                                                                  |
+# | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
+# +------------------------------------------------------------------+
+#
+# This file is part of Check_MK.
+# The official homepage is at http://mathias-kettner.de/check_mk.
+#
+# check_mk is free software;  you can redistribute it and/or modify it
+# under the  terms of the  GNU General Public License  as published by
+# the Free Software Foundation in version 2.  check_mk is  distributed
+# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
+# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
+# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
+# tails. You should have  received  a copy of the  GNU  General Public
+# License along with GNU Make; see the file  COPYING.  If  not,  write
+# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
+# Boston, MA 02110-1301 USA.
+
+if type who >/dev/null; then
+    echo "<<>>"
+    who | wc -l
+fi
+
diff --git a/usr/lib/check_mk_agent/plugins/mk_netstat b/usr/lib/check_mk_agent/plugins/mk_netstat
new file mode 100755
index 0000000..b5f9559
--- /dev/null
+++ b/usr/lib/check_mk_agent/plugins/mk_netstat
@@ -0,0 +1,32 @@
+#!/bin/sh
+# +------------------------------------------------------------------+
+# |             ____ _               _        __  __ _  __           |
+# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
+# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
+# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
+# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
+# |                                                                  |
+# | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
+# +------------------------------------------------------------------+
+#
+# This file is part of Check_MK.
+# The official homepage is at http://mathias-kettner.de/check_mk.
+#
+# check_mk is free software;  you can redistribute it and/or modify it
+# under the  terms of the  GNU General Public License  as published by
+# the Free Software Foundation in version 2.  check_mk is  distributed
+# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
+# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
+# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
+# tails. You should have  received  a copy of the  GNU  General Public
+# License along with GNU Make; see the file  COPYING.  If  not,  write
+# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
+# Boston, MA 02110-1301 USA.
+
+# This is not part of the standard agent since it can take very
+# long to run if your TCP/UDP table is large. Netstat seems to
+# have an execution time complexity of at least O(n^2) on Linux.
+
+echo '<<>>'
+netstat -ntua  |  egrep '^(tcp|udp)' | sed -e 's/LISTEN/LISTENING/g'
+
diff --git a/usr/lib/check_mk_agent/plugins/mk_nfsexports b/usr/lib/check_mk_agent/plugins/mk_nfsexports
new file mode 100755
index 0000000..685b81f
--- /dev/null
+++ b/usr/lib/check_mk_agent/plugins/mk_nfsexports
@@ -0,0 +1,38 @@
+#!/bin/bash
+# +------------------------------------------------------------------+
+# |             ____ _               _        __  __ _  __           |
+# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
+# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
+# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
+# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
+# |                                                                  |
+# | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
+# +------------------------------------------------------------------+
+#
+# This file is part of Check_MK.
+# The official homepage is at http://mathias-kettner.de/check_mk.
+#
+# check_mk is free software;  you can redistribute it and/or modify it
+# under the  terms of the  GNU General Public License  as published by
+# the Free Software Foundation in version 2.  check_mk is  distributed
+# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
+# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
+# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
+# tails. You should have  received  a copy of the  GNU  General Public
+# License along with GNU Make; see the file  COPYING.  If  not,  write
+# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
+# Boston, MA 02110-1301 USA.
+
+# this check will only run if we have a working nfs environment or SHOULD have one.
+# not tested for nfs3
+
+# verify if there are exports defined in your local /etc/exports
+if [ -r /etc/exports ]; then
+    EXPORTS=$(grep -v -e ^# -e ^$ /etc/exports)
+fi
+
+if [ "$EXPORTS" ] && pgrep '(portmap|rpcbind)' >/dev/null && pgrep rpc.mountd >/dev/null
+then
+    echo "<<>>"
+    waitmax 3 showmount --no-headers -e
+fi
diff --git a/usr/local/bin/mount_drive.py b/usr/local/bin/mount_drive.py
new file mode 100755
index 0000000..cb6c9a8
--- /dev/null
+++ b/usr/local/bin/mount_drive.py
@@ -0,0 +1,21 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+import sys
+import subprocess
+import configparser
+
+config = configparser.ConfigParser()
+config.read('/etc/pve-usb-automount/main.conf')
+
+MAX_FILES = config.get("MAIN", "MAX_FILES", fallback=3)
+
+dev = sys.argv[1]
+devs = dev.split("/")
+devname = devs[len(devs)-1]
+
+mountpoint = sys.argv[2]
+mountnames = mountpoint.split("/")
+mountname = mountnames[len(mountnames)-1]
+
+subprocess.Popen("pvesm add dir 'usb-%s' -path '%s' -maxfiles %s -content vztmpl,iso,backup -is_mountpoint 1" % (devname, mountpoint, MAX_FILES), stdout=subprocess.PIPE, shell=True)
diff --git a/usr/local/bin/speicherpig b/usr/local/bin/speicherpig
new file mode 100755
index 0000000..7900eb3
--- /dev/null
+++ b/usr/local/bin/speicherpig
@@ -0,0 +1,122 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Getopt::Long;
+use Pod::Usage;
+use constant DEFTYPE => 'size';
+
+# pod/help {{{
+=head1 NAME
+
+speicherpig - sum up process memory usage based on process names
+
+=head1 SYNOPSIS
+
+speicherpig [--count] [--help] [--byname] [--reverse] [type]
+
+=head1 OPTIONS
+
+    --count     Show count of summed up processes
+    --help      Show help and exit
+    --byname    Order output by process names, not by sums
+    --reverse   Reverse order
+                                                                                                                                            
+    type        Type of memory usage (passed to ps) to get                                                                                  
+                process memory info.  Will use 'size' by                                                                                    
+                default.  You may try 'rss'. Use 'vsize' to                                                                                 
+                include swap information.                                                                                                   
+                                                                                                                                            
+                Speicherpig expects size outputs in KiB.                                                                                    
+                                                                                                                                            
+=head1 AUTHOR                                                                                                                               
+                                                                                                                                            
+Written by Christoph 'Mehdorn' Weber                                                                                                        
+
+=head1 REPORTING BUGS
+
+Report bugs to 
+
+=head1 COPYRIGHT
+
+Copyright 2010 Christoph 'Mehdorn' Weber.  License Creative Commons
+Attribution-Share Alike 3.0 Germany
+.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY.
+
+=head1 TRIVIA
+
+Speicherpig, speicherpig, does whatever a speicherpig does
+
+=head1 SEE ALSO
+
+ps(1), proc(5)
+
+=cut
+# }}}
+
+sub pretty_print {
+    my ($kbytes) = @_;
+
+    return sprintf "%7.2f GiB", $kbytes/1024/1024 if $kbytes > 1024*1024;
+    return sprintf "%7.2f MiB", $kbytes/1024      if $kbytes > 1024;
+    return sprintf "%7.2f KiB", $kbytes;
+}
+
+# option/parameter handling {{{
+# get options
+my $help       = 0;
+my $order_name = 0;
+my $reverse    = 0;
+my $with_count = 0;
+GetOptions(
+    'byname'  => \$order_name,
+    'count'   => \$with_count,
+    'help'    => \$help,
+    'reverse' => \$reverse,
+) or pod2usage(-exitval => 1);
+pod2usage(-exitval => 0, -verbose => 2) if $help;
+
+# get the only supported parameter
+my ($type) = @ARGV;
+$type = 'rss' unless $type;
+# }}}
+
+# get process list from ps {{{
+open(my $ps, 'ps --no-headers -eo '. $type .',comm |') or
+    die 'Cannot run ps: ', $!;
+my @proclist = <$ps>;
+close($ps) or die 'Cannot close ps: ', $!;
+chomp @proclist;
+# }}}
+
+# sum up information {{{
+my %procsums;
+my %proccounts;
+foreach my $line (@proclist) {
+    my ($size, $name) = $line =~ m{^ *(\d+) (.*)$}og;
+    $procsums{$name} += $size;
+    $proccounts{$name}++ if $with_count;
+}
+# }}}
+
+# sort output {{{
+my @key_order;
+if ($order_name) {
+    @key_order = sort keys %procsums;
+} else {
+    @key_order = sort { $procsums{$a} <=> $procsums{$b} } sort keys %procsums;
+}
+@key_order = reverse @key_order if $reverse;
+# }}}
+
+# show output {{{
+foreach my $name (@key_order) {
+    # don't show empty sets
+    next unless $procsums{$name};
+
+    printf "%16s: %s\n",
+        pretty_print($procsums{$name}),
+        $with_count ? $name .' ('. $proccounts{$name} .')' : $name
+}
diff --git a/usr/local/bin/umount_drive.py b/usr/local/bin/umount_drive.py
new file mode 100755
index 0000000..fb52523
--- /dev/null
+++ b/usr/local/bin/umount_drive.py
@@ -0,0 +1,11 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+import sys
+import subprocess
+
+mountpoint = sys.argv[1]
+mountnames = mountpoint.split("/")
+mountname = mountnames[len(mountnames)-1]
+
+subprocess.Popen("pvesm remove 'usb-%s'" % (mountname), stdout=subprocess.PIPE, shell=True)
\ No newline at end of file
diff --git a/webmin/favorites.json b/webmin/favorites.json
new file mode 100644
index 0000000..7a838d0
--- /dev/null
+++ b/webmin/favorites.json
@@ -0,0 +1,37 @@
+{"favorites":[
+    {
+        "link": "/init/",
+        "title": "System/System-Start und -Stop: System-Start- und Stop-Dienste",
+        "icon": "webmin"
+    },
+    {
+        "link": "/cron/",
+        "title": "System/Geplante Aufträge (Cron): Geplante Cron-Aufträge",
+        "icon": "webmin"
+    },
+    {
+        "link": "/at/",
+        "title": "System/Geplante Aufträge (AT): Geplante AT-Befehle",
+        "icon": "webmin"
+    },
+    {
+        "link": "/useradmin/",
+        "title": "System/Benutzer und Gruppen: Benutzer und Gruppen",
+        "icon": "webmin"
+    },
+    {
+        "link": "/samba/",
+        "title": "Server/Samba - SMB/CIFS-Fileserver: Samba Freigabeverwaltung",
+        "icon": "webmin"
+    },
+    {
+        "link": "/filemin/index.cgi?path=",
+        "title": "Sonstiges/File Manager: Filemin [/]",
+        "icon": "webmin"
+    },
+    {
+        "link": "/exports/",
+        "title": "Netzwerk/NFS-Exporte: NFS-Exporte",
+        "icon": "webmin"
+    }
+]}
\ No newline at end of file