Записки программиста, обо всем и ни о чем. Но, наверное, больше профессионального.

2011-11-03

Орешек

Орех, это который NUT.
Пришлось мне на днях конфигурить бережное выключение станции, снабженной ИБП. На компе, понятное дело :) установлен Debian Squeeze, UPS я взял от Powercom, модель Smart King Pro 700 (сразу скажу — неудачно закупился, дефектный упс оказался, что-то с егойным контроллером. Если посмотреть на цену девайса и сравнить с ценой приличных моделей аналогичной функциональности, удивляться не приходится).

Проблема была сформулирована так: если пропадает питание, станция должна аккуратно гасить виртмашины, крутящиеся на ней с помощью VirtualBox.

Итого, при исчезновении питания, задача упс-ного софта — заслать команду выключения станции и подождать, пока все процессы аккуратно завершатся. Задача скриптов выключения — сделать виртмашинам savestate (аналог гибернации) в нужное время. Получается куча скриптов и конфигов.

Что самое сложное в процессе отладки скриптов выключения компа? Самое сложное, это пережить задротство с выключением-включением системы каждый раз, как вызывается проверка. Я это пережил, систему вроде отладил, сохраняю результат (как советовал добрый человек — лучший бекап, это выложить файл в Интернет, пусть его люди сами раскопируют :). Чуть не забыл, в моем конфиге используется концепция «пропало питание и не поднялось через 2 секунды — гаси машину». Обычно используется концепция «пропало питание — тяни на батареях пока они не высохнут, потом быстренько гаси машину».

Поехали.

Конспект выданных с консоли команд (все от рута, ясен пончик) при настройке системы:
# создание и включение скрипта гашения виртмашин:
nano /etc/default/virtualbox
nano /etc/init.d/rc.vbox

chmod 755 /etc/init.d/rc.vbox
update-rc.d rc.vbox remove
update-rc.d rc.vbox defaults

# установка софта для UPS:
aptitude install nut
aptitude install sysv-rc-conf

# редактирование конфигов UPS:
nano /etc/default/nut
nano /etc/nut/nut.conf
nano /etc/nut/ups.conf
nano /etc/nut/upsd.conf
nano /etc/nut/upsd.users
nano /etc/nut/upsmon.conf
nano /etc/nut/upssched.conf
nano /root/upssched-cmd

# размещение скрипта, вызываемого при переходе на батареи:
chmod +x /root/upssched-cmd
chown nut:nut /root/upssched-cmd
mv /root/upssched-cmd /sbin/

# доп.телодвижения, необходимые для работы конфига:
mkdir /var/run/nut/upssched
chown -R nut:nut /var/run/nut
touch /var/log/test.log

# запуск, проверка и прочее:
/etc/init.d/nut start
sysv-rc-conf

upsdrvctl start
upsc pcmskp
upsd
upsd -c reload
upscmd -l
upscmd -l pcmskp

После (вернее, в процессе) конфигурирования мне понадобилось пару раз перезапустить машину, чтобы софт правильно прихватил порт USB с упсом.

Теперь содержимое вышеуказанных скриптов и конфигов. Из текста выброшены почти все каменты (копирайты оставил):

cat /etc/default/virtualbox
# юзер, под которым работают виртмашины (он их запускает)
SHUTDOWN_USERS="valik"
# что делать с виртмашинами
SHUTDOWN=savestate


cat /etc/init.d/rc.vbox
#!/bin/sh
### BEGIN INIT INFO
# Provides:          vboxcontrol
# Required-Start:    vboxdrv $network $local_fs
# Required-Stop:     ssh $network $local_fs
# Should-Start:      samba
# Should-Stop:       samba
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Description:       VirtualBox VM Control
### END INIT INFO
# ко мне скрипт пришел чере «испорченный телефон», да и я его местами подкрутил,
# alas.
# This version is Vbox4, v1.0 by David Fuchs Based on:
# Version 20090301 by Kevin Swanson based on:
# Version 2008051100 by Jochem Kossen
# http://farfewertoes.com
#
# Released in the public domain
#
# This file came with a README file containing the instructions on how
# to use this script.
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
DEVICE=/dev/vboxdrv
LOG="/var/log/vbox-install.log"
NOLSB=
DEBIAN=yes
MODPROBE=/sbin/modprobe

