Newer
Older
///////////////////////////////////////////////////////////////////////////////////////////////////
// Прикладной интерфейс
Перем мНастройки;
Перем Лог;
Перем мИдентификаторКластера;
Перем ЭтоWindows;
Процедура ЗарегистрироватьКоманду(Знач ИмяКоманды, Знач Парсер) Экспорт
ОписаниеКоманды = Парсер.ОписаниеКоманды(ИмяКоманды, "Управление сеансами информационной базы");
Парсер.ДобавитьПозиционныйПараметрКоманды(ОписаниеКоманды, "Действие", "lock|unlock|kill");
Сосна Евгений
committed
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "-ras", "Сетевой адрес RAS, по умолчанию localhost:1545");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "-rac", "Команда запуска RAC, по умолчанию находим в каталоге установки 1с");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "-db", "Имя информационной базы");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-db-user",
"Пользователь информационной базы");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-db-pwd",
"Пароль пользователя информационной базы");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-cluster-admin",
"Администратор кластера");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
Сосна Евгений
committed
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-v8version",
"Маска версии платформы 1С");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-lockmessage",
"Сообщение блокировки");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-lockuccode",
"Ключ разрешения запуска");
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-lockstart",
Сосна Евгений
committed
"Время старта блокировки пользователей, время указываем как '2040-12-31T23:59:59'");
Сосна Евгений
committed
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды,
"-lockstartat",
"Время старта блокировки через n сек");
Парсер.ДобавитьКоманду(ОписаниеКоманды);
КонецПроцедуры
Функция ВыполнитьКоманду(Знач ПараметрыКоманды) Экспорт
ПрочитатьПараметры(ПараметрыКоманды);
Если Не ПараметрыВведеныКорректно() Тогда
Возврат МенеджерКомандПриложения.РезультатыКоманд().НеверныеПараметры;
КонецЕсли;
Если мНастройки.Действие = "lock" Тогда
УстановитьСтатусБлокировкиСеансов(Истина);
ИначеЕсли мНастройки.Действие = "unlock" Тогда
УстановитьСтатусБлокировкиСеансов(Ложь);
ИначеЕсли мНастройки.Действие = "kill" Тогда
УстановитьСтатусБлокировкиСеансов(Истина);
ОтключитьСуществующиеСеансы();
Иначе
Лог.Ошибка("Неизвестное действие: " + мНастройки.Действие);
Возврат МенеджерКомандПриложения.РезультатыКоманд().НеверныеПараметры;
Возврат МенеджерКомандПриложения.РезультатыКоманд().НеРеализовано;
КонецФункции
Процедура ПрочитатьПараметры(Знач ПараметрыКоманды)
мНастройки = Новый Структура;
Для Каждого КЗ Из ПараметрыКоманды Цикл
Лог.Отладка(КЗ.Ключ + " = " + КЗ.Значение);
КонецЦикла;
мНастройки.Вставить("АдресСервераАдминистрирования", ПараметрыКоманды["-ras"]);
мНастройки.Вставить("ПутьКлиентаАдминистрирования", ПараметрыКоманды["-rac"]);
мНастройки.Вставить("ИмяБазыДанных", ПараметрыКоманды["-db"]);
мНастройки.Вставить("АдминистраторИБ", ПараметрыКоманды["-db-user"]);
мНастройки.Вставить("ПарольАдминистратораИБ", ПараметрыКоманды["-db-pwd"]);
мНастройки.Вставить("АдминистраторКластера", ПараметрыКоманды["-cluster-admin"]);
мНастройки.Вставить("ПарольАдминистратораКластера", ПараметрыКоманды["-cluster-pwd"]);
Сосна Евгений
committed
мНастройки.Вставить("ИспользуемаяВерсияПлатформы", ПараметрыКоманды["-v8version"]);
мНастройки.Вставить("КлючРазрешенияЗапуска", ПараметрыКоманды["-lockuccode"]);
мНастройки.Вставить("СообщениеОблокировке", ПараметрыКоманды["-lockmessage"]);
мНастройки.Вставить("ВремяСтратаБлокировки", ПараметрыКоманды["-lockstart"]);
мНастройки.Вставить("ВремяСтратаБлокировкиЧерез", ПараметрыКоманды["-lockstartat"]);
мНастройки.Вставить("Действие", ПараметрыКоманды["Действие"]);
Сосна Евгений
committed
//Получим путь к платформе если вдруг не установленна
мНастройки.ПутьКлиентаАдминистрирования = ПолучитьПутьКRAC(мНастройки.ПутьКлиентаАдминистрирования, мНастройки.ИспользуемаяВерсияПлатформы);
Если ПустаяСтрока(мНастройки.АдресСервераАдминистрирования) Тогда
мНастройки.АдресСервераАдминистрирования = "localhost:1545";
КонецЕсли;
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
КонецПроцедуры
Функция ПараметрыВведеныКорректно()
Успех = Истина;
Если Не ЗначениеЗаполнено(мНастройки.АдресСервераАдминистрирования) Тогда
Лог.Ошибка("Не указан сервер администрирования");
Успех = Ложь;
КонецЕсли;
Если Не ЗначениеЗаполнено(мНастройки.ПутьКлиентаАдминистрирования) Тогда
Лог.Ошибка("Не указан клиент администрирования");
Успех = Ложь;
КонецЕсли;
Если Не ЗначениеЗаполнено(мНастройки.ИмяБазыДанных) Тогда
Лог.Ошибка("Не указано имя базы данных");
Успех = Ложь;
КонецЕсли;
Если Не ЗначениеЗаполнено(мНастройки.Действие) Тогда
Лог.Ошибка("Не указано действие lock/unlock");
Успех = Ложь;
КонецЕсли;
Возврат Успех;
КонецФункции
/////////////////////////////////////////////////////////////////////////////////
// Взаимодействие с кластером
Процедура УстановитьСтатусБлокировкиСеансов(Знач Блокировать)
КлючиАвторизацииВБазе = "";
Если ЗначениеЗаполнено(мНастройки.АдминистраторИБ) Тогда
КлючиАвторизацииВБазе = КлючиАвторизацииВБазе + СтрШаблон(" --infobase-user=""%1""", мНастройки.АдминистраторИБ);
КонецЕсли;
Если ЗначениеЗаполнено(мНастройки.ПарольАдминистратораИБ) Тогда
КлючиАвторизацииВБазе = КлючиАвторизацииВБазе + СтрШаблон(" --infobase-pwd=""%1""", мНастройки.ПарольАдминистратораИБ);
КонецЕсли;
Сосна Евгений
committed
ИдентификаторКластера = ИдентификаторКластера();
ИдентификаторБазы = ИдентификаторБазы();
КлючРазрешенияЗапуска = ?(ПустаяСтрока(мНастройки.КлючРазрешенияЗапуска), ИдентификаторБазы, мНастройки.КлючРазрешенияЗапуска);
ВремяБлокировки = мНастройки.ВремяСтратаБлокировки;
Если ПустаяСтрока(ВремяБлокировки) И Не ПустаяСтрока(мНастройки.ВремяСтратаБлокировкиЧерез) Тогда
Секунды = 0;
Попытка
Секунды = Число(мНастройки.ВремяСтратаБлокировкиЧерез);
Исключение
КонецПопытки;
Сосна Евгений
committed
ВремяБлокировки = Формат(ТекущаяДата()+Секунды,"ДФ='yyyy-MM-ddTHH:mm:ss'");
Сосна Евгений
committed
КонецЕсли;
КомандаВыполнения = СтрокаЗапускаКлиента() + СтрШаблон("infobase update --infobase=""%3""%4 --cluster=""%1""%2 --sessions-deny=%5 --denied-message=""%6"" --denied-from=""%8"" --permission-code=""%7""",
Сосна Евгений
committed
ИдентификаторКластера,
Сосна Евгений
committed
ИдентификаторБазы,
Сосна Евгений
committed
?(Блокировать, "on", "off"),
мНастройки.СообщениеОблокировке,
КлючРазрешенияЗапуска,
ВремяБлокировки);
ЗапуститьПроцесс(КомандаВыполнения);
Лог.Информация("Сеансы " + ?(Блокировать, "запрещены", "разрешены"));
КонецПроцедуры
Функция ИдентификаторКластера()
Если мИдентификаторКластера = Неопределено Тогда
Лог.Информация("Получаю список кластеров");
КомандаВыполнения = СтрокаЗапускаКлиента() + "cluster list";
СписокКластеров = ЗапуститьПроцесс(КомандаВыполнения);
УИДКластера = Сред(СписокКластеров,(Найти(СписокКластеров,":")+1),Найти(СписокКластеров,"host")-Найти(СписокКластеров,":")-1);
мИдентификаторКластера = СокрЛП(СтрЗаменить(УИДКластера,Символы.ПС,""));
КонецЕсли;
Если ПустаяСтрока(мИдентификаторКластера) Тогда
ВызватьИсключение "Кластер серверов отсутствует";
КонецЕсли;
Возврат мИдентификаторКластера;
КонецФункции
Функция ИдентификаторБазы()
Если мИдентификаторБазы = Неопределено Тогда
мИдентификаторБазы = НайтиБазуВКластере();
КонецЕсли;
Возврат мИдентификаторБазы;
КонецФункции
КомандаВыполнения = СтрокаЗапускаКлиента() + СтрШаблон("infobase summary list --cluster=""%1""%2",
ИдентификаторКластера(),
КлючиАвторизацииВКластере());
Лог.Информация("Получаю список баз кластера");
СписокБазВКластере = ЗапуститьПроцесс(КомандаВыполнения);
ЧислоСтрок = СтрЧислоСтрок(СписокБазВКластере);
НайденаБазаВКластере = Ложь;
Для К = 1 По ЧислоСтрок Цикл
СтрокаРазбора = СтрПолучитьСтроку(СписокБазВКластере,К);
ПозицияРазделителя = Найти(СтрокаРазбора,":");
Если Найти(СтрокаРазбора,"infobase")>0 Тогда
УИДИБ = СокрЛП(Сред(СтрокаРазбора,ПозицияРазделителя+1));
ИначеЕсли Найти(СтрокаРазбора,"name")>0 Тогда
ИмяБазы = СокрЛП(Сред(СтрокаРазбора,ПозицияРазделителя+1));
Сосна Евгений
committed
Если Нрег(ИмяБазы) = НРег(мНастройки.ИмяБазыДанных) Тогда
Сообщить("Получен УИД базы");
НайденаБазаВКластере = Истина;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не НайденаБазаВКластере Тогда
ВызватьИсключение "База "+мНастройки.ИмяБазыДанных +" не найдена в кластере";
КонецЕсли;
Возврат УИДИБ;
КонецФункции
Функция КлючиАвторизацииВКластере()
КомандаВыполнения = "";
Если ЗначениеЗаполнено(мНастройки.АдминистраторКластера) Тогда
КомандаВыполнения = КомандаВыполнения + СтрШаблон(" --cluster-user=""%1""", мНастройки.АдминистраторКластера);
КонецЕсли;
Если ЗначениеЗаполнено(мНастройки.ПарольАдминистратораКластера) Тогда
КомандаВыполнения = КомандаВыполнения + СтрШаблон(" --cluster-pwd=""%1""", мНастройки.ПарольАдминистратораКластера);
КонецЕсли;
Возврат КомандаВыполнения;
КонецФункции
Перем ПутьКлиентаАдминистрирования;
Если ЭтоWindows Тогда
ПутьКлиентаАдминистрирования = ЗапускПриложений.ОбернутьВКавычки(мНастройки.ПутьКлиентаАдминистрирования);
Иначе
ПутьКлиентаАдминистрирования = мНастройки.ПутьКлиентаАдминистрирования;
КонецЕсли;
Возврат ПутьКлиентаАдминистрирования + " " +
мНастройки.АдресСервераАдминистрирования + " ";
КонецФункции
Функция ЗапуститьПроцесс(Знач СтрокаВыполнения)
Перем ПаузаОжиданияЧтенияБуфера;
ПаузаОжиданияЧтенияБуфера = 10;
Процесс = СоздатьПроцесс(СтрокаВыполнения,,Истина);
Процесс.Запустить();
ТекстБазовый = "";
Счетчик = 0; МаксСчетчикЦикла = 100000;
Пока Истина Цикл
Текст = Процесс.ПотокВывода.Прочитать();
Лог.Отладка("Цикл ПотокаВывода "+Текст);
Если Текст = Неопределено ИЛИ ПустаяСтрока(СокрЛП(Текст)) Тогда
Прервать;
КонецЕсли;
Счетчик = Счетчик + 1;
Если Счетчик > МаксСчетчикЦикла Тогда
Прервать;
КонецЕсли;
ТекстБазовый = ТекстБазовый + Текст;
sleep(ПаузаОжиданияЧтенияБуфера); //Подождем, надеюсь буфер не переполниться.
КонецЦикла;
Процесс.ОжидатьЗавершения();
Если Процесс.КодВозврата = 0 Тогда
Текст = Процесс.ПотокВывода.Прочитать();
ТекстБазовый = ТекстБазовый + Текст;
Лог.Отладка(ТекстБазовый);
Возврат ТекстБазовый;
ВызватьИсключение "Сообщение от RAS/RAC
|" + Процесс.ПотокОшибок.Прочитать();
Процедура ОтключитьСуществующиеСеансы()
Лог.Информация("Отключаю существующие сеансы");
СеансыБазы = ПолучитьСписокСеансов();
Для Каждого Сеанс Из СеансыБазы Цикл
Сосна Евгений
committed
Попытка
ОтключитьСеанс(Сеанс);
Исключение
Лог.Ошибка(ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьСписокСеансов()
ТаблицаСеансов = Новый ТаблицаЗначений;
ТаблицаСеансов.Колонки.Добавить("Идентификатор");
ТаблицаСеансов.Колонки.Добавить("Приложение");
ТаблицаСеансов.Колонки.Добавить("Пользователь");
ТаблицаСеансов.Колонки.Добавить("НомерСеанса");
КомандаЗапуска = СтрокаЗапускаКлиента() + СтрШаблон("session list --cluster=""%1""%2 --infobase=""%3""",
ИдентификаторКластера(),
КлючиАвторизацииВКластере(),
ИдентификаторБазы());
СписокСеансовИБ = ЗапуститьПроцесс(КомандаЗапуска);
ЧислоСтрок = СтрЧислоСтрок(СписокСеансовИБ);
ТекСтрока = Неопределено;
Для К = 1 По ЧислоСтрок Цикл
СтрокаРазбора = СтрПолучитьСтроку(СписокСеансовИБ,К);
ПозицияРазделителя = Найти(СтрокаРазбора,":");
СтрокаРазбораИмя = СокрЛП(Лев(СтрокаРазбора,ПозицияРазделителя-1));
СтрокаРазбораЗначение = СокрЛП(Сред(СтрокаРазбора,ПозицияРазделителя+1));
Если СтрокаРазбораИмя = "session" Тогда
ТекСтрока = ТаблицаСеансов.Добавить();
ТекСтрока.Идентификатор = СтрокаРазбораЗначение;
ИначеЕсли СтрокаРазбораИмя = "user-name" Тогда
ТекСтрока.Пользователь = СтрокаРазбораЗначение;
ИначеЕсли СтрокаРазбораИмя = "app-id" Тогда
ТекСтрока.Приложение = СтрокаРазбораЗначение;
ИначеЕсли СтрокаРазбораИмя = "session-id" Тогда
ТекСтрока.НомерСеанса = СтрокаРазбораЗначение;
КонецЕсли;
КонецЦикла;
Возврат ТаблицаСеансов;
КонецФункции
Процедура ОтключитьСеанс(Знач Сеанс)
СтрокаВыполнения = СтрокаЗапускаКлиента() + СтрШаблон("session terminate --cluster=""%1""%2 --session=""%3""",
ИдентификаторКластера(),
КлючиАвторизацииВКластере(),
Сеанс.Идентификатор);
Лог.Информация(СтрШаблон("Отключаю сеанс: %1 [%2] (%3)", Сеанс.НомерСеанса, Сеанс.Пользователь, Сеанс.Приложение));
Сосна Евгений
committed
ЗапуститьПроцесс(СтрокаВыполнения);
Сосна Евгений
committed
Функция ПолучитьПутьКRAC(ТекущийПуть, Знач ВерсияПлатформы="")
Если НЕ ПустаяСтрока(ТекущийПуть) Тогда
ФайлУтилиты = Новый Файл(ТекущийПуть);
Если ФайлУтилиты.Существует() Тогда
Лог.Отладка("Текущая версия rac "+ФайлУтилиты.ПолноеИмя);
Возврат ФайлУтилиты.ПолноеИмя;
КонецЕсли;
КонецЕсли;
Если ПустаяСтрока(ВерсияПлатформы) Тогда
ВерсияПлатформы="8.3";
КонецЕсли;
Конфигуратор = Новый УправлениеКонфигуратором;
ПутьКПлатформе = Конфигуратор.ПолучитьПутьКВерсииПлатформы(ВерсияПлатформы);
Лог.Отладка("Используемый путь для поиска rac "+ПутьКПлатформе);
КаталогУстановки = Новый Файл(ПутьКПлатформе);
Лог.Отладка(КаталогУстановки.Путь);
Сосна Евгений
committed
ИмяФайла = ?(ЭтоWindows, "rac.exe", "rac");
ФайлУтилиты = Новый Файл(ОбъединитьПути(Строка(КаталогУстановки.Путь), ИмяФайла));
Если ФайлУтилиты.Существует() Тогда
Лог.Отладка("Текущая версия rac "+ФайлУтилиты.ПолноеИмя);
Возврат ФайлУтилиты.ПолноеИмя;
КонецЕсли;
Возврат ТекущийПуть;
КонецФункции
/////////////////////////////////////////////////////////////////////////////////
СистемнаяИнформация = Новый СистемнаяИнформация;
ЭтоWindows = Найти(НРег(СистемнаяИнформация.ВерсияОС), "windows") > 0;
Лог = Логирование.ПолучитьЛог("vanessa.app.deployka");