Revision 66c08b64
Von Moritz Bunkus vor mehr als 11 Jahren hinzugefügt
SL/Controller/Admin.pm | ||
---|---|---|
12 | 12 |
use SL::DB::Printer; |
13 | 13 |
use SL::Helper::Flash; |
14 | 14 |
use SL::Locale::String qw(t8); |
15 |
use SL::System::InstallationLock; |
|
15 | 16 |
use SL::User; |
16 | 17 |
|
17 | 18 |
use Rose::Object::MakeMethods::Generic |
18 | 19 |
( |
19 |
'scalar --get_set_init' => [ qw(client user group printer nologin_file_name db_cfg is_locked
|
|
20 |
'scalar --get_set_init' => [ qw(client user group printer db_cfg is_locked |
|
20 | 21 |
all_dateformats all_numberformats all_countrycodes all_stylesheets all_menustyles all_clients all_groups all_users all_rights all_printers) ], |
21 | 22 |
); |
22 | 23 |
|
... | ... | |
355 | 356 |
|
356 | 357 |
sub action_unlock_system { |
357 | 358 |
my ($self) = @_; |
358 |
unlink $self->nologin_file_name; |
|
359 |
|
|
360 |
SL::System::InstallationLock->unlock; |
|
359 | 361 |
flash_later('info', t8('Lockfile removed!')); |
360 | 362 |
$self->redirect_to(action => 'show'); |
361 | 363 |
} |
... | ... | |
363 | 365 |
sub action_lock_system { |
364 | 366 |
my ($self) = @_; |
365 | 367 |
|
366 |
my $fh = IO::File->new($self->nologin_file_name, "w"); |
|
367 |
if (!$fh) { |
|
368 |
$::form->error(t8('Cannot create Lock!')); |
|
369 |
|
|
370 |
} else { |
|
371 |
$fh->close; |
|
372 |
flash_later('info', t8('Lockfile created!')); |
|
373 |
$self->redirect_to(action => 'show'); |
|
374 |
} |
|
368 |
SL::System::InstallationLock->unlock; |
|
369 |
flash_later('info', t8('Lockfile created!')); |
|
370 |
$self->redirect_to(action => 'show'); |
|
375 | 371 |
} |
376 | 372 |
|
377 | 373 |
# |
... | ... | |
379 | 375 |
# |
380 | 376 |
|
381 | 377 |
sub init_db_cfg { $::lx_office_conf{'authentication/database'} } |
382 |
sub init_nologin_file_name { $::lx_office_conf{paths}->{userspath} . '/nologin'; } |
|
383 |
sub init_is_locked { -e $_[0]->nologin_file_name } |
|
378 |
sub init_is_locked { SL::System::InstallationLock->is_locked } |
|
384 | 379 |
sub init_client { SL::DB::Manager::AuthClient->find_by(id => ($::form->{id} || ($::form->{client} || {})->{id})) } |
385 | 380 |
sub init_user { SL::DB::AuthUser ->new(id => ($::form->{id} || ($::form->{user} || {})->{id}))->load } |
386 | 381 |
sub init_group { SL::DB::AuthGroup ->new(id => ($::form->{id} || ($::form->{group} || {})->{id}))->load } |
SL/DBUpgrade2.pm | ||
---|---|---|
235 | 235 |
|
236 | 236 |
# Process a Perl script which updates the database. |
237 | 237 |
# If the script returns 1 then the update was successful. |
238 |
# Return code "2" means "needs more interaction; remove
|
|
239 |
# users/nologin and end current request".
|
|
238 |
# Return code "2" means "needs more interaction; unlock
|
|
239 |
# the system and end current request".
|
|
240 | 240 |
# All other return codes are fatal errors. |
241 | 241 |
sub process_perl_script { |
242 | 242 |
$::lxdebug->enter_sub(); |
... | ... | |
266 | 266 |
print $::form->parse_html_template("dbupgrade/error", { file => $filename, error => $error }); |
267 | 267 |
::end_of_request(); |
268 | 268 |
} elsif (1 != $result) { |
269 |
unlink("users/nologin") if (2 == $result);
|
|
269 |
SL::System::InstallationLock->unlock if 2 == $result;
|
|
270 | 270 |
::end_of_request(); |
271 | 271 |
} |
272 | 272 |
|
... | ... | |
469 | 469 |
form => $::form, |
470 | 470 |
auth => 1 |
471 | 471 |
); |
472 |
User->dbupdate2($form, $scripts->parse_dbupdate_controls); |
|
472 |
User->dbupdate2(form => $form, |
|
473 |
updater => $scripts->parse_dbupdate_controls, |
|
474 |
database => $dbname); |
|
473 | 475 |
|
474 | 476 |
=head1 OVERVIEW |
475 | 477 |
|
... | ... | |
638 | 640 |
Perl scripts are executed via L<eval>. If L<eval> returns falsish then |
639 | 641 |
an error is expected. There are two special return values: If the |
640 | 642 |
script returns C<1> then the update was successful. Return code C<2> |
641 |
means "needs more interaction from the user; remove users/nologin and
|
|
643 |
means "needs more interaction from the user; unlock the system and
|
|
642 | 644 |
end current upgrade process". All other return codes are fatal errors. |
643 | 645 |
|
644 | 646 |
Inside the Perl script several local variables exist that can be used: |
SL/Dispatcher.pm | ||
---|---|---|
235 | 235 |
eval { |
236 | 236 |
pre_request_checks(script => $script, action => $action, routing_type => $routing_type, script_name => $script_name); |
237 | 237 |
|
238 |
if ( (-e ($::lx_office_conf{paths}->{userspath} . "/nologin"))
|
|
238 |
if ( SL::System::InstallationLock->is_locked
|
|
239 | 239 |
&& !is_admin_request(script => $script, script_name => $script_name, routing_type => $routing_type)) { |
240 | 240 |
$::form->error($::locale->text('System currently down for maintenance!')); |
241 | 241 |
} |
SL/System/InstallationLock.pm | ||
---|---|---|
1 |
package SL::System::InstallationLock; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
sub lock { |
|
6 |
my ($class) = @_; |
|
7 |
|
|
8 |
return 1 if $::lx_office_conf{debug}->{keep_installation_unlocked}; |
|
9 |
|
|
10 |
my $fh; |
|
11 |
if (!open($fh, ">", $class->lock_file_name)) { |
|
12 |
die $::locale->text('Lock file handling failed. Please verify that the directory "#1" is writeable by the webserver.', $::lx_office_conf{paths}->{userspath}); |
|
13 |
} |
|
14 |
|
|
15 |
close $fh; |
|
16 |
|
|
17 |
return 1; |
|
18 |
} |
|
19 |
|
|
20 |
sub unlock { |
|
21 |
my ($class) = @_; |
|
22 |
|
|
23 |
return 1 if $::lx_office_conf{debug}->{keep_installation_unlocked}; |
|
24 |
|
|
25 |
my $name = $class->lock_file_name; |
|
26 |
if ((-f $name) && !unlink($name)) { |
|
27 |
die $::locale->text('Lock file handling failed. Please verify that the directory "#1" is writeable by the webserver.', $::lx_office_conf{paths}->{userspath}); |
|
28 |
} |
|
29 |
|
|
30 |
return 1; |
|
31 |
} |
|
32 |
|
|
33 |
sub is_locked { |
|
34 |
my ($class) = @_; |
|
35 |
|
|
36 |
return 0 if $::lx_office_conf{debug}->{keep_installation_unlocked}; |
|
37 |
return -f $class->lock_file_name; |
|
38 |
} |
|
39 |
|
|
40 |
sub lock_file_name { |
|
41 |
$::lx_office_conf{paths}->{userspath} . "/nologin"; |
|
42 |
} |
|
43 |
|
|
44 |
1; |
|
45 |
|
|
46 |
__END__ |
|
47 |
|
|
48 |
=pod |
|
49 |
|
|
50 |
=encoding utf8 |
|
51 |
|
|
52 |
=head1 NAME |
|
53 |
|
|
54 |
SL::System::InstallationLock - Handle locking the installation with a |
|
55 |
global lock file |
|
56 |
|
|
57 |
=head1 SYNOPSIS |
|
58 |
|
|
59 |
SL::System::InstallationLock->lock; |
|
60 |
# Do important and uninterruptable work! |
|
61 |
SL::System::InstallationLock->unlock; |
|
62 |
|
|
63 |
|
|
64 |
=head1 OVERVIEW |
|
65 |
|
|
66 |
If the global lock file exists then no user may login. The |
|
67 |
administration area is not affected. |
|
68 |
|
|
69 |
There's a configuration setting |
|
70 |
C<debug.keep_installation_unlocked>. If it is trueish then all of |
|
71 |
these commands will always keep the installation unlocked: L</lock> |
|
72 |
and L</unlock> won't do anything and L</is_locked> always returns 0. |
|
73 |
|
|
74 |
=head1 FUNCTIONS |
|
75 |
|
|
76 |
=over 4 |
|
77 |
|
|
78 |
=item C<is_locked> |
|
79 |
|
|
80 |
Returns 1 or 0 depending on whether or not the installation is currently locked. |
|
81 |
|
|
82 |
=item C<lock> |
|
83 |
|
|
84 |
Creates the lock file. Throws an exception if writing to the lock file |
|
85 |
location fails. |
|
86 |
|
|
87 |
=item C<lock_file_name> |
|
88 |
|
|
89 |
Returns the file name for the global lock file. |
|
90 |
|
|
91 |
=item C<unlock> |
|
92 |
|
|
93 |
Removed the lock file. Throws an exception if the lock exists and |
|
94 |
removing the lock file fails. |
|
95 |
|
|
96 |
=back |
|
97 |
|
|
98 |
=head1 BUGS |
|
99 |
|
|
100 |
Nothing here yet. |
|
101 |
|
|
102 |
=head1 AUTHOR |
|
103 |
|
|
104 |
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt> |
|
105 |
|
|
106 |
=cut |
SL/User.pm | ||
---|---|---|
43 | 43 |
use SL::DBUtils; |
44 | 44 |
use SL::Iconv; |
45 | 45 |
use SL::Inifile; |
46 |
use SL::System::InstallationLock; |
|
46 | 47 |
|
47 | 48 |
use strict; |
48 | 49 |
|
... | ... | |
135 | 136 |
} |
136 | 137 |
|
137 | 138 |
# update the tables |
138 |
my $fh; |
|
139 |
if (!$::lx_office_conf{debug}->{keep_installation_unlocked} && !open($fh, ">", $::lx_office_conf{paths}->{userspath} . "/nologin")) { |
|
140 |
$form->show_generic_error($main::locale->text('A temporary file could not be created. ' . |
|
141 |
'Please verify that the directory "#1" is writeable by the webserver.', |
|
142 |
$::lx_office_conf{paths}->{userspath}), |
|
143 |
'back_button' => 1); |
|
144 |
} |
|
139 |
SL::System::InstallationLock->lock; |
|
145 | 140 |
|
146 | 141 |
# ignore HUP, QUIT in case the webserver times out |
147 | 142 |
$SIG{HUP} = 'IGNORE'; |
... | ... | |
151 | 146 |
$self->dbupdate2($form, $dbupdater); |
152 | 147 |
SL::DBUpgrade2->new(form => $::form, auth => 1)->apply_admin_dbupgrade_scripts(0); |
153 | 148 |
|
154 |
close($fh); |
|
155 |
|
|
156 |
# remove lock file |
|
157 |
unlink($::lx_office_conf{paths}->{userspath} . "/nologin"); |
|
149 |
SL::System::InstallationLock->unlock; |
|
158 | 150 |
|
159 | 151 |
print $form->parse_html_template("dbupgrade/footer"); |
160 | 152 |
|
locale/de/all | ||
---|---|---|
46 | 46 |
'A lower-case character is required.' => 'Ein Kleinbuchstabe ist vorgeschrieben.', |
47 | 47 |
'A special character is required (valid characters: #1).' => 'Ein Sonderzeichen ist vorgeschrieben (gültige Zeichen: #1).', |
48 | 48 |
'A temporary directory could not be created:' => 'Ein temporäres Verzeichnis konnte nicht erstellt werden:', |
49 |
'A temporary file could not be created. Please verify that the directory "#1" is writeable by the webserver.' => 'Eine temporäre Datei konnte nicht angelegt werden. Bitte stellen Sie sicher, dass das Verzeichnis "#1" vom Webserver beschrieben werden darf.', |
|
50 | 49 |
'A temporary file could not be created:' => 'Eine temporäre Datei konnte nicht erstellt werden:', |
51 | 50 |
'A unit with this name does already exist.' => 'Eine Einheit mit diesem Namen existiert bereits.', |
52 | 51 |
'A valid taxkey is missing!' => 'Einen gültiger Steuerschlüssel fehlt!', |
... | ... | |
372 | 371 |
'Cancel' => 'Abbrechen', |
373 | 372 |
'Cancel Accounts Payables Transaction' => 'Kreditorenbuchung stornieren', |
374 | 373 |
'Cancel Accounts Receivables Transaction' => 'Debitorenbuchung stornieren', |
375 |
'Cannot create Lock!' => 'System kann nicht gesperrt werden!', |
|
376 | 374 |
'Cannot delete account!' => 'Konto kann nicht gelöscht werden!', |
377 | 375 |
'Cannot delete customer!' => 'Kunde kann nicht gelöscht werden!', |
378 | 376 |
'Cannot delete default account!' => 'Das Standard-Konto kann nicht gelöscht werden!', |
... | ... | |
454 | 452 |
'Close Flash' => 'Schließen', |
455 | 453 |
'Close SEPA exports' => 'SEPA-Export abschließen', |
456 | 454 |
'Close Window' => 'Fenster Schließen', |
455 |
'Close window' => 'Fenster schließen', |
|
457 | 456 |
'Closed' => 'Geschlossen', |
458 | 457 |
'Collective Orders only work for orders from one customer!' => 'Sammelaufträge funktionieren nur für Aufträge von einem Kunden!', |
459 | 458 |
'Column name' => 'Spaltenname', |
... | ... | |
931 | 930 |
'Filter date by' => 'Datum filtern nach', |
932 | 931 |
'Filter for customer variables' => 'Filter für benutzerdefinierte Kundenvariablen', |
933 | 932 |
'Filter for item variables' => 'Filter für benutzerdefinierte Artikelvariablen', |
933 |
'Filter parts' => 'Artikel filtern', |
|
934 | 934 |
'Finish' => 'Abschließen', |
935 | 935 |
'First 20 Lines' => 'Nur erste 20 Datensätze', |
936 | 936 |
'Fix transaction' => 'Buchung korrigieren', |
... | ... | |
1213 | 1213 |
'Loading...' => 'Wird geladen...', |
1214 | 1214 |
'Local Tax Office Preferences' => 'Angaben zum Finanzamt', |
1215 | 1215 |
'Lock System' => 'System sperren', |
1216 |
'Lock file handling failed. Please verify that the directory "#1" is writeable by the webserver.' => 'Die Lockdateibehandlung schlug fehl. Bitte stellen Sie sicher, dass der Webserver das Verzeichnis "#1" beschreiben darf.', |
|
1216 | 1217 |
'Lockfile created!' => 'System gesperrt!', |
1217 | 1218 |
'Lockfile removed!' => 'System entsperrt!', |
1218 | 1219 |
'Login' => 'Anmelden', |
... | ... | |
1319 | 1320 |
'No Company Address given' => 'Keine Firmenadresse hinterlegt!', |
1320 | 1321 |
'No Company Name given' => 'Kein Firmenname hinterlegt!', |
1321 | 1322 |
'No Customer was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Endkunde gefunden', |
1322 |
'No Database Drivers available!' => 'Kein Datenbanktreiber verfügbar!', |
|
1323 | 1323 |
'No Dataset selected!' => 'Keine Datenbank ausgewählt!', |
1324 | 1324 |
'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden', |
1325 | 1325 |
'No action defined.' => 'Keine Aktion definiert.', |
... | ... | |
2369 | 2369 |
'Valid' => 'Gültig', |
2370 | 2370 |
'Valid from' => 'Gültig ab', |
2371 | 2371 |
'Valid until' => 'gültig bis', |
2372 |
'Valid/Obsolete' => 'Gültig/ungültig', |
|
2372 | 2373 |
'Value' => 'Wert', |
2373 | 2374 |
'Variable' => 'Variable', |
2374 | 2375 |
'Variable Description' => 'Datenfeldbezeichnung', |
Auch abrufbar als: Unified diff
Locking in eigenes Modul verschieben