if $MODPROBE -c | grep -q '^allow_unsupported_modules  *0'; then
  MODPROBE="$MODPROBE --allow-unsupported-modules"
fi

[ -f /lib/lsb/init-functions ] || NOLSB=yes
[ -f /etc/vbox/vbox.cfg ] && . /etc/vbox/vbox.cfg

if [ -n "$INSTALL_DIR" ]; then
    VBOXMANAGE="$INSTALL_DIR/VBoxManage"
    DODKMS="$INSTALL_DIR/src/vboxhost/do_dkms"
    BUILDVBOXDRV="$INSTALL_DIR/src/vboxhost/vboxdrv/build_in_tmp"
    BUILDVBOXNETFLT="$INSTALL_DIR/src/vboxhost/vboxnetflt/build_in_tmp"
    BUILDVBOXNETADP="$INSTALL_DIR/src/vboxhost/vboxnetadp/build_in_tmp"
else
    VBOXMANAGE="/usr/lib/virtualbox/VBoxManage"
    DODKMS="/usr/share/virtualbox/src/vboxhost/do_dkms"
    BUILDVBOXDRV="/usr/share/virtualbox/src/vboxhost/vboxdrv/build_in_tmp"
    BUILDVBOXNETFLT="/usr/share/virtualbox/src/vboxhost/vboxnetflt/build_in_tmp"
    BUILDVBOXNETADP="/usr/share/virtualbox/src/vboxhost/vboxnetadp/build_in_tmp"
fi

[ -z "$DEBIAN" -o -x $VBOXMANAGE -a -x $BUILDVBOXDRV ] || exit 0

if [ -n "$NOLSB" ]; then
    if [ -f /etc/redhat-release ]; then
        system=redhat
    elif [ -f /etc/SuSE-release ]; then
        system=suse
    elif [ -f /etc/gentoo-release ]; then
        system=gentoo
    fi
fi

[ -r /etc/default/virtualbox ] && . /etc/default/virtualbox

if [ -z "$NOLSB" ]; then
    . /lib/lsb/init-functions
    fail_msg() {
        echo ""
        log_failure_msg "$1"
    }
    succ_msg() {
        log_end_msg 0
    }
    begin_msg() {
        log_daemon_msg "$@"
    }
else
    if [ "$system" = "redhat" ]; then
        . /etc/init.d/functions
        fail_msg() {
            echo -n " "
            echo_failure
            echo
            echo "  ($1)"
        }
        succ_msg() {
            echo -n " "
            echo_success
            echo
        }
    elif [ "$system" = "suse" ]; then
        . /etc/rc.status
        fail_msg() {
            rc_failed 1
            rc_status -v
            echo "  ($1)"
        }
        succ_msg() {
            rc_reset
            rc_status -v
        }
    elif [ "$system" = "gentoo" ]; then
        if [ -f /sbin/functions.sh ]; then
            . /sbin/functions.sh
        elif [ -f /etc/init.d/functions.sh ]; then
            . /etc/init.d/functions.sh
        fi
        fail_msg() {
            eerror "$1"
        }
        succ_msg() {
            eend "$?"
        }
        begin_msg() {
            ebegin "$1"
        }
        if [ "`which $0`" = "/sbin/rc" ]; then
            shift
        fi
    else
        fail_msg() {
            echo " ...failed!"
            echo "  ($1)"
        }
        succ_msg() {
            echo " ...done."
        }
    fi
    if [ "$system" != "gentoo" ]; then
        begin_msg() {
            [ -z "${1:-}" ] && return 1
            if [ -z "${2:-}" ]; then
                echo -n "$1"
            else
                echo -n "$1: $2"
            fi
        }
    fi
