لکه څنګه چې موږ د لینکس چاپیریال کې د 1C محصولات څنګه کار کوي موضوع ته کتنه وکړه، یو نیمګړتیا وموندل شوه - د 1C سرورونو کلستر اداره کولو لپاره د مناسب ګرافیکي ملټي پلیټ فارم وسیلې نشتوالی. او پریکړه وشوه چې دا نیمګړتیا د ریک کنسول افادیت لپاره د GUI په لیکلو سره سم کړئ. Tcl/tk د پرمختیایي ژبې په توګه غوره شوی و ځکه چې زما په نظر، د دې دندې لپاره ترټولو مناسب. او له همدې امله، زه غواړم په دې موادو کې د حل ځینې په زړه پورې اړخونه وړاندې کړم.
د کار کولو لپاره تاسو به tcl/tk او 1C توزیع ته اړتیا ولرئ. او له هغه وخته چې ما پریکړه وکړه چې د دریمې ډلې کڅوړو کارولو پرته د لومړني tcl/tk تحویلۍ ډیری وړتیاوې رامینځته کړم ، زه به 8.6.7 نسخه ته اړتیا ولرم چې پکې ttk شامل دي - د اضافي ګرافیک عناصرو سره یوه کڅوړه چې موږ یې په عمده ډول ttk ته اړتیا لرو. :: TreeView، دا د ونې جوړښت او د میز (لست) په بڼه دواړه ډاټا ښودلو ته اجازه ورکوي. همچنان ، په نوې نسخه کې ، د استثنا سره کار بیا کار شوی (د هڅه کولو کمانډ ، کوم چې په پروژه کې کارول کیږي کله چې بهرني کمانډونه چلوي).
پروژه د څو فایلونو څخه جوړه ده (که څه هم هیڅ شی تاسو په یو کې د هرڅه کولو څخه منع نه کوي):
rac_gui.cfg - ډیفالټ ترتیب
rac_gui.tcl - اصلي لانچ سکریپټ
د lib ډایرکټر فایلونه لري چې په اوتومات ډول په پیل کې بار شوي:
function.tcl - د پروسیجرونو سره فایل
gui.tcl - اصلي ګرافیکي انٹرفیس
images.tcl - base64 انځور کتابتون
د rac_gui.tcl فایل، په حقیقت کې، ژباړونکی پیل کوي، متغیرات پیل کوي، ماډلونه، تشکیلات او داسې نور باروي. د نظرونو سره د فایل منځپانګې:
rac_gui.tcl
#!/bin/sh
exec wish "$0" -- "$@"
# Устанавливаем текущий каталог
set dir(root) [pwd]
# Устанавливаем рабочий каталог, если его нет то создаём
set dir(work) [file join $env(HOME) .rac_gui]
if {[file exists $dir(work)] == 0 } {
file mkdir $dir(work)
}
# каталог с модулями
set dir(lib) "[file join $dir(root) lib]"
# загружаем пользовательский конфиг, если он отсутствует, то копируем дефолтный
if {[file exists [file join $dir(work) rac_gui.cfg]] ==0} {
file copy [file join [pwd] rac_gui.cfg] [file join $dir(work) rac_gui.cfg]
}
source [file join $dir(work) rac_gui.cfg]
# Код проверки наличия rac и правильности указания пути в конфиге
# если программа не найдена то будет выведен диалог для указания корректного пути
# и этот путь будет записан в пользовательский конфиг
if {[file exists $rac_cmd] == 0} {
set rac_cmd [tk_getOpenFile -initialdir $env(HOME) -parent . -title "Укажите путь до rac" -initialfile rac]
file copy [file join $dir(work) rac_gui.cfg] [file join $dir(work) rac_gui.cfg.bak]
set orig_file [open [file join $dir(work) rac_gui.cfg.bak] "r"]
set file [open [file join $dir(work) rac_gui.cfg] "w"]
while {[gets $orig_file line] >=0 } {
if {[string match "set rac_cmd*" $line]} {
puts $file "set rac_cmd $rac_cmd"
} else {
puts $file $line
}
}
close $file
close $orig_file
#return "$host:$port"
file delete [file join $dir(work) 1c_srv.cfg.bak]
} else {
puts "Found $rac_cmd"
}
set cluster_user ""
set cluster_pwd ""
set agent_user ""
set agent_pwd ""
## LOAD FILE ##
# Загружаем модули кроме gui.tcl так как его надо загрузить последним
foreach modFile [lsort [glob -nocomplain [file join $dir(lib) *.tcl]]] {
if {[file tail $modFile] ne "gui.tcl"} {
source $modFile
puts "Loaded module $modFile"
}
}
source [file join $dir(lib) gui.tcl]
source [file join $dir(work) rac_gui.cfg]
# Читаем файл со списком серверов 1С
# и добавляем в дерево
if [file exists [file join $dir(work) 1c_srv.cfg]] {
set f [open [file join $dir(work) 1c_srv.cfg] "RDONLY"]
while {[gets $f line] >=0} {
.frm_tree.tree insert {} end -id "server::$line" -text "$line" -values "$line"
}
}
د هر هغه څه ډاونلوډ کولو وروسته چې اړتیا ورته وي او د ریک افادیت شتون چیک کول ، ګرافیکي کړکۍ به پیل شي. د پروګرام انٹرفیس له دریو عناصرو څخه جوړ دی:
وسیلې پټې، ونه او لیست
ما د "ونې" مینځپانګې د امکان تر حده د 1C څخه معیاري وینډوز تجهیزاتو ته ورته کړې.
اصلي کوډ چې دا کړکۍ جوړوي په فایل کې شتون لري
lib/gui.tcl
# установка размера и положения основного окна
# можно установить в переменную topLevelGeometry в конфиг программы
if {[info exists topLevelGeometry]} {
wm geometry . $topLevelGeometry
} else {
wm geometry . 1024x768
}
# Заголовок окна
wm title . "1C Rac GUI"
wm iconname . "1C Rac Gui"
# иконка окна (берется из файла lib/imges.tcl)
wm iconphoto . tcl
wm protocol . WM_DELETE_WINDOW Quit
wm overrideredirect . 0
wm positionfrom . user
ttk::style theme use clam
# Панель инсрументов
set frm_tool [frame .frm_tool]
pack $frm_tool -side left -fill y
ttk::panedwindow .panel -orient horizontal -style TPanedwindow
pack .panel -expand true -fill both
pack propagate .panel false
ttk::button $frm_tool.btn_add -command Add -image add_grey_32
ttk::button $frm_tool.btn_del -command Del -image del_grey_32
ttk::button $frm_tool.btn_edit -command Edit -image edit_grey_32
ttk::button $frm_tool.btn_quit -command Quit -image quit_grey_32
pack $frm_tool.btn_add $frm_tool.btn_del $frm_tool.btn_edit -side top -padx 5 -pady 5
pack $frm_tool.btn_quit -side bottom -padx 5 -pady 5
# Дерево с полосами прокрутки
set frm_tree [frame .frm_tree]
ttk::scrollbar $frm_tree.hsb1 -orient horizontal -command [list $frm_tree.tree xview]
ttk::scrollbar $frm_tree.vsb1 -orient vertical -command [list $frm_tree.tree yview]
set tree [ttk::treeview $frm_tree.tree -show tree
-xscrollcommand [list $frm_tree.hsb1 set] -yscrollcommand [list $frm_tree.vsb1 set]]
grid $tree -row 0 -column 0 -sticky nsew
grid $frm_tree.vsb1 -row 0 -column 1 -sticky nsew
grid $frm_tree.hsb1 -row 1 -column 0 -sticky nsew
grid columnconfigure $frm_tree 0 -weight 1
grid rowconfigure $frm_tree 0 -weight 1
# назначение обработчика нажатия кнопкой мыши
bind $frm_tree.tree <ButtonRelease> "TreePress $frm_tree.tree"
# Список для данных (таблица)
set frm_work [frame .frm_work]
ttk::scrollbar $frm_work.hsb -orient horizontal -command [list $frm_work.tree_work xview]
ttk::scrollbar $frm_work.vsb -orient vertical -command [list $frm_work.tree_work yview]
set tree_work [
ttk::treeview $frm_work.tree_work
-show headings -columns "par val" -displaycolumns "par val"
-xscrollcommand [list $frm_work.hsb set]
-yscrollcommand [list $frm_work.vsb set]
]
# Установка цветов для чередования в таблице
$tree_work tag configure dark -background $color(dark_table_bg)
$tree_work tag configure light -background $color(light_table_bg)
# Размещение элементов на форме
grid $tree_work -row 0 -column 0 -sticky nsew
grid $frm_work.vsb -row 0 -column 1 -sticky nsew
grid $frm_work.hsb -row 1 -column 0 -sticky nsew
grid columnconfigure $frm_work 0 -weight 1
grid rowconfigure $frm_work 0 -weight 1
pack $frm_tree $frm_work -side left -expand true -fill both
#.panel add $frm_tool -weight 1
.panel add $frm_tree -weight 1
.panel add $frm_work -weight 1
د برنامه سره کار کولو الګوریتم په لاندې ډول دی:
1. لومړی، تاسو اړتیا لرئ د اصلي کلستر سرور اضافه کړئ (د بیلګې په توګه، د کلستر مدیریت سرور (په لینکس کې، مدیریت د "/opt/1C/v8.3/x86_64/ras cluster —daemon" کمانډ سره پیل شوی)).
د دې کولو لپاره، په "+" تڼۍ کلیک وکړئ او په هغه کړکۍ کې چې خلاصیږي، د سرور پته او بندر دننه کړئ:
وروسته، زموږ سرور به په ونې کې د هغې په کلیک کولو سره ښکاره شي، د کلسترونو لیست به خلاص شي یا د پیوستون تېروتنه به ښکاره شي.
2. د کلستر نوم باندې کلیک کول به د دې لپاره موجود دندو لیست خلاص کړي.
۱.…
او داسې نور، i.e. د نوي کلستر د اضافه کولو لپاره، په لیست کې موجود هر یو غوره کړئ او په تول پټه کې "+" تڼۍ کیکاږئ او نوی ډیالوګ به ښکاره شي:
په وسیلې پټه کې بټنونه د شرایطو پورې اړه لري دندې ترسره کوي، د بیلګې په توګه. په دې پورې اړه لري چې د ونې کوم عنصر یا لیست غوره شوی، یو یا بل طرزالعمل به ترسره شي.
راځئ چې د اضافې تڼۍ مثال وګورو ("+"):
د تڼۍ نسل کوډ:
ttk::button $frm_tool.btn_add -command Add -image add_grey_32
دلته موږ ګورو چې کله چې تڼۍ کیښودل شي، د "اضافه" طرزالعمل به اجرا شي، د هغې کوډ:
proc Add {} {
global active_cluster host
# Определяем идентификатор выделенного элемента
set id [.frm_tree.tree selection]
# Определяем значение этого элемента
set values [.frm_tree.tree item [.frm_tree.tree selection] -values]
set key [lindex [split $id "::"] 0]
# в зависимости от того что выделили будет запущена нужная процедура
if {$key eq "" || $key eq "server"} {
set host [ Add::server ]
return
}
Add::$key .frm_tree.tree $host $values
}
دلته د ټیکل یوه ګټه ده: تاسو کولی شئ د کړنلارې نوم په توګه د متغیر ارزښت تیر کړئ:
Add::$key .frm_tree.tree $host $values
دا د مثال په توګه، که موږ اصلي سرور ته اشاره وکړو او "+" فشار راوړو، نو د Add::server کړنلاره به پیل شي، که چیرې په کلستر کې - Add::cluster او داسې نور (زه به د دې په اړه ولیکئ چې چیرته اړین "کیلي" د یو څه لاندې څخه راځي)، لیست شوي طرزالعملونه د شرایطو سره مناسب ګرافیک عناصر راوباسي.
لکه څنګه چې تاسو دمخه یادونه کړې وي ، فورمې په سټایل کې ورته دي - دا د حیرانتیا خبره نده ، ځکه چې دوی د یوې کړنلارې لخوا ښودل شوي ، په دقیق ډول د فارم اصلي چوکاټ (کړکۍ ، تڼۍ ، عکس ، لیبل) ، د پروسې نوم AddTopLevel
proc AddToplevel {lbl img {win_name .add}} {
set cmd "destroy $win_name"
if [winfo exists $win_name] {destroy $win_name}
toplevel $win_name
wm title $win_name $lbl
wm iconphoto $win_name tcl
# метка с иконкой
ttk::label $win_name.lbl -image $img
# фрейм с полями ввода
set frm [ttk::labelframe $win_name.frm -text $lbl -labelanchor nw]
grid columnconfigure $frm 0 -weight 1
grid rowconfigure $frm 0 -weight 1
# фрейм и кнопки
set frm_btn [frame $win_name.frm_btn -border 0]
ttk::button $frm_btn.btn_ok -image ok_grey_24 -command { }
ttk::button $frm_btn.btn_cancel -command $cmd -image quit_grey_24
grid $win_name.lbl -row 0 -column 0 -sticky nw -padx 5 -pady 10
grid $frm -row 0 -column 1 -sticky nw -padx 5 -pady 5
grid $frm_btn -row 1 -column 1 -sticky se -padx 5 -pady 5
pack $frm_btn.btn_cancel -side right
pack $frm_btn.btn_ok -side right -padx 10
return $frm
}
د کال پیرامیټرونه: سرلیک، د کتابتون څخه د عکس لپاره د عکس نوم (lib/images.tcl) او د اختیاري کړکۍ نوم پیرامیټر (ډیفالټ .add). په دې توګه، که موږ د اصلي سرور او کلستر اضافه کولو لپاره پورته مثالونه واخلو، نو زنګ به د دې مطابق وي:
AddToplevel "Добавление основного сервера" server_grey_64
او یا
AddToplevel "Добавление кластера" cluster_grey_64
ښه، د دې مثالونو په دوام، زه به هغه پروسیجرونه وښیم چې د سرور یا کلستر لپاره ډیالوګ اضافه کوي.
اضافه کول::سرور
proc Add::server {} {
global default
# выводим основную форму
set frm [AddToplevel "Добавление основного сервера" server_grey_64]
# добавляем етки и поля ввода на эту форму
label $frm.lbl_host -text "Адрес сервера"
entry $frm.ent_host
label $frm.lbl_port -text "Порт"
entry $frm.ent_port
$frm.ent_port insert end $default(port)
grid $frm.lbl_host -row 0 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_host -row 0 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_port -row 1 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_port -row 1 -column 1 -sticky nsew -padx 5 -pady 5
grid columnconfigure $frm 0 -weight 1
grid rowconfigure $frm 0 -weight 1
#set frm_btn [frame .add.frm_btn -border 0]
# переопределяем обработчик нажатия кнопки
.add.frm_btn.btn_ok configure -command {
set host [SaveMainServer [.add.frm.ent_host get] [.add.frm.ent_port get]]
.frm_tree.tree insert {} end -id "server::$host" -text "$host" -values "$host"
destroy .add
return $host
}
return $frm
}
اضافه کول::کلستر
proc Add::cluster {tree host values} {
global default lifetime_limit expiration_timeout session_fault_tolerance_level
global max_memory_size max_memory_time_limit errors_count_threshold security_level
global load_balancing_mode kill_problem_processes
agent_user agent_pwd cluster_user cluster_pwd auth_agent
if {$agent_user ne "" && $agent_pwd ne ""} {
set auth_agent "--agent-user=$agent_user --agent-pwd=$agent_pwd"
} else {
set auth_agent ""
}
# устанавливаем глобальные переменные ()
set lifetime_limit $default(lifetime_limit)
set expiration_timeout $default(expiration_timeout)
set session_fault_tolerance_level $default(session_fault_tolerance_level)
set max_memory_size $default(max_memory_size)
set max_memory_time_limit $default(max_memory_time_limit)
set errors_count_threshold $default(errors_count_threshold)
set security_level [lindex $default(security_level) 0]
set load_balancing_mode [lindex $default(load_balancing_mode) 0]
set frm [AddToplevel "Добавление кластера" cluster_grey_64]
label $frm.lbl_host -text "Адрес основного сервера"
entry $frm.ent_host
label $frm.lbl_port -text "Порт"
entry $frm.ent_port
$frm.ent_port insert end $default(port)
label $frm.lbl_name -text "Название кластера"
entry $frm.ent_name
label $frm.lbl_secure_connect -text "Защищённое соединение"
ttk::combobox $frm.cb_security_level -textvariable security_level -values $default(security_level)
label $frm.lbl_expiration_timeout -text "Останавливать выключенные процессы через:"
entry $frm.ent_expiration_timeout -textvariable expiration_timeout
label $frm.lbl_session_fault_tolerance_level -text "Уровень отказоустойчивости"
entry $frm.ent_session_fault_tolerance_level -textvariable session_fault_tolerance_level
label $frm.lbl_load_balancing_mode -text "Режим распределения нагрузки"
ttk::combobox $frm.cb_load_balancing_mode -textvariable load_balancing_mode
-values $default(load_balancing_mode)
label $frm.lbl_errors_count_threshold -text "Допустимое отклонение количества ошибок сервера, %"
entry $frm.ent_errors_count_threshold -textvariable errors_count_threshold
label $frm.lbl_processes -text "Рабочие процессы:"
label $frm.lbl_lifetime_limit -text "Период перезапуска, сек."
entry $frm.ent_lifetime_limit -textvariable lifetime_limit
label $frm.lbl_max_memory_size -text "Допустимый объём памяти, КБ"
entry $frm.ent_max_memory_size -textvariable max_memory_size
label $frm.lbl_max_memory_time_limit -text "Интервал превышения допустимого объёма памяти, сек."
entry $frm.ent_max_memory_time_limit -textvariable max_memory_time_limit
label $frm.lbl_kill_problem_processes -justify left -anchor nw -text "Принудительно завершать проблемные процессы"
checkbutton $frm.check_kill_problem_processes -variable kill_problem_processes -onvalue yes -offvalue no
grid $frm.lbl_host -row 0 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_host -row 0 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_port -row 1 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_port -row 1 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_name -row 2 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_name -row 2 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_secure_connect -row 3 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.cb_security_level -row 3 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_expiration_timeout -row 4 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_expiration_timeout -row 4 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_session_fault_tolerance_level -row 5 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_session_fault_tolerance_level -row 5 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_load_balancing_mode -row 6 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.cb_load_balancing_mode -row 6 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_errors_count_threshold -row 7 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_errors_count_threshold -row 7 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_processes -row 8 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.lbl_lifetime_limit -row 9 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_lifetime_limit -row 9 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_max_memory_size -row 10 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_max_memory_size -row 10 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_max_memory_time_limit -row 11 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.ent_max_memory_time_limit -row 11 -column 1 -sticky nsew -padx 5 -pady 5
grid $frm.lbl_kill_problem_processes -row 12 -column 0 -sticky nw -padx 5 -pady 5
grid $frm.check_kill_problem_processes -row 12 -column 1 -sticky nw -padx 5 -pady 5
# переопределяем обработчик
.add.frm_btn.btn_ok configure -command {
RunCommand "" "cluster insert
--host=[.add.frm.ent_host get]
--port=[.add.frm.ent_port get]
--name=[.add.frm.ent_name get]
--expiration-timeout=$expiration_timeout
--lifetime-limit=$lifetime_limit
--max-memory-size=$max_memory_size
--max-memory-time-limit=$max_memory_time_limit
--security-level=$security_level
--session-fault-tolerance-level=$session_fault_tolerance_level
--load-balancing-mode=$load_balancing_mode
--errors-count-threshold=$errors_count_threshold
--kill-problem-processes=$kill_problem_processes
$auth_agent $host"
Run::server $tree $host ""
destroy .add
}
return $frm
}
کله چې د دې پروسیجرونو کوډ پرتله کول، توپیر په ښکاره سترګو لیدل کیږي؛ زه به د "Ok" تڼۍ سمبالونکي باندې تمرکز وکړم. په Tk کې، د ګرافیک عناصرو ملکیتونه د اختیار په کارولو سره د برنامه اجرا کولو پرمهال له پامه غورځول کیدی شي سمبالول. د مثال په توګه، د تڼۍ ښودلو لپاره لومړنۍ کمانډ:
ttk::button $frm_btn.btn_ok -image ok_grey_24 -command { }
مګر زموږ په فورمو کې، کمانډ په اړین فعالیت پورې اړه لري:
.add.frm_btn.btn_ok configure -command {
RunCommand "" "cluster insert
--host=[.add.frm.ent_host get]
--port=[.add.frm.ent_port get]
--name=[.add.frm.ent_name get]
--expiration-timeout=$expiration_timeout
--lifetime-limit=$lifetime_limit
--max-memory-size=$max_memory_size
--max-memory-time-limit=$max_memory_time_limit
--security-level=$security_level
--session-fault-tolerance-level=$session_fault_tolerance_level
--load-balancing-mode=$load_balancing_mode
--errors-count-threshold=$errors_count_threshold
--kill-problem-processes=$kill_problem_processes
$auth_agent $host"
Run::server $tree $host ""
destroy .add
}
په پورته مثال کې، د "کلګ شوي" تڼۍ د کلستر اضافه کولو پروسه پیلوي.
دلته دا ارزښت لري چې په Tk کې د ګرافیک عناصرو سره د کار کولو په لور یو تحلیل رامینځته کړئ - د مختلف ډیټا ان پټ عناصرو لپاره (د ننوتلو ، کمبو باکس ، چیک بټن او نور) لپاره یو پیرامیټر د متن متغیر په توګه معرفي شوی:
entry $frm.ent_lifetime_limit -textvariable lifetime_limit
دا متغیر په نړیوال نوم ځای کې تعریف شوی او اوس مهال داخل شوی ارزښت لري. هغوی. د دې لپاره چې د ساحې څخه داخل شوي متن ترلاسه کړئ، تاسو اړتیا لرئ چې د متغیر سره ورته ارزښت ولولئ (البته، په دې شرط چې دا د عنصر رامینځته کولو په وخت کې تعریف شوی وي).
د داخل شوي متن بیرته ترلاسه کولو دوهم میتود (د ننوتلو ډول عناصرو لپاره) د get کمانډ کارول دي:
.add.frm.ent_name get
دا دواړه میتودونه په پورتني کوډ کې لیدل کیدی شي.
د دې تڼۍ کلیک کول، پدې حالت کې، د ریک په شرایطو کې د کلستر اضافه کولو لپاره د تولید شوي کمانډ لاین سره د RunCommand پروسیجر پیل کوي:
/opt/1C/v8.3/x86_64/rac cluster insert --host=localhost --port=1540 --name=dsdsds --expiration-timeout=0 --lifetime-limit=0 --max-memory-size=0 --max-memory-time-limit=0 --security-level=0 --session-fault-tolerance-level=0 --load-balancing-mode=performance --errors-count-threshold=0 --kill-problem-processes=no localhost:1545
اوس موږ اصلي کمانډ ته راځو، کوم چې د هغه پیرامیټونو سره چې موږ ورته اړتیا لرو د ریک لانچ کنټرولوي، د کمانډ محصول په لیستونو او بیرته راګرځولو کې هم تجزیه کوي، که اړتیا وي:
RunCommand
proc RunCommand {root par} {
global dir rac_cmd cluster work_list_row_count agent_user agent_pwd cluster_user cluster_pwd
puts "$rac_cmd $par"
set work_list_row_count 0
# открываем канал в неблокирующем режиме
# $rac - команда с полным путём
# $par - сформированные ключи запуска и опции
set pipe [open "|$rac_cmd $par" "r"]
try {
set lst ""
set l ""
# вывод команды добавляем в список списков
while {[gets $pipe line]>=0} {
#puts $line
if {$line eq ""} {
lappend l $lst
set lst ""
} else {
lappend lst [string trim $line]
}
}
close $pipe
return $l
} on error {result options} {
# Запуск обработчика ошибок
ErrorParcing $result $options
return ""
}
}
د اصلي سرور معلوماتو ته د ننوتلو وروسته، دا به په ونې کې اضافه شي، د دې لپاره، په پورتني اضافه: سرور طرزالعمل کې، لاندې کوډ مسؤل دی:
.frm_tree.tree insert {} end -id "server::$host" -text "$host" -values "$host"
اوس، په ونې کې د سرور نوم په کلیک کولو سره، موږ د هغه سرور لخوا اداره شوي کلسترونو لیست ترلاسه کوو، او په کلستر کې کلیک کولو سره، موږ د کلستر عناصرو لیست ترلاسه کوو (سرورونه، انفوبیسونه، او نور). دا د TreePress طرزالعمل کې پلي کیږي (file lib/function.tcl):
proc TreePress {tree} {
global host server active_cluster infobase
# определяем выделенный элемент
set id [$tree selection]
# устанавливаем нужные глобальные переменные
SetGlobalVarFromTreeItems $tree $id
# Определяем ключ и значение, т.е. именно тип выбранного элемента
set values [$tree item $id -values]
set key [lindex [split $id "::"] 0]
# и в зависимости от того что выбрали будет запущена соответствующая процедура
# в пространстве имён Run
Run::$key $tree $host $values
}
په دې اساس، Run::server به د اصلي سرور لپاره پیل شي (د کلستر لپاره - Run::cluster، د کاري سرور لپاره - Run::work_server، etc.). هغوی. د $ کیلي متغیر ارزښت د ونې عنصر نوم برخه ده چې د اختیار لخوا مشخص شوي -د.
راځئ چې طرزالعمل ته پام وکړو
چلول::سرور
proc Run::server {tree host values} {
# получаем список кластеров требуемого сервера
set lst [RunCommand server::$host "cluster list $host"]
if {$lst eq ""} {return}
set l [lindex $lst 0]
#puts $lst
# удаляем лишнее из списка
.frm_work.tree_work delete [ .frm_work.tree_work children {}]
# читаем список
foreach cluster_list $lst {
# Заполняем список полученными значениями
InsertItemsWorkList $cluster_list
# обрабатываем вывод (список) для добавления данных в дерево
foreach i $cluster_list {
#puts $i
set cluster_list [split $i ":"]
if {[string trim [lindex $cluster_list 0]] eq "cluster"} {
set cluster_id [string trim [lindex $cluster_list 1]]
lappend cluster($cluster_id) $cluster_id
}
if {[string trim [lindex $cluster_list 0]] eq "name"} {
lappend cluster($cluster_id) [string trim [lindex $cluster_list 1]]
}
}
}
# добавляем кластеры в дерево
foreach x [array names cluster] {
set id [lindex $cluster($x) 0]
if { [$tree exists "cluster::$id"] == 0 } {
$tree insert "server::$host" end -id "cluster::$id" -text "[lindex $cluster($x) 1]" -values "$id"
# добавляем элементы в кластер
InsertClusterItems $tree $id
}
}
if { [$tree exists "agent_admins::$id"] == 0 } {
$tree insert "server::$host" end -id "agent_admins::$id" -text "Администраторы" -values "$id"
#InsertClusterItems $tree $id
}
}
دا کړنلاره هغه څه پروسس کوي چې له سرور څخه د RunCommand کمانډ له لارې ترلاسه شوي او هر ډول شیان په ونې کې اضافه کوي - کلسترونه، مختلف ریښې عناصر (اډو، کاري سرورونه، ناستې، او داسې نور). که تاسو له نږدې وګورئ، تاسو به دننه د InsertItemsWorkList پروسې ته زنګ ووهئ. دا د ریک کنسول افادیت محصول پروسس کولو سره په ګرافیکي لیست کې د عناصرو اضافه کولو لپاره کارول کیږي ، کوم چې دمخه د $ lst متغیر ته د لیست په توګه راستون شوی و. دا د لیستونو لیست دی چې د عناصرو جوړه جوړه د کولون لخوا جلا شوي.
د مثال په توګه، د کلستر اړیکو لیست:
svk@svk ~]$ /opt/1C/v8.3/x86_64/rac connection list --cluster=783d2170-56c3-11e8-c586-fc75165efbb2 localhost:1545
connection : dcf5991c-7d24-11e8-1690-fc75165efbb2
conn-id : 0
host : svk.home
process : 79de2e16-56c3-11e8-c586-fc75165efbb2
infobase : 00000000-0000-0000-0000-000000000000
application : "JobScheduler"
connected-at : 2018-07-01T14:49:51
session-number : 0
blocked-by-ls : 0
connection : b993293a-7d24-11e8-1690-fc75165efbb2
conn-id : 0
host : svk.home
process : 79de2e16-56c3-11e8-c586-fc75165efbb2
infobase : 00000000-0000-0000-0000-000000000000
application : "JobScheduler"
connected-at : 2018-07-01T14:48:52
session-number : 0
blocked-by-ls : 0
په ګرافیکي بڼه به داسې ښکاري:
پورته کړنلاره د سرلیک او ډیټا لپاره د عناصرو نومونه غوره کوي ترڅو جدول ډک کړي:
InsertItemsWorklist
proc InsertItemsWorkList {lst} {
global work_list_row_count
# установка чередования цвета для строки
if [expr $work_list_row_count % 2] {
set tag dark
} else {
set tag light
}
# разбор строк на пары ключ - значение
foreach i $lst {
if [regexp -nocase -all -- {(D+)(s*?|)(:)(s*?|)(.*)} $i match param v2 v3 v4 value] {
lappend column_list [string trim $param]
lappend value_list [string trim $value]
}
}
# заполнение таблицы
.frm_work.tree_work configure -columns $column_list -displaycolumns $column_list
.frm_work.tree_work insert {} end -values $value_list -tags $tag
.frm_work.tree_work column #0 -stretch
# установка заголовков
foreach j $column_list {
.frm_work.tree_work heading $j -text $j
}
incr work_list_row_count
}
دلته، د ساده کمانډ [split $str ":"] پر ځای، کوم چې تار په عناصرو ویشي چې د ":" لخوا جلا شوي او لیست بیرته راولي، یو منظم بیان کارول کیږي، ځکه چې ځینې عناصر هم کولن لري.
د InsertClusterItems کړنلاره (یو له ډیری ورته ورته) په ساده ډول د اړین کلستر عنصر ونې ته د ورته پیژندونکو سره د ماشومانو عناصرو لیست اضافه کوي
د کلستر توکي داخل کړئ
proc InsertClusterItems {tree id} {
set parent "cluster::$id"
$tree insert $parent end -id "infobases::$id" -text "Информационные базы" -values "$id"
$tree insert $parent end -id "servers::$id" -text "Рабочие серверы" -values "$id"
$tree insert $parent end -id "admins::$id" -text "Администраторы" -values "$id"
$tree insert $parent end -id "managers::$id" -text "Менеджеры кластера" -values $id
$tree insert $parent end -id "processes::$id" -text "Рабочие процессы" -values "workprocess-all"
$tree insert $parent end -id "sessions::$id" -text "Сеансы" -values "sessions-all"
$tree insert $parent end -id "locks::$id" -text "Блокировки" -values "blocks-all"
$tree insert $parent end -id "connections::$id" -text "Соединения" -values "connections-all"
$tree insert $parent end -id "profiles::$id" -text "Профили безопасности" -values $id
}
تاسو کولی شئ د ورته طرزالعمل پلي کولو لپاره دوه نور اختیارونه په پام کې ونیسئ، چیرې چې دا به په ښکاره ډول ښکاره شي چې تاسو څنګه اصلاح کولی شئ او د تکرار امرونو څخه ځان خلاص کړئ:
په دې پروسیجر کې، اضافه کول او چک کول په سر کې حل کیږي:
InsertBaseItems
proc InsertBaseItems {tree id} {
set parent "infobase::$id"
if { [$tree exists "sessions::$id"] == 0 } {
$tree insert $parent end -id "sessions::$id" -text "Сеансы" -values "$id"
}
if { [$tree exists "locks::$id"] == 0 } {
$tree insert $parent end -id "locks::$id" -text "Блокировки" -values "$id"
}
if { [$tree exists "connections::$id"] == 0 } {
$tree insert $parent end -id "connections::$id" -text "Соединения" -values "$id"
}
}
دلته یو ډیر درست چلند دی:
InsertProfileItems
proc InsertProfileItems {tree id} {
set parent "profile::$id"
set lst {
{dir "Виртуальные каталоги"}
{com "Разрешённые COM-классы"}
{addin "Внешние компоненты"}
{module "Внешние отчёты и обработки"}
{app "Разрешённые приложения"}
{inet "Ресурсы интернет"}
}
foreach i $lst {
append item [lindex $i 0] "::$id"
if { [$tree exists $item] == 0 } {
$tree insert $parent end -id $item -text [lindex $i 1] -values "$id"
}
unset item
}
}
د دوی تر مینځ توپیر د لوپ کارول دي، په کوم کې چې تکرار کمانډ اجرا کیږي. د کارولو کومه طریقه د پراختیا کونکي په اختیار کې ده.
موږ د عناصرو اضافه کول او د معلوماتو بیرته ترلاسه کول پوښلي، اوس د دې وخت دی چې په ترمیم تمرکز وکړو. له هغه ځایه چې اساسا ، ورته پیرامیټونه د ترمیم او اضافه کولو لپاره کارول کیږي (د معلوماتو اساس استثنا سره) ، ورته ډیالوګ فارمونه کارول کیږي. د اضافه کولو لپاره د زنګ وهلو پروسیجرونو الګوریتم داسې ښکاري:
اضافه کړئ::$key->AddToplevel
او د دې په څیر ترمیم لپاره:
تدوین::$key->Add::$key->AddTopLevel
د مثال په توګه، راځئ چې د کلستر ترمیم واخلو، د بیلګې په توګه. په ونه کې د کلستر په نوم کلیک کولو سره، د وسیلې بار (پنسل) کې د ترمیم تڼۍ فشار ورکړئ او اړونده بڼه به په سکرین کې ښکاره شي:
ایډیټ::کلستر
proc Edit::cluster {tree host values} {
global default lifetime_limit expiration_timeout session_fault_tolerance_level
global max_memory_size max_memory_time_limit errors_count_threshold security_level
global load_balancing_mode kill_problem_processes active_cluster
agent_user agent_pwd cluster_user cluster_pwd auth
if {$cluster_user ne "" && $cluster_pwd ne ""} {
set auth "--cluster-user=$cluster_user --cluster-pwd=$cluster_pwd"
} else {
set auth ""
}
# рисуем форму для кластера
set frm [Add::cluster $tree $host $values]
# меняем текст на метке
$frm configure -text "Редактирование кластера"
set active_cluster $values
# получаем данные по выделенному кластеру
set lst [RunCommand cluster::$values "cluster info --cluster=$active_cluster $host"]
# заполняем поля
FormFieldsDataInsert $frm $lst
# выключаем поля, редактирование которых запрещено
$frm.ent_host configure -state disable
$frm.ent_port configure -state disable
# переназначаем обработчик
.add.frm_btn.btn_ok configure -command {
RunCommand "" "cluster update
--cluster=$active_cluster $auth
--name=[.add.frm.ent_name get]
--expiration-timeout=$expiration_timeout
--lifetime-limit=$lifetime_limit
--max-memory-size=$max_memory_size
--max-memory-time-limit=$max_memory_time_limit
--security-level=$security_level
--session-fault-tolerance-level=$session_fault_tolerance_level
--load-balancing-mode=$load_balancing_mode
--errors-count-threshold=$errors_count_threshold
--kill-problem-processes=$kill_problem_processes
$auth $host"
$tree delete "cluster::$active_cluster"
Run::server $tree $host ""
destroy .add
}
}
په کوډ کې د نظرونو پراساس، په اصولو کې، هرڅه روښانه دي، پرته له دې چې د تڼۍ سمبالونکي کوډ له پامه غورځول شوی او د FormFieldsDataInsert طرزالعمل شتون لري چې ساحې د معلوماتو سره ډکوي او متغیرات پیل کوي:
FormFieldsDataInsert
proc FormFieldsDataInsert {frm lst} {
foreach i [lindex $lst 0] {
# получаем список параметров и значений
if [regexp -nocase -all -- {(D+)(s*?|)(:)(s*?|)(.*)} $i match param v2 v3 v4 value] {
# меняем символы
regsub -all -- "-" [string trim $param] "_" entry_name
# заполняем данными
if [winfo exists $frm.ent_$entry_name] {
$frm.ent_$entry_name delete 0 end
$frm.ent_$entry_name insert end [string trim $value """]
}
if [winfo exists $frm.cb_$entry_name] {
global $entry_name
set $entry_name [string trim $value """]
}
# для чекбоксов меняем значения
if [winfo exists $frm.check_$entry_name] {
global $entry_name
if {$value eq "0"} {
set $entry_name no
} elseif {$value eq "1"} {
set $entry_name yes
} else {
set $entry_name $value
}
}
}
}
}
په دې کړنالرې کې، د tcl یوه بله ګټه پورته شوه - د نورو متغیرونو ارزښتونه د متغیر نومونو په توګه ځای پرځای شوي. هغوی. د فورمو ډکولو او د متغیرونو ابتکار اتومات کولو لپاره، د ساحو او متغیرونو نومونه د ریک یوټیلیټ د کمانډ لاین سویچونو سره مطابقت لري او د یو څه استثنا سره د کمانډ محصول پیرامیټرو نومونه - ډش د انډر سکور لخوا بدل شوی. د بیلګې په توګه ټاکل شوي دندې - انکار د میدان سره سمون خوري ent_scheduled_jobs_deny او متغیر ټاکل شوې_دندو_منظم.
د اضافه کولو او ترمیم کولو فورمې ممکن د ساحو په جوړښت کې توپیر ولري، د بیلګې په توګه، د معلوماتو اساس سره کار کول:
د معلوماتو امنیت اضافه کول
د معلوماتو امنیت ترمیم کول
د تدوین په کړنلاره کې Edit::infobase، اړین ساحې په فورمه کې اضافه کیږي؛ کوډ خورا لوی دی، نو زه یې دلته نه وړاندې کوم.
د انډول په واسطه، د نورو عناصرو لپاره د اضافه کولو، ایډیټ کولو، حذف کولو پروسیجرونه پلي کیږي.
له هغه وخته چې د کارونې فعالیت د سرورونو ، کلسترونو ، معلوماتو اډو او نورو محدود شمیر معنی لري ، ترڅو معلومه کړي چې کوم کلستر د کوم سرور یا معلوماتو امنیت سیسټم پورې اړه لري ، ډیری نړیوال تغیرات معرفي شوي ، چې ارزښتونه یې هر یو ټاکل شوي. کله چې تاسو د ونې په عناصرو کلیک وکړئ. هغوی. کړنلاره په تکراري ډول د ټولو اصلي عناصرو له لارې پرمخ ځي او متغیرات ټاکي:
SetGlobalVarFromTreeItems
proc SetGlobalVarFromTreeItems {tree id} {
global host server active_cluster infobase
set parent [$tree parent $id]
set values [$tree item $id -values]
set key [lindex [split $id "::"] 0]
switch -- $key {
server {set host $values}
work_server {set server $values}
cluster {set active_cluster $values}
infobase {set infobase $values}
}
if {$parent eq ""} {
return
} else {
SetGlobalVarFromTreeItems $tree $parent
}
}
د 1C کلستر تاسو ته اجازه درکوي د اجازې سره یا پرته کار وکړئ. دلته دوه ډوله مدیران شتون لري - د کلستر اجنټ مدیر او د کلستر مدیر. په دې اساس، د سم عملیات لپاره، 4 نور نړیوال تغیرات معرفي شوي چې د مدیر ننوتل او پټنوم لري. هغوی. که چیرې په کلستر کې د مدیر حساب شتون ولري، ستاسو د ننوتلو او پټنوم د ننوتلو لپاره به یو ډیالوګ ښکاره شي، ډاټا به په حافظه کې خوندي شي او د اړوند کلستر لپاره په هر کمانډ کې داخل شي.
دا د غلطۍ اداره کولو طرزالعمل مسؤلیت دی.
تېروتنه
proc ErrorParcing {err opt} {
global cluster_user cluster_pwd agent_user agent_pwd
switch -regexp -- $err {
"Cluster administrator is not authenticated" {
AuthorisationDialog "Администратор кластера"
.auth_win.frm_btn.btn_ok configure -command {
set cluster_user [.auth_win.frm.ent_name get]
set cluster_pwd [.auth_win.frm.ent_pwd get]
destroy .auth_win
}
#RunCommand $root $par
}
"Central server administrator is not authenticated" {
AuthorisationDialog "Администратор агента кластера"
.auth_win.frm_btn.btn_ok configure -command {
set agent_user [.auth_win.frm.ent_name get]
set agent_pwd [.auth_win.frm.ent_pwd get]
destroy .auth_win
}
}
"Администратор кластера не аутентифицирован" {
AuthorisationDialog "Администратор кластера"
.auth_win.frm_btn.btn_ok configure -command {
set cluster_user [.auth_win.frm.ent_name get]
set cluster_pwd [.auth_win.frm.ent_pwd get]
destroy .auth_win
}
#RunCommand $root $par
}
"Администратор центрального сервера не аутентифицирован" {
AuthorisationDialog "Администратор агента кластера"
.auth_win.frm_btn.btn_ok configure -command {
set agent_user [.auth_win.frm.ent_name get]
set agent_pwd [.auth_win.frm.ent_pwd get]
destroy .auth_win
}
}
(.+) {
tk_messageBox -type ok -icon error -message "$err"
}
}
}
هغوی. د هغه څه پورې اړه لري چې کمانډ بیرته راځي، عکس العمل به د هغې مطابق وي.
دا مهال، د فعالیت شاوخوا 95 سلنه پلي شوي، ټول هغه څه چې پاتې دي د امنیتي پروفایلونو سره د کار پلي کول دي او ازموینه یې =). بس نور څه نه. زه د خرابې کیسې لپاره بخښنه غواړم.
کوډ په دودیز ډول شتون لري
تازه کول: ما د امنیتي پروفایلونو سره کار پای ته ورساوه. اوس فعالیت 100٪ پلي کیږي.
2 تازه کول: په انګلیسي او روسی کې ځایی کول اضافه شوي ، په win7 کې کار ازمول شوی
سرچینه: www.habr.com