source: trunk/LATMOS-Accounts/lib/LATMOS/Accounts/SyncManager.pm @ 1737

Last change on this file since 1737 was 1737, checked in by nanardon, 8 years ago

Add task modules

Add two task module:

  • Unexportexpired: unexported expire aliases and nethost
  • Updatedyndata: refresh aliases and group with autoMember settings
File size: 6.1 KB
Line 
1package LATMOS::Accounts::SyncManager;
2
3use strict;
4use warnings;
5use LATMOS::Accounts::Log;
6use LATMOS::Accounts;
7use Config::IniFiles;
8
9=head1 NAME
10
11LATMOS::Accounts::SyncManager - Routine task manager
12
13=head1 DESCRIPTION
14
15Handle Task process run by L<la-sync-manager>
16
17=head1 FUNCTIONS
18
19=cut
20
21=head2 new($config)
22
23Instaciate object.
24
25C<$config> is a path to an alternative configuration file to default one.
26
27=cut
28
29sub new {
30    my ($class, $config) = @_;
31
32    my $ini = Config::IniFiles->new(
33        -file => join('/', ($config || '/etc/latmos-accounts'),
34            'la-sync-manager.ini'),
35    ) or do {
36        la_log LA_ERR, "Cannot load config";
37        return;
38    };
39
40    foreach my $section (qw(basessynchro refreshexpired updatedyndata)) {
41        if ( !grep {
42            lc($ini->val($_, 'type', '')) eq $section
43            } $ini->Sections ) {
44            $ini->newval("_$section", 'type', $section);
45        }
46    }
47
48    bless {
49        ini => $ini,
50        config => $config,
51        lastrev => 0,
52    }, $class;
53}
54
55=head2 ini
56
57Return a reference to the L<Ini::Files> object handling configuration.
58
59=cut
60
61sub ini { $_[0]->{ini} }
62
63=head2 dbrev
64
65Return the current base revision
66
67=cut
68
69sub dbrev {
70    my ($self) = @_;
71    my $LA = LATMOS::Accounts->new($self->{config}, noacl => 1);
72    my $base = $LA->base;
73    return $base->current_rev;
74}
75
76sub _load_state_ini {
77    my ($self) = @_;
78    my $la = LATMOS::Accounts->new($self->{config}, noacl => 1);
79
80    my $state_file =  $la->val('_default_', 'state_dir', '/');
81    $state_file .= '/la-sync-manager.ini';
82    la_log(LA_DEBUG, "Status file is %s", $state_file);
83    if ($state_file && ! -w $state_file) {
84        # don't exists, we have to create it
85        open(my $handle, '>', $state_file) or do {
86            la_log(LA_ERR, "Cannot open build net status file %s",
87                $state_file);
88            return;
89        };
90        print $handle "[_default_]\n";
91        close($handle);
92    }
93    return Config::IniFiles->new(
94        -file => $state_file
95    );
96}
97
98=head2 get_last_rev($module)
99
100Return the last revision the module succeed
101
102=cut
103
104sub get_last_rev {
105    my ($self, $module) = @_;
106
107    my $ini = $self->_load_state_ini or return(0, 0);
108
109    return ($ini->val($module, 'rev', 0), $ini->val($module, 'time', 0));
110}
111
112=head2 list_modules
113
114List configured task module
115
116=cut
117
118sub list_modules {
119    my ($self) = @_;
120    $self->ini->Sections;
121}
122
123=head2 process_module($module)
124
125Process C<$module>.
126
127=cut
128
129# TODO what is $dbrev, why is it need here ??
130
131sub process_module {
132    my ($self, $module) = @_;
133
134    eval {
135        if (!$self->ini->SectionExists($module)) {
136            la_log LA_ERR, "Cannot run inexistant module %s", $module;
137            return;
138        }
139
140        my $modtype = $self->ini->val($module, 'type', $module);
141        my $task = LATMOS::Accounts::Task->new(
142            $modtype,
143            config => $self->{config},
144            name   => $module,
145            syncm  => $self,
146        )
147            or do {
148            la_log(LA_ERR, 'Cannot load module %s', $modtype);
149            return;
150        };
151        la_log LA_NOTICE, "Processing sync module %s (%s)", $module, $modtype;
152        if (!$task->init) {
153            la_log(LA_ERR, 'init() failed for module %s', $module);
154            return;
155        }
156
157        my ($lastrev, $lastRunTime) = $self->get_last_rev($module);
158        my $currentrev = $self->dbrev;
159        if (!$task->needupd($lastrev, $currentrev, $self)) {
160            la_log LA_DEBUG, "No change on main base, aborting";
161            return 1;
162        }
163
164        my $currentTime = time;
165
166        if ($currentTime < $lastRunTime + $task->runDelay) {
167            la_log LA_DEBUG, "Too short delay to run task, waiting";
168            return 1;
169        }
170
171        my $res = $task->run;
172        if (!$res) {
173            my $ini = $self->_load_state_ini or return;
174            $ini->newval($module, 'error', LATMOS::Accounts::Log::lastmessage());
175            la_log LA_ERR, "Task %s did not end successfully", $module;
176            $ini->RewriteConfig;
177        } else {
178            $task->post if ($res);
179            my $ini = $self->_load_state_ini or return;
180
181            $ini->delval($module, 'error');
182            $ini->newval($module, 'rev', $currentrev);
183            my $time = time;
184            $ini->newval($module, 'time', $time);
185            $ini->SetParameterComment(
186                $module, 'time',
187                scalar(localtime(time)),
188            );
189            $ini->RewriteConfig;
190
191            la_log LA_DEBUG, "end process $module";
192        }
193        return $res;
194    };
195
196    if ($@) {
197        la_log(LA_CRIT, 'Fatal Perl Error: %s', $@);
198        return;
199    } else {
200        return 1;
201    }
202}
203
204=head2 reset_module_savepoint($module)
205
206Reset the savepoint for module C<$module> to force it to run at next
207synchronisation.
208
209=cut
210
211sub reset_module_savepoint {
212    my ($self, $module) = @_;
213    if (!$self->ini->SectionExists($module)) {
214        la_log LA_ERR, "Cannot run inexistant module %s", $module;
215        return;
216    }
217
218    my $modtype = $self->ini->val($module, 'type', $module);
219    my $task = LATMOS::Accounts::Task->new(
220        $modtype,
221        config => $self->{config},
222        name   => $module,
223        syncm  => $self,
224    )
225        or do {
226        la_log(LA_ERR, 'Cannot load module %s', $modtype);
227        return;
228    };
229    $task->init or do {
230        la_log LA_ERR, "Cannot init module %s", $_;
231        return;
232    };
233
234    my $ini = $self->_load_state_ini or return;
235
236    $ini->delval($module, 'rev');
237    $ini->newval($module, 'time', 0);
238    $ini->SetParameterComment(
239        $module, 'time',
240        'Reset to 0 the ' . scalar(localtime(time)),
241    );
242
243    $task->reset_savepoint; # Specific reset
244    $ini->RewriteConfig;
245}
246
2471;
248
249__END__
250
251=head1 SEE ALSO
252
253L<LATMOS::Accountsi::Task>
254
255=head1 AUTHOR
256
257Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
258
259=head1 COPYRIGHT AND LICENSE
260
261Copyright (C) 2012 CNRS SA/CETP/LATMOS
262
263This library is free software; you can redistribute it and/or modify
264it under the same terms as Perl itself, either Perl version 5.10.0 or,
265at your option, any later version of Perl 5 you may have available.
266
267=cut
Note: See TracBrowser for help on using the repository browser.