fi
case "$1" in
start)
;;
stop)
    echo "Run rc.vbox stop" >> /var/log/test.log
    wait=0
    log_daemon_msg "Stopping vms..."
    for i in $SHUTDOWN_USERS; do
        # don't create the ipcd directory with wrong permissions!
        if [ -d /tmp/.vbox-$i-ipc ]; then
            export VBOX_IPC_SOCKETID="$i"
            VMS=`$VBOXMANAGE --nologo list runningvms | sed -e 's/^".*".*{\(.*\)}/\1/' 2>/dev/null`
            if [ -n "$VMS" ]; then
                if [ "$SHUTDOWN" = "poweroff" ]; then
                    begin_msg "Powering off remaining VMs"
                    for v in $VMS; do
                        $VBOXMANAGE --nologo controlvm $v poweroff
                    done
                    succ_msg
                elif [ "$SHUTDOWN" = "acpibutton" ]; then
                    begin_msg "Sending ACPI power button event to remaining VMs"
                    for v in $VMS; do
                        $VBOXMANAGE --nologo controlvm $v acpipowerbutton
                        wait=30
                    done
                    succ_msg
                elif [ "$SHUTDOWN" = "savestate" ]; then
                    begin_msg "Saving state of remaining VMs"
                    for v in $VMS; do
                        $VBOXMANAGE --nologo controlvm $v savestate
                    done
                    succ_msg
                fi
            fi
        fi
    done
    # wait for some seconds when doing ACPI shutdown
    if [ "$wait" -ne 0 ]; then
        begin_msg "Waiting for $wait seconds for VM shutdown"
        sleep $wait
        succ_msg
    fi
;;
*)
echo "Usage: $0 {stop}"
    exit 1
;;
esac
exit 0


cat /etc/default/nut
START_UPSD=yes
START_UPSMON=yes


cat /etc/nut/nut.conf
MODE=standalone


cat /etc/nut/ups.conf
[pcmskp]
    driver = usbhid-ups
    port = auto
    desc = "sqz on powercom smart king pro 700"


cat /etc/nut/upsd.conf
LISTEN 127.0.0.1
LISTEN ::1


cat /etc/nut/upsd.users
[local_mon]
    password = 12345678
    actions = SET
    instcmds = ALL
    upsmon master


cat /etc/nut/upsmon.conf
MONITOR pcmskp@localhost 1 local_mon 12345678 master
# RUN_AS_USER nutmon
# говорят, это ужасная дыра в безопасности
RUN_AS_USER root
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
NOTIFYCMD /sbin/upssched
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower
NOTIFYMSG ONLINE "UPS %s on line power"
NOTIFYMSG ONBATT "UPS %s on battery"
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5


cat /etc/nut/upssched.conf
CMDSCRIPT /sbin/upssched-cmd
PIPEFN /var/run/nut/upssched/upssched.pipe
LOCKFN /var/run/nut/upssched/upssched.lock
AT ONBATT * START-TIMER nopower 2
AT ONLINE * CANCEL-TIMER nopower


cat /sbin/upssched-cmd
#!/bin/bash
# nopower timer from /etc/nut/upssched.conf
# я почикал оригинальный скрипт, надеюсь, Paul не в претензии.
##
#   upssched-cmd: Notification script for use with Network UPS tools (NUT)
#   1.0
#
#   Copyright (C) 2005  Paul J. Lucas
#
#   This program 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; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
MAIL=/usr/bin/mail
EMAIL=root
[ -z "$PAGER" ] && PAGER=$EMAIL
notify() {
    echo $2 | $MAIL -s "$3" $1
    echo $2 >> /var/log/test.log
    echo $2 | wall
}
case $1 in
nopower)
 notify $PAGER $1 "UPS on battery now, timer nopower done"
 shutdown -h +0 powerevent
 /sbin/upsmon -c fsd ;;
COMMBAD)    notify $PAGER $1 "UPS communications lost" ;;
COMMOK)     notify $PAGER $1 "UPS communications established" ;;
FSD)        notify $EMAIL $1 "UPS being shut down by master" ;;
LOWBATT)    notify $EMAIL $1 "UPS has a low battery" ;;
NOCOMM)     notify $PAGER $1 "UPS unavailable" ;;
ONBATT)     notify $PAGER $1 "UPS on battery power" ;;
ONLINE)     notify $PAGER $1 "UPS on line power" ;;
REPLBATT)   notify $EMAIL $1 "UPS battery needs replacement" ;;
SHUTDOWN)   notify $EMAIL $1 "NUT shutting system down" ;;
esac

Вот так. У меня работает.

Некоторые использованные источники:
networkupstools.org/documentation
networkupstools.org/stable-hcl — проверьте перед покупкой ИБП!
blasterspike.it/2011/03/28/how-to-install-nut-on-ubuntu-10-10-maverick-meerkat
blog.shadypixel.com/monitoring-a-ups-with-nut-on-debian-or-ubuntu-linux/#comment-1549
smilecouple.org/2011/05/27/install-virtual-box-4-on-ubuntu-with-phpvirtualbox4
code.google.com/p/phpvirtualbox/wiki/vboxwebServiceConfigLinux
rogerprice.org/NUT.html#UPSSCHED-CMD
homepage.mac.com/pauljlucas/personal/macmini/ups

Напоследок посоветую посвятить выбору производителя и модели UPS не менее пары часов времени. Сэкономите время же и деньги. Понравившуюся модель проверяйте на совместимость с софтом и количество параметров под управлением софта. Как я заметил, народ рекомендует MGE. А я денег пожалел на упс. oops :(

2 комментария:

  1. В Debian Wheezy столкнулся с проблемой - не выключается хост и syslog содержит сообщение типа
    "upssched Failed to connect to parent and failed to create parent: No such file or directory"
    Как выяснилось, папка
    /var/run/nut/upssched, указанная в конфиге
    /etc/nut/upssched.conf
    все время куда-то пропадает.
    Решение проблемы: в конфиге указать папку
    /var/run/nut
    вместо
    /var/run/nut/upssched
    Тогда все работает как надо.

    ОтветитьУдалить
  2. Хозяйке на заметку.
    Есть в ГитХабе проект
    https://github.com/bkidwell/vbox-service-template
    в котором приведен шаблон rc скрипта для Виртуалбокса "vbox-service-template is an init.d script template for running a VirtualBox machine as a service".

    ОтветитьУдалить

Архив блога

Ярлыки

linux (241) python (191) citation (186) web-develop (170) gov.ru (159) video (124) бытовуха (115) sysadm (100) GIS (97) Zope(Plone) (88) бурчалки (84) Book (83) programming (82) грабли (77) Fun (76) development (73) windsurfing (72) Microsoft (64) hiload (62) internet provider (57) opensource (57) security (57) опыт (55) movie (52) Wisdom (51) ML (47) driving (45) hardware (45) language (45) money (42) JS (41) curse (40) bigdata (39) DBMS (38) ArcGIS (34) history (31) PDA (30) howto (30) holyday (29) Google (27) Oracle (27) tourism (27) virtbox (27) health (26) vacation (24) AI (23) Autodesk (23) SQL (23) humor (23) Java (22) knowledge (22) translate (20) CSS (19) cheatsheet (19) hack (19) Apache (16) Klaipeda (15) Manager (15) web-browser (15) Никонов (15) functional programming (14) happiness (14) music (14) todo (14) PHP (13) course (13) scala (13) weapon (13) HTTP. Apache (12) SSH (12) frameworks (12) hero (12) im (12) settings (12) HTML (11) SciTE (11) USA (11) crypto (11) game (11) map (11) HTTPD (9) ODF (9) Photo (9) купи/продай (9) benchmark (8) documentation (8) 3D (7) CS (7) DNS (7) NoSQL (7) cloud (7) django (7) gun (7) matroska (7) telephony (7) Microsoft Office (6) VCS (6) bluetooth (6) pidgin (6) proxy (6) Donald Knuth (5) ETL (5) NVIDIA (5) Palanga (5) REST (5) bash (5) flash (5) keyboard (5) price (5) samba (5) CGI (4) LISP (4) RoR (4) cache (4) car (4) display (4) holywar (4) nginx (4) pistol (4) spark (4) xml (4) Лебедев (4) IDE (3) IE8 (3) J2EE (3) NTFS (3) RDP (3) holiday (3) mount (3) Гоблин (3) кухня (3) урюк (3) AMQP (2) ERP (2) IE7 (2) NAS (2) Naudoc (2) PDF (2) address (2) air (2) british (2) coffee (2) fitness (2) font (2) ftp (2) fuckup (2) messaging (2) notify (2) sharepoint (2) ssl/tls (2) stardict (2) tests (2) tunnel (2) udev (2) APT (1) Baltic (1) CRUD (1) Canyonlands (1) Cyprus (1) DVDShrink (1) Jabber (1) K9Copy (1) Matlab (1) Portugal (1) VBA (1) WD My Book (1) autoit (1) bike (1) cannabis (1) chat (1) concurrent (1) dbf (1) ext4 (1) idioten (1) join (1) krusader (1) license (1) life (1) migration (1) mindmap (1) navitel (1) pneumatic weapon (1) quiz (1) regexp (1) robot (1) science (1) seaside (1) serialization (1) shore (1) spatial (1) tie (1) vim (1) Науру (1) крысы (1) налоги (1) пианино (1)