=head1 LICENSE
Bweb - A Bacula web interface
- Bacula® - The Network Backup Solution
+ Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
The main author of Bweb is Eric Bollengier.
The main author of Bacula is Kern Sibbald, with contributions from
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Bacula® is a registered trademark of John Walker.
+ Bacula® is a registered trademark of John Walker.
The licensor of Bacula is the Free Software Foundation Europe
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
Switzerland, email:ftf@fsfeurope.org.
=head2 EXAMPLE
- $ref = { name => 'me', age => 26 };
+ $ref = { name => 'me', age => 26Â };
$self->display($ref, "people.tpl");
=cut
log_dir => qr!^(.+)?$!,
stat_job_table => qr!^(\w*)$!,
display_log_time => qr!^(on)?$!,
+ enable_security => qr/^(on)?$/,
+ enable_security_acl => qr/^(on)?$/,
);
=head1 FUNCTION
my ($self) = @_;
$self->{error} = '';
+ # we need to reset checkbox first
$self->{debug} = 0;
+ $self->{display_log_time} = 0;
+ $self->{enable_security} = 0;
+ $self->{enable_security_acl} = 0;
foreach my $k (CGI::param())
{
TO_SEC => " interval '1 second' * ",
SEC_TO_INT => "SEC_TO_INT",
SEC_TO_TIME => '',
- MATCH => " ~ ",
+ MATCH => " ~* ",
STARTTIME_DAY => " date_trunc('day', Job.StartTime) ",
STARTTIME_HOUR => " date_trunc('hour', Job.StartTime) ",
STARTTIME_MONTH => " date_trunc('month', Job.StartTime) ",
STARTTIME_PHOUR=> " date_part('hour', Job.StartTime) ",
STARTTIME_PDAY => " date_part('day', Job.StartTime) ",
STARTTIME_PMONTH => " date_part('month', Job.StartTime) ",
+ STARTTIME_PWEEK => " date_part('week', Job.StartTime) ",
DB_SIZE => " SELECT pg_database_size(current_database()) ",
+ CAT_POOL_TYPE => " MediaType || '_' || Pool.Name ",
+ CONCAT_SEP => "",
},
mysql => {
UNIX_TIMESTAMP => 'UNIX_TIMESTAMP',
STARTTIME_PHOUR=> " DATE_FORMAT(StartTime, '%H') ",
STARTTIME_PDAY => " DATE_FORMAT(StartTime, '%d') ",
STARTTIME_PMONTH => " DATE_FORMAT(StartTime, '%m') ",
+ STARTTIME_PWEEK => " DATE_FORMAT(StartTime, '%v') ",
# with mysql < 5, you have to play with the ugly SHOW command
DB_SIZE => " SELECT 0 ",
# works only with mysql 5
# DB_SIZE => " SELECT sum(DATA_LENGTH) FROM INFORMATION_SCHEMA.TABLES ",
+ CAT_POOL_TYPE => " CONCAT(MediaType,'_',Pool.Name) ",
+ CONCAT_SEP => " SEPARATOR '' ",
},
);
+sub dbh_is_mysql
+{
+ my ($self) = @_;
+ return $self->{info}->{dbi} =~ /dbi:mysql/i;
+}
+
sub dbh_disconnect
{
my ($self) = @_;
return $self->{dbh}->selectrow_hashref($query) ;
}
+sub dbh_strcat
+{
+ my ($self, @what) = @_;
+ if ($self->dbh_is_mysql()) {
+ return 'CONCAT(' . join(',', @what) . ')' ;
+ } else {
+ return join(' || ', @what);
+ }
+}
+
+sub dbh_prepare
+{
+ my ($self, $query) = @_;
+ $self->debug($query, up => 1);
+ return $self->{dbh}->prepare($query);
+}
+
# display Mb/Gb/Kb
sub human_size
{
- my @unit = qw(b Kb Mb Gb Tb);
+ my @unit = qw(B KB MB GB TB);
my $val = shift || 0;
my $i=0;
my $format = '%i %s';
return "$val years";
}
+# display Enabled
+sub human_enabled
+{
+ my $val = shift || 0;
+
+ if ($val eq '1' or $val eq "yes") {
+ return "yes";
+ } elsif ($val eq '2' or $val eq "archived") {
+ return "archived";
+ } else {
+ return "no";
+ }
+}
+
+# display Enabled
+sub from_human_enabled
+{
+ my $val = shift || 0;
+
+ if ($val == 1 or $val eq "yes") {
+ return 1;
+ } elsif ($val == 2 or $val eq "archived") {
+ return 2;
+ } else {
+ return 0;
+ }
+}
+
# get Day, Hour, Year
sub from_human_sec
{
my ($self) = @_;
unless ($self->{dbh}) {
+
$self->{dbh} = DBI->connect($self->{info}->{dbi},
$self->{info}->{user},
$self->{info}->{password});
$self->{dbh}->{FetchHashKeyName} = 'NAME_lc';
- if ($self->{info}->{dbi} =~ /^dbi:Pg/i) {
+ if ($self->dbh_is_mysql()) {
+ $self->{dbh}->do("SET group_concat_max_len=1000000");
+ } else {
$self->{dbh}->do("SET datestyle TO 'ISO, YMD'");
}
}
sub new
{
my ($class, %arg) = @_;
- my $self = bless {
+ my $self = bless ({
dbh => undef, # connect_db();
info => {
dbi => '', # DBI:Pg:database=bacula;host=127.0.0.1
user => 'bacula',
password => 'test',
},
- } ;
+ },$class) ;
map { $self->{lc($_)} = $arg{$_} } keys %arg ;
$self->{sql} = $sql_func{$1};
}
+ $self->{loginname} = CGI::remote_user();
$self->{debug} = $self->{info}->{debug};
$Bweb::Gui::template_dir = $self->{info}->{template_dir};
sub display_clients
{
my ($self) = @_;
+ my $where=''; # by default
- my $where='';
- my $arg = $self->get_form("client", "qre_client");
+ my $arg = $self->get_form("client", "qre_client",
+ "jclient_groups", "qnotingroup");
if ($arg->{qre_client}) {
$where = "WHERE Name $self->{sql}->{MATCH} $arg->{qre_client} ";
} elsif ($arg->{client}) {
$where = "WHERE Name = '$arg->{client}' ";
+ } elsif ($arg->{jclient_groups}) {
+ # $filter could already contains client_group_member
+ $where = "
+ JOIN client_group_member USING (ClientId)
+ JOIN client_group USING (client_group_id)
+ WHERE client_group_name IN ($arg->{jclient_groups}) ";
+ } elsif ($arg->{qnotingroup}) {
+ $where = "
+ WHERE NOT EXISTS
+ (SELECT 1 FROM client_group_member
+ WHERE Client.ClientId = client_group_member.ClientId
+ )
+";
}
my $query = "
AutoPrune AS autoprune,
FileRetention AS fileretention,
JobRetention AS jobretention
-FROM Client
-$where
-";
+FROM Client " . $self->get_client_filter() .
+$where ;
my $all = $self->dbh_selectall_hashref($query, 'name') ;
maxvoljobs => 0,
maxvolbytes => 0,
maxvolfiles => 0,
+ filenameid => 0,
+ pathid => 0,
);
my %opt_ss =( # string with space
type => 1,
poolrecycle => 1,
replace => 1,
- );
+ expired => 1,
+ enabled => 1,
+ username => 1,
+ rolename => 1,
+ );
my %opt_p = ( # option with path
fileset=> 1,
mtxcmd => 1,
if ($value =~ /^([\w\d\.\-\s]+)$/) {
$ret{$i} = $1;
}
- } elsif ($i =~ /^j(\w+)s$/) { # quote join args
+ } elsif ($i =~ /^j(\w+)s$/) { # quote join args "'arg1', 'arg2'"
my @value = grep { ! /^\s*$/ } CGI::param($1) ;
if (@value) {
$ret{$i} = $self->dbh_join(@value) ;
}
if ($what{db_clients}) {
+ my $filter='';
+ if ($what{filter}) {
+ # get security filter only if asked
+ $filter = $self->get_client_filter();
+ }
+
my $query = "
SELECT Client.Name as clientname
-FROM Client
+ FROM Client $filter
";
my $clients = $self->dbh_selectall_hashref($query, 'clientname');
values %$clients] ;
}
+ if ($what{db_client_groups}) {
+ my $filter='';
+ if ($what{filter}) {
+ # get security filter only if asked
+ $filter = $self->get_client_group_filter();
+ }
+
+ my $query = "
+SELECT client_group_name AS name
+ FROM client_group $filter
+";
+
+ my $grps = $self->dbh_selectall_hashref($query, 'name');
+ $ret{db_client_groups} = [sort {$a->{name} cmp $b->{name} }
+ values %$grps] ;
+ }
+
+ if ($what{db_usernames}) {
+ my $query = "
+SELECT username
+ FROM bweb_user
+";
+
+ my $users = $self->dbh_selectall_hashref($query, 'username');
+ $ret{db_usernames} = [sort {$a->{username} cmp $b->{username} }
+ values %$users] ;
+ }
+
+ if ($what{db_roles}) {
+ my $query = "
+SELECT rolename
+ FROM bweb_role
+";
+
+ my $r = $self->dbh_selectall_hashref($query, 'rolename');
+ $ret{db_roles} = [sort {$a->{rolename} cmp $b->{rolename} }
+ values %$r] ;
+ }
+
if ($what{db_mediatypes}) {
my $query = "
SELECT MediaType as mediatype
-FROM MediaType
+ FROM MediaType
";
- my $medias = $self->dbh_selectall_hashref($query, 'mediatype');
+ my $media = $self->dbh_selectall_hashref($query, 'mediatype');
$ret{db_mediatypes} = [sort {$a->{mediatype} cmp $b->{mediatype} }
- values %$medias] ;
+ values %$media] ;
}
if ($what{db_locations}) {
my $query = "
-SELECT Location as location, Cost as cost FROM Location
+SELECT Location as location, Cost as cost
+ FROM Location
";
my $loc = $self->dbh_selectall_hashref($query, 'location');
$ret{db_locations} = [ sort { $a->{location}
if ($what{db_filesets}) {
my $query = "
SELECT FileSet.FileSet AS fileset
-FROM FileSet
+ FROM FileSet
";
my $filesets = $self->dbh_selectall_hashref($query, 'fileset');
}
if ($what{db_jobnames}) {
+ my $filter='';
+ if ($what{filter}) {
+ $filter = " JOIN Client USING (ClientId) " . $self->get_client_filter();
+ }
my $query = "
SELECT DISTINCT Job.Name AS jobname
-FROM Job
+ FROM Job $filter
";
my $jobnames = $self->dbh_selectall_hashref($query, 'jobname');
if ($what{db_devices}) {
my $query = "
SELECT Device.Name AS name
-FROM Device
+ FROM Device
";
my $devices = $self->dbh_selectall_hashref($query, 'name');
my ($self) = @_;
my $fields = $self->get_form(qw/age level status clients filesets
- graph gtype type
- db_clients limit db_filesets width height
+ graph gtype type filter db_clients
+ limit db_filesets width height
qclients qfilesets qjobnames db_jobnames/);
}
-sub display_client_job
-{
- my ($self, %arg) = @_ ;
-
- $arg{order} = ' Job.JobId DESC ';
- my ($limit, $label) = $self->get_limit(%arg);
-
- my $clientname = $self->dbh_quote($arg{clientname});
-
- my $query="
-SELECT DISTINCT Job.JobId AS jobid,
- Job.Name AS jobname,
- FileSet.FileSet AS fileset,
- Level AS level,
- StartTime AS starttime,
- JobFiles AS jobfiles,
- JobBytes AS jobbytes,
- JobStatus AS jobstatus,
- JobErrors AS joberrors
-
- FROM Client,Job,FileSet
- WHERE Client.Name=$clientname
- AND Client.ClientId=Job.ClientId
- AND Job.FileSetId=FileSet.FileSetId
- $limit
-";
-
- my $all = $self->dbh_selectall_hashref($query, 'jobid') ;
-
- $self->display({ clientname => $arg{clientname},
- Filter => $label,
- ID => $cur_id++,
- Jobs => [ values %$all ],
- },
- "display_client_job.tpl") ;
-}
-
sub get_selected_media_location
{
my ($self) = @_ ;
- my $medias = $self->get_form('jmedias');
+ my $media = $self->get_form('jmedias');
- unless ($medias->{jmedias}) {
+ unless ($media->{jmedias}) {
return undef;
}
my $query = "
SELECT Media.VolumeName AS volumename, Location.Location AS location
FROM Media LEFT JOIN Location ON (Media.LocationId = Location.LocationId)
-WHERE Media.VolumeName IN ($medias->{jmedias})
+WHERE Media.VolumeName IN ($media->{jmedias})
";
my $all = $self->dbh_selectall_hashref($query, 'volumename') ;
sub move_media
{
- my ($self) = @_ ;
+ my ($self, $in) = @_ ;
- my $medias = $self->get_selected_media_location();
+ my $media = $self->get_selected_media_location();
- unless ($medias) {
+ unless ($media) {
return ;
}
-
+
my $elt = $self->get_form('db_locations');
$self->display({ ID => $cur_id++,
+ enabled => human_enabled($in),
%$elt, # db_locations
- medias => [
- sort { $a->{volumename} cmp $b->{volumename} } values %$medias
+ media => [
+ sort { $a->{volumename} cmp $b->{volumename} } values %$media
],
},
"move_media.tpl");
my $all = $self->dbh_selectall_hashref($query, 'volumename') ;
- $self->display({ Medias => [ values %$all ] },
+ $self->display({ Media => [ values %$all ] },
"help_extern_compute.tpl");
}
my $all = $self->dbh_selectall_hashref($query, 'volumename') ;
- $self->display({ Medias => [ values %$all ] },
+ $self->display({ Media => [ values %$all ] },
"help_intern_compute.tpl");
}
}
}
+ if ($elt{client_groups}) {
+ my @clients = grep { ! /^\s*$/ } CGI::param('client_group');
+ if (@clients) {
+ $ret{client_groups} = \@clients;
+ my $str = $self->dbh_join(@clients);
+ $limit .= "AND client_group_name IN ($str) ";
+ }
+ }
+
if ($elt{filesets}) {
my @filesets = grep { ! /^\s*$/ } CGI::param('fileset');
if (@filesets) {
}
if ($elt{mediatypes}) {
- my @medias = grep { ! /^\s*$/ } CGI::param('mediatype');
- if (@medias) {
- $ret{mediatypes} = \@medias;
- my $str = $self->dbh_join(@medias);
+ my @media = grep { ! /^\s*$/ } CGI::param('mediatype');
+ if (@media) {
+ $ret{mediatypes} = \@media;
+ my $str = $self->dbh_join(@media);
$limit .= "AND Media.MediaType IN ($str) ";
}
}
sub display_job
{
my ($self, %arg) = @_ ;
+ return if $self->cant_do('r_view_job');
$arg{order} = ' Job.JobId DESC ';
my ($limit, $label) = $self->get_limit(%arg);
my ($where, undef) = $self->get_param('clients',
+ 'client_groups',
'level',
'filesets',
'jobtype',
'pools',
'jobid',
'status');
+ my $cgq='';
+ if (CGI::param('client_group')) {
+ $cgq .= "
+JOIN client_group_member USING (ClientId)
+JOIN client_group USING (client_group_id)
+";
+ }
+ my $filter = $self->get_client_filter();
my $query="
SELECT Job.JobId AS jobid,
JobErrors AS joberrors
- FROM Client,
+ FROM Client $filter $cgq,
Job LEFT JOIN Pool ON (Job.PoolId = Pool.PoolId)
LEFT JOIN FileSet ON (Job.FileSetId = FileSet.FileSetId)
WHERE Client.ClientId=Job.ClientId
- AND Job.JobStatus != 'R'
+ AND Job.JobStatus NOT IN ('R', 'C')
$where
$limit
";
sub display_job_zoom
{
my ($self, $jobid) = @_ ;
+ $self->can_do('r_view_job');
$jobid = $self->dbh_quote($jobid);
-
+
+ # get security filter
+ my $filter = $self->get_client_filter();
+
my $query="
SELECT DISTINCT Job.JobId AS jobid,
Client.Name AS client,
$self->{sql}->{SEC_TO_TIME}( $self->{sql}->{UNIX_TIMESTAMP}(EndTime)
- $self->{sql}->{UNIX_TIMESTAMP}(StartTime)) AS duration
- FROM Client,
+ FROM Client $filter,
Job LEFT JOIN FileSet ON (Job.FileSetId = FileSet.FileSetId)
LEFT JOIN Pool ON (Job.PoolId = Pool.PoolId)
WHERE Client.ClientId=Job.ClientId
$self->display($row, "display_job_zoom.tpl");
}
+sub display_job_group
+{
+ my ($self, %arg) = @_;
+ $self->can_do('r_view_job');
+
+ my ($limit, $label) = $self->get_limit(groupby => 'client_group_name', %arg);
+
+ my ($where, undef) = $self->get_param('client_groups',
+ 'level',
+ 'pools');
+ my $filter = $self->get_client_group_filter();
+ my $query =
+"
+SELECT client_group_name AS client_group_name,
+ COALESCE(jobok.jobfiles,0) + COALESCE(joberr.jobfiles,0) AS jobfiles,
+ COALESCE(jobok.jobbytes,0) + COALESCE(joberr.jobbytes,0) AS jobbytes,
+ COALESCE(jobok.joberrors,0) + COALESCE(joberr.joberrors,0) AS joberrors,
+ COALESCE(jobok.nbjobs,0) AS nbjobok,
+ COALESCE(joberr.nbjobs,0) AS nbjoberr,
+ COALESCE(jobok.duration, '0:0:0') AS duration
+
+FROM client_group $filter LEFT JOIN (
+ SELECT client_group_name AS client_group_name, COUNT(1) AS nbjobs,
+ SUM(JobFiles) AS jobfiles, SUM(JobBytes) AS jobbytes,
+ SUM(JobErrors) AS joberrors,
+ SUM($self->{sql}->{SEC_TO_TIME}( $self->{sql}->{UNIX_TIMESTAMP}(EndTime)
+ - $self->{sql}->{UNIX_TIMESTAMP}(StartTime)))
+ AS duration
+
+ FROM Job JOIN client_group_member ON (Job.ClientId = client_group_member.ClientId)
+ JOIN client_group USING (client_group_id)
+
+ WHERE JobStatus = 'T'
+ $where
+ $limit
+) AS jobok USING (client_group_name) LEFT JOIN
+
+(
+ SELECT client_group_name AS client_group_name, COUNT(1) AS nbjobs,
+ SUM(JobFiles) AS jobfiles, SUM(JobBytes) AS jobbytes,
+ SUM(JobErrors) AS joberrors
+ FROM Job JOIN client_group_member ON (Job.ClientId = client_group_member.ClientId)
+ JOIN client_group USING (client_group_id)
+
+ WHERE JobStatus IN ('f','E', 'A')
+ $where
+ $limit
+) AS joberr USING (client_group_name)
+
+ ";
+
+ my $all = $self->dbh_selectall_hashref($query, 'client_group_name');
+
+ my $rep = { groups => [ values %$all ], age => $arg{age}, filter => $label };
+
+ $self->debug($rep);
+ $self->display($rep, "display_job_group.tpl");
+}
+
sub display_media
{
my ($self, %arg) = @_ ;
'volstatus',
'locations');
- my $arg = $self->get_form('jmedias', 'qre_media');
+ my $arg = $self->get_form('jmedias', 'qre_media', 'expired');
if ($arg->{jmedias}) {
$where = "AND Media.VolumeName IN ($arg->{jmedias}) $where";
if ($arg->{qre_media}) {
$where = "AND Media.VolumeName $self->{sql}->{MATCH} $arg->{qre_media} $where";
}
+ if ($arg->{expired}) {
+ $where = "
+ AND VolStatus = 'Full'
+ AND ( $self->{sql}->{UNIX_TIMESTAMP}(Media.LastWritten)
+ + $self->{sql}->{TO_SEC}(Media.VolRetention)
+ ) < NOW() " . $where ;
+ }
my $query="
SELECT Media.VolumeName AS volumename,
$self->display({ ID => $cur_id++,
Pool => $elt{pool},
Location => $elt{location},
- Medias => [ values %$all ]
+ Media => [ values %$all ],
},
"display_media.tpl");
}
-sub display_medias
+sub display_allmedia
{
my ($self) = @_ ;
{
my ($self) = @_ ;
- my $medias = $self->get_form('jmedias');
+ my $media = $self->get_form('jmedias');
- unless ($medias->{jmedias}) {
+ unless ($media->{jmedias}) {
return $self->error("Can't get media selection");
}
my $query="
SELECT InChanger AS online,
+ Media.Enabled AS enabled,
VolBytes AS nb_bytes,
VolumeName AS volumename,
VolStatus AS volstatus,
FROM Pool,
Media LEFT JOIN Location ON (Media.LocationId = Location.LocationId)
WHERE Pool.PoolId = Media.PoolId
- AND VolumeName IN ($medias->{jmedias})
+ AND VolumeName IN ($media->{jmedias})
";
my $all = $self->dbh_selectall_hashref($query, 'volumename') ;
sub location_edit
{
my ($self) = @_ ;
+ $self->can_do('r_location_mgnt');
my $loc = $self->get_form('qlocation');
unless ($loc->{qlocation}) {
";
my $row = $self->dbh_selectrow_hashref($query);
-
+ $row->{enabled} = human_enabled($row->{enabled});
$self->display({ ID => $cur_id++,
%$row }, "location_edit.tpl") ;
-
}
sub location_save
{
my ($self) = @_ ;
+ $self->can_do('r_location_mgnt');
- my $arg = $self->get_form(qw/qlocation qnewlocation cost/) ;
+ my $arg = $self->get_form(qw/qlocation qnewlocation cost enabled/) ;
unless ($arg->{qlocation}) {
return $self->error("Can't get location");
}
return $self->error("Can't get new cost");
}
- my $enabled = CGI::param('enabled') || '';
- $enabled = $enabled?1:0;
+ my $enabled = from_human_enabled($arg->{enabled});
my $query = "
UPDATE Location SET Cost = $arg->{cost},
$self->dbh_do($query);
- $self->display_location();
+ $self->location_display();
}
sub location_del
{
my ($self) = @_ ;
+ $self->can_do('r_location_mgnt');
+
my $arg = $self->get_form(qw/qlocation/) ;
unless ($arg->{qlocation}) {
}
$query = "
-DELETE FROM Location WHERE Location = $arg->{qlocation} LIMIT 1
+DELETE FROM Location WHERE Location = $arg->{qlocation}
";
$self->dbh_do($query);
- $self->display_location();
+ $self->location_display();
}
-
sub location_add
{
my ($self) = @_ ;
+ $self->can_do('r_location_mgnt');
+
my $arg = $self->get_form(qw/qlocation cost/) ;
unless ($arg->{qlocation}) {
$self->dbh_do($query);
- $self->display_location();
+ $self->location_display();
}
-sub display_location
+sub location_display
{
my ($self) = @_ ;
{
my ($self) = @_ ;
- my $medias = $self->get_selected_media_location();
- unless ($medias) {
+ my $media = $self->get_selected_media_location();
+ unless ($media) {
return ;
}
$self->display({ email => $self->{info}->{email_media},
%$arg,
- medias => [ values %$medias ],
+ media => [ values %$media ],
},
"update_location.tpl");
}
+###########################################################
+
+sub groups_edit
+{
+ my ($self) = @_;
+ $self->can_do('r_group_mgnt');
+
+ my $grp = $self->get_form(qw/qclient_group db_clients/);
+
+ unless ($grp->{qclient_group}) {
+ $self->display({ ID => $cur_id++,
+ client_group => "''",
+ %$grp,
+ }, "groups_edit.tpl");
+ return;
+ }
+
+ my $query = "
+SELECT Name AS name
+ FROM Client JOIN client_group_member using (clientid)
+ JOIN client_group using (client_group_id)
+WHERE client_group_name = $grp->{qclient_group}
+";
+
+ my $row = $self->dbh_selectall_hashref($query, "name");
+ $self->debug($row);
+ $self->display({ ID => $cur_id++,
+ client_group => $grp->{qclient_group},
+ %$grp,
+ client_group_member => [ values %$row]},
+ "groups_edit.tpl");
+}
+
+sub groups_save
+{
+ my ($self) = @_;
+ $self->can_do('r_group_mgnt');
+
+ my $arg = $self->get_form(qw/qclient_group jclients qnewgroup/);
+
+ if (!$arg->{qclient_group} and $arg->{qnewgroup}) {
+ my $query = "
+INSERT INTO client_group (client_group_name)
+VALUES ($arg->{qnewgroup})
+";
+ $self->dbh_do($query);
+ $arg->{qclient_group} = $arg->{qnewgroup};
+ }
+
+ unless ($arg->{qclient_group}) {
+ return $self->error("Can't get groups");
+ }
+
+ $self->{dbh}->begin_work();
+
+ my $query = "
+DELETE FROM client_group_member
+ WHERE client_group_id IN
+ (SELECT client_group_id
+ FROM client_group
+ WHERE client_group_name = $arg->{qclient_group})
+";
+ $self->dbh_do($query);
+
+ $query = "
+ INSERT INTO client_group_member (clientid, client_group_id)
+ (SELECT Clientid,
+ (SELECT client_group_id
+ FROM client_group
+ WHERE client_group_name = $arg->{qclient_group})
+ FROM Client WHERE Name IN ($arg->{jclients})
+ )
+";
+ $self->dbh_do($query);
+
+ if ($arg->{qclient_group} ne $arg->{qnewgroup}) {
+ $query = "
+UPDATE client_group
+ SET client_group_name = $arg->{qnewgroup}
+ WHERE client_group_name = $arg->{qclient_group}
+";
+
+ $self->dbh_do($query);
+ }
+
+ $self->{dbh}->commit() or $self->error($self->{dbh}->errstr);
+
+ $self->display_groups();
+}
+
+sub groups_del
+{
+ my ($self) = @_;
+ $self->can_do('r_group_mgnt');
+
+ my $arg = $self->get_form(qw/qclient_group/);
+
+ unless ($arg->{qclient_group}) {
+ return $self->error("Can't get groups");
+ }
+
+ $self->{dbh}->begin_work();
+
+ my $query = "
+DELETE FROM client_group_member
+ WHERE client_group_id IN
+ (SELECT client_group_id
+ FROM client_group
+ WHERE client_group_name = $arg->{qclient_group});
+
+DELETE FROM bweb_client_group_acl
+ WHERE client_group_id IN
+ (SELECT client_group_id
+ FROM client_group
+ WHERE client_group_name = $arg->{qclient_group});
+
+DELETE FROM client_group
+ WHERE client_group_name = $arg->{qclient_group};
+";
+ $self->dbh_do($query);
+
+ $self->{dbh}->commit();
+
+ $self->display_groups();
+}
+
+sub display_groups
+{
+ my ($self) = @_;
+
+ my $arg = $self->get_form(qw/db_client_groups/) ;
+
+ if ($self->{dbh}->errstr) {
+ return $self->error("Can't use groups with bweb, read INSTALL to enable them");
+ }
+
+ $self->debug($arg);
+
+ $self->display({ ID => $cur_id++,
+ %$arg},
+ "display_groups.tpl");
+}
+
+###########################################################
+
+sub get_roles
+{
+ my ($self) = @_;
+ if (not $self->{info}->{enable_security}) {
+ return 1;
+ }
+ # admin is a special user that can do everything
+ if ($self->{loginname} eq 'admin') {
+ return 1;
+ }
+ if (!$self->{loginname}) {
+ return 0;
+ }
+ # already fill
+ if (defined $self->{security}) {
+ return 1;
+ }
+ $self->{security} = {};
+ my $u = $self->dbh_quote($self->{loginname});
+
+ my $query = "
+ SELECT use_acl, rolename
+ FROM bweb_user
+ JOIN bweb_role_member USING (userid)
+ JOIN bweb_role USING (roleid)
+ WHERE username = $u
+";
+ my $rows = $self->dbh_selectall_arrayref($query);
+ # do cache with this role
+ if (!$rows) {
+ return 0;
+ }
+ foreach my $r (@$rows) {
+ $self->{security}->{$r->[1]}=1;
+ }
+
+ $self->{security}->{use_acl} = $rows->[0]->[0];
+ return 1;
+}
+
+sub cant_do
+{
+ my ($self, $action) = @_;
+ # is security enabled in configuration ?
+ if (not $self->{info}->{enable_security}) {
+ return 0
+ }
+ # admin is a special user that can do everything
+ if ($self->{loginname} eq 'admin') {
+ return 0;
+ }
+ # must be logged
+ if (!$self->{loginname}) {
+ $self->{error} = "Can't do $action, your are not logged. " .
+ "Check security with your administrator";
+ return 1;
+ }
+ $self->get_roles();
+ if (!$self->{security}->{$action}) {
+ $self->{error} =
+ "$self->{loginname} sorry, but this action ($action) " .
+ "is not permited. " .
+ "Check security with your administrator";
+ return 1;
+ }
+ return 0;
+}
+
+# make like an assert (program die)
+sub can_do
+{
+ my ($self, $action) = @_;
+ if ($self->cant_do($action)) {
+ $self->error($self->{error});
+ $self->display_end();
+ exit 0;
+ }
+ return 1;
+}
+
+sub use_filter
+{
+ my ($self) = @_;
+
+ if (!$self->{info}->{enable_security} or
+ !$self->{info}->{enable_security_acl})
+ {
+ return 0 ;
+ }
+
+ if ($self->get_roles()) {
+ return $self->{security}->{use_acl};
+ } else {
+ return 0;
+ }
+}
+
+# JOIN Client USING (ClientId) " . $b->get_client_filter() . "
+sub get_client_filter
+{
+ my ($self, $login) = @_;
+ my $u;
+ if ($login) {
+ $u = $self->dbh_quote($login);
+ } elsif ($self->use_filter()) {
+ $u = $self->dbh_quote($self->{loginname});
+ } else {
+ return '';
+ }
+ return "
+ JOIN (SELECT ClientId FROM client_group_member
+ JOIN client_group USING (client_group_id)
+ JOIN bweb_client_group_acl USING (client_group_id)
+ JOIN bweb_user USING (userid)
+ WHERE bweb_user.username = $u
+ ) AS filter USING (ClientId)";
+}
+
+#JOIN client_group USING (client_group_id)" . $b->get_client_group_filter()
+sub get_client_group_filter
+{
+ my ($self, $login) = @_;
+ my $u;
+ if ($login) {
+ $u = $self->dbh_quote($login);
+ } elsif ($self->use_filter()) {
+ $u = $self->dbh_quote($self->{loginname});
+ } else {
+ return '';
+ }
+ return "
+ JOIN (SELECT client_group_id
+ FROM bweb_client_group_acl
+ JOIN bweb_user USING (userid)
+ WHERE bweb_user.username = $u
+ ) AS filter USING (client_group_id)";
+}
+
+# role and username have to be quoted before
+# role and username can be a quoted list
+sub revoke
+{
+ my ($self, $role, $username) = @_;
+ $self->can_do("r_user_mgnt");
+
+ my $nb = $self->dbh_do("
+ DELETE FROM bweb_role_member
+ WHERE roleid = (SELECT roleid FROM bweb_role
+ WHERE rolename IN ($role))
+ AND userid = (SELECT userid FROM bweb_user
+ WHERE username IN ($username))");
+ return $nb;
+}
+
+# role and username have to be quoted before
+# role and username can be a quoted list
+sub grant
+{
+ my ($self, $role, $username) = @_;
+ $self->can_do("r_user_mgnt");
+
+ my $nb = $self->dbh_do("
+ INSERT INTO bweb_role_member (roleid, userid)
+ SELECT roleid, userid FROM bweb_role, bweb_user
+ WHERE rolename IN ($role)
+ AND username IN ($username)
+ ");
+ return $nb;
+}
+
+# role and username have to be quoted before
+# role and username can be a quoted list
+sub grant_like
+{
+ my ($self, $copy, $user) = @_;
+ $self->can_do("r_user_mgnt");
+
+ my $nb = $self->dbh_do("
+ INSERT INTO bweb_role_member (roleid, userid)
+ SELECT roleid, a.userid
+ FROM bweb_user AS a, bweb_role_member
+ JOIN bweb_user USING (userid)
+ WHERE bweb_user.username = $copy
+ AND a.username = $user");
+ return $nb;
+}
+
+# username can be a join quoted list of usernames
+sub revoke_all
+{
+ my ($self, $username) = @_;
+ $self->can_do("r_user_mgnt");
+
+ $self->dbh_do("
+ DELETE FROM bweb_role_member
+ WHERE userid IN (
+ SELECT userid
+ FROM bweb_user
+ WHERE username in ($username))");
+ $self->dbh_do("
+DELETE FROM bweb_client_group_acl
+ WHERE userid IN (
+ SELECT userid
+ FROM bweb_user
+ WHERE username IN ($username))");
+
+}
+
+sub users_del
+{
+ my ($self) = @_;
+ $self->can_do("r_user_mgnt");
+
+ my $arg = $self->get_form(qw/jusernames/);
+
+ unless ($arg->{jusernames}) {
+ return $self->error("Can't get user");
+ }
+
+ $self->{dbh}->begin_work();
+ {
+ $self->revoke_all($arg->{jusernames});
+ $self->dbh_do("
+DELETE FROM bweb_user WHERE username IN ($arg->{jusernames})");
+ }
+ $self->{dbh}->commit();
+
+ $self->display_users();
+}
+
+sub users_add
+{
+ my ($self) = @_;
+ $self->can_do("r_user_mgnt");
+
+ # we don't quote username directly to check that it is conform
+ my $arg = $self->get_form(qw/username qpasswd qcomment jrolenames qcreate qcopy_username jclient_groups/) ;
+
+ if (not $arg->{qcreate}) {
+ $arg = $self->get_form(qw/db_roles db_usernames db_client_groups/);
+ $self->display($arg, "display_user.tpl");
+ return 1;
+ }
+
+ my $u = $self->dbh_quote($arg->{username});
+
+ $arg->{use_acl}=(CGI::param('use_acl')?'true':'false');
+
+ if (!$arg->{qpasswd}) {
+ $arg->{qpasswd} = "''";
+ }
+ if (!$arg->{qcomment}) {
+ $arg->{qcomment} = "''";
+ }
+
+ # will fail if user already exists
+ # UPDATE with mysql dbi does not return if update is ok
+ ($self->dbh_do("
+ UPDATE bweb_user
+ SET passwd=$arg->{qpasswd}, comment=$arg->{qcomment},
+ use_acl=$arg->{use_acl}
+ WHERE username = $u")
+# and (! $self->dbh_is_mysql() )
+ ) and
+ $self->dbh_do("
+ INSERT INTO bweb_user (username, passwd, use_acl, comment)
+ VALUES ($u, $arg->{qpasswd}, $arg->{use_acl}, $arg->{qcomment})");
+
+ $self->{dbh}->begin_work();
+ {
+ $self->revoke_all($u);
+
+ if ($arg->{qcopy_username}) {
+ $self->grant_like($arg->{qcopy_username}, $u);
+ } else {
+ $self->grant($arg->{jrolenames}, $u);
+ }
+
+ if ($arg->{jclient_groups}) {
+ $self->dbh_do("
+INSERT INTO bweb_client_group_acl (client_group_id, userid)
+ SELECT client_group_id, userid
+ FROM client_group, bweb_user
+ WHERE client_group_name IN ($arg->{jclient_groups})
+ AND username = $u
+");
+ }
+ }
+ $self->{dbh}->commit();
+
+ $self->display_users();
+}
+
+# TODO: we miss a matrix with all user/roles
+sub display_users
+{
+ my ($self) = @_;
+ $self->can_do("r_user_mgnt");
+
+ my $arg = $self->get_form(qw/db_usernames/) ;
+
+ if ($self->{dbh}->errstr) {
+ return $self->error("Can't use users with bweb, read INSTALL to enable them");
+ }
+
+ $self->display({ ID => $cur_id++,
+ %$arg},
+ "display_users.tpl");
+}
+
+sub display_user
+{
+ my ($self) = @_;
+ $self->can_do("r_user_mgnt");
+
+ my $arg = $self->get_form('username');
+ my $user = $self->dbh_quote($arg->{username});
+
+ my $userp = $self->dbh_selectrow_hashref("
+ SELECT username, passwd, comment, use_acl
+ FROM bweb_user
+ WHERE username = $user
+");
+ if (!$userp) {
+ return $self->error("Can't find $user in catalog");
+ }
+ my $filter = $self->get_client_group_filter($arg->{username});
+ my $scg = $self->dbh_selectall_hashref("
+ SELECT client_group_name AS name
+ FROM client_group $filter
+", 'name');
+
+# rolename | userid
+#------------+--------
+# cancel_job |
+# restore |
+# run_job | 1
+
+ my $role = $self->dbh_selectall_hashref("
+SELECT rolename, temp.userid
+ FROM bweb_role
+ LEFT JOIN (SELECT roleid, userid
+ FROM bweb_user JOIN bweb_role_member USING (userid)
+ WHERE username = $user) AS temp USING (roleid)
+ORDER BY rolename
+", 'rolename');
+
+ $arg = $self->get_form(qw/db_usernames db_client_groups/);
+
+ $self->display({
+ db_usernames => $arg->{db_usernames},
+ username => $userp->{username},
+ comment => $userp->{comment},
+ passwd => $userp->{passwd},
+ use_acl => $userp->{use_acl},
+ db_client_groups => $arg->{db_client_groups},
+ client_group => [ values %$scg ],
+ db_roles => [ values %$role],
+ }, "display_user.tpl");
+}
+
+
+###########################################################
+
sub get_media_max_size
{
my ($self, $type) = @_;
Media.VolUseDuration AS voluseduration,
Media.VolRetention AS volretention,
Media.Comment AS comment,
- PoolRecycle.Name AS poolrecycle
+ PoolRecycle.Name AS poolrecycle,
+ Media.Enabled AS enabled
FROM Media INNER JOIN Pool AS PoolMedia ON (Media.PoolId = PoolMedia.PoolId)
LEFT JOIN Pool AS PoolRecycle ON (Media.RecyclePoolId = PoolRecycle.PoolId)
my $row = $self->dbh_selectrow_hashref($query);
$row->{volretention} = human_sec($row->{volretention});
$row->{voluseduration} = human_sec($row->{voluseduration});
+ $row->{enabled} = human_enabled($row->{enabled});
my $elt = $self->get_form(qw/db_pools db_locations/);
sub save_location
{
my ($self) = @_ ;
+ $self->can_do('r_media_mgnt');
my $arg = $self->get_form('jmedias', 'qnewlocation') ;
$self->display_media();
}
-sub change_location
+sub location_change
{
my ($self) = @_ ;
+ $self->can_do('r_media_mgnt');
- my $medias = $self->get_selected_media_location();
- unless ($medias) {
+ my $media = $self->get_selected_media_location();
+ unless ($media) {
return $self->error("Can't get media selection");
}
my $newloc = CGI::param('newlocation');
my $comm = CGI::param('comment') || '';
$comm = $self->dbh_quote("$user: $comm");
- my $query;
+ my $arg = $self->get_form('enabled');
+ my $en = human_enabled($arg->{enabled});
+ my $b = $self->get_bconsole();
- foreach my $media (keys %$medias) {
+ my $query;
+ foreach my $vol (keys %$media) {
$query = "
INSERT LocationLog (Date, Comment, MediaId, LocationId, NewVolStatus)
VALUES(
- NOW(), $comm, (SELECT MediaId FROM Media WHERE VolumeName = '$media'),
- (SELECT LocationId FROM Location WHERE Location = '$medias->{$media}->{location}'),
- (SELECT VolStatus FROM Media WHERE VolumeName = '$media')
+ NOW(), $comm, (SELECT MediaId FROM Media WHERE VolumeName = '$vol'),
+ (SELECT LocationId FROM Location WHERE Location = '$media->{$vol}->{location}'),
+ (SELECT VolStatus FROM Media WHERE VolumeName = '$vol')
)
";
$self->dbh_do($query);
$self->debug($query);
+ $b->send_cmd("update volume=\"$vol\" enabled=$en");
}
+ $b->close();
my $q = new CGI;
$q->param('action', 'update_location');
$self->display({ email => $self->{info}->{email_media},
url => $url,
newlocation => $newloc,
- # [ { volumename => 'vol1' }, { volumename => 'vol2'\81\81 },..]
- medias => [ values %$medias ],
+ # [ { volumename => 'vol1' }, { volumename => 'vol2'},..]
+ media => [ values %$media ],
},
"change_location.tpl");
sub display_client_stats
{
my ($self, %arg) = @_ ;
+ $self->can_do('r_view_stat');
my $client = $self->dbh_quote($arg{clientname});
- my ($limit, $label) = $self->get_limit(%arg);
+ # get security filter
+ my $filter = $self->get_client_filter();
+ my ($limit, $label) = $self->get_limit(%arg);
my $query = "
SELECT
count(Job.JobId) AS nb_jobs,
sum(Job.JobErrors) AS nb_err,
sum(Job.JobFiles) AS nb_files,
Client.Name AS clientname
-FROM Job INNER JOIN Client USING (ClientId)
+FROM Job JOIN Client USING (ClientId) $filter
WHERE
Client.Name = $client
$limit
$row->{ID} = $cur_id++;
$row->{label} = $label;
+ $row->{grapharg} = "client";
+
+ $self->display($row, "display_client_stats.tpl");
+}
+
+
+sub display_group_stats
+{
+ my ($self, %arg) = @_ ;
+
+ my $carg = $self->get_form(qw/qclient_group/);
+
+ unless ($carg->{qclient_group}) {
+ return $self->error("Can't get group");
+ }
+
+ my ($limit, $label) = $self->get_limit(%arg);
+
+ my $query = "
+SELECT
+ count(Job.JobId) AS nb_jobs,
+ sum(Job.JobBytes) AS nb_bytes,
+ sum(Job.JobErrors) AS nb_err,
+ sum(Job.JobFiles) AS nb_files,
+ client_group.client_group_name AS clientname
+FROM Job JOIN Client USING (ClientId)
+ JOIN client_group_member ON (Client.ClientId = client_group_member.clientid)
+ JOIN client_group USING (client_group_id)
+WHERE
+ client_group.client_group_name = $carg->{qclient_group}
+ $limit
+GROUP BY client_group.client_group_name
+";
+
+ my $row = $self->dbh_selectrow_hashref($query);
+
+ $row->{ID} = $cur_id++;
+ $row->{label} = $label;
+ $row->{grapharg} = "client_group";
$self->display($row, "display_client_stats.tpl");
}
my $whereW = '';
my $arg = $self->get_form('jmediatypes', 'qmediatypes');
- if ($arg->{jmediatypes}) {
+ if ($arg->{jmediatypes}) {
$whereW = "WHERE MediaType IN ($arg->{jmediatypes}) ";
$whereA = "AND MediaType IN ($arg->{jmediatypes}) ";
}
Pool.MaxVolJobs AS maxvoljobs,
Pool.MaxVolFiles AS maxvolfiles,
Pool.MaxVolBytes AS maxvolbytes,
- subq.PoolId AS PoolId
+ subq.PoolId AS PoolId,
+ subq.MediaType AS mediatype,
+ $self->{sql}->{CAT_POOL_TYPE} AS uniq
FROM
(
SELECT COALESCE(media_avg_size.volavg,0) * count(Media.MediaId) AS volmax,
$whereW
";
- my $all = $self->dbh_selectall_hashref($query, 'name') ;
+ my $all = $self->dbh_selectall_hashref($query, 'uniq') ;
$query = "
SELECT Pool.Name AS name,
$query = "
SELECT VolStatus AS volstatus, count(MediaId) AS nb
FROM Media
- WHERE PoolId=$p->{poolid}
+ WHERE PoolId=$p->{poolid}
+ AND Media.MediaType = '$p->{mediatype}'
$whereA
GROUP BY VolStatus
";
sub display_running_job
{
my ($self) = @_;
+ return if $self->cant_do('r_view_running_job');
my $arg = $self->get_form('client', 'jobid');
if (!$arg->{client} and $arg->{jobid}) {
+ # get security filter
+ my $filter = $self->get_client_filter();
my $query = "
SELECT Client.Name AS name
-FROM Job INNER JOIN Client USING (ClientId)
+FROM Job INNER JOIN Client USING (ClientId) $filter
WHERE Job.JobId = $arg->{jobid}
";
sub display_running_jobs
{
my ($self, $display_action) = @_;
-
+ return if $self->cant_do('r_view_running_job');
+
+ # get security filter
+ my $filter = $self->get_client_filter();
+
my $query = "
SELECT Job.JobId AS jobid,
Job.Name AS jobname,
- $self->{sql}->{UNIX_TIMESTAMP}(StartTime))
AS duration,
Client.Name AS clientname
-FROM Job INNER JOIN Client USING (ClientId)
-WHERE JobStatus IN ('C','R','B','e','D','F','S','m','M','s','j','c','d','t','p')
+FROM Job INNER JOIN Client USING (ClientId) $filter
+WHERE
+ JobStatus IN ('C','R','B','e','D','F','S','m','M','s','j','c','d','t','p')
";
my $all = $self->dbh_selectall_hashref($query, 'jobid') ;
sub eject_media
{
my ($self) = @_;
+ $self->can_do('r_media_mgnt');
+
my %ret;
my $arg = $self->get_form('jmedias');
$a->status();
$a->{have_status} = 1;
}
-
+ # TODO: set enabled
print "eject $vol->{volumename} from $vol->{storage} : ";
if ($a->send_to_io($vol->{slot})) {
print "<img src='/bweb/T.png' alt='ok'><br/>";
sub ach_register
{
my ($self, $ach) = @_;
+ $self->can_do('r_configure');
$self->{info}->{ach_list}->{$ach->{name}} = $ach;
sub ach_edit
{
my ($self) = @_;
+ $self->can_do('r_configure');
+
my $arg = $self->get_form('ach');
if (!$arg->{ach}
or !$self->{info}->{ach_list}
sub ach_del
{
my ($self) = @_;
+ $self->can_do('r_configure');
+
my $arg = $self->get_form('ach');
if (!$arg->{ach}
sub ach_add
{
my ($self) = @_;
+ $self->can_do('r_configure');
+
my $arg = $self->get_form('ach', 'mtxcmd', 'device', 'precmd');
my $b = $self->get_bconsole();
sub delete
{
my ($self) = @_;
+ $self->can_do('r_delete_job');
+
my $arg = $self->get_form('jobid');
if ($arg->{jobid}) {
sub do_update_media
{
my ($self) = @_ ;
+ $self->can_do('r_media_mgnt');
my $arg = $self->get_form(qw/media volstatus inchanger pool
slot volretention voluseduration
maxvoljobs maxvolfiles maxvolbytes
- qcomment poolrecycle
+ qcomment poolrecycle enabled
/);
unless ($arg->{media}) {
$update .= " slot=0 inchanger=no ";
}
+ if ($arg->{enabled}) {
+ $update .= " enabled=$arg->{enabled} ";
+ }
+
if ($arg->{pool}) {
$update .= " pool=$arg->{pool} " ;
}
$update .= " maxvolbytes=$arg->{maxvolbytes} " ;
}
+ if (defined $arg->{poolrecycle}) {
+ $update .= " recyclepool=\"$arg->{poolrecycle}\" " ;
+ }
+
my $b = $self->get_bconsole();
$self->display({
$loc = $self->dbh_quote($loc); # is checked by db
push @q, "LocationId=(SELECT LocationId FROM Location WHERE Location=$loc)";
}
- if ($arg->{poolrecycle}) {
- push @q, "RecyclePoolId=(SELECT PoolId FROM Pool WHERE Name='$arg->{poolrecycle}')";
- }
if (!$arg->{qcomment}) {
$arg->{qcomment} = "''";
}
sub update_slots
{
my ($self) = @_;
+ $self->can_do('r_autochanger_mgnt');
my $ach = CGI::param('ach') ;
$ach = $self->ach_get($ach);
sub get_job_log
{
my ($self) = @_;
+ $self->can_do('r_view_log');
my $arg = $self->get_form('jobid', 'limit', 'offset');
unless ($arg->{jobid}) {
if ($arg->{limit} == 100) {
$arg->{limit} = 1000;
}
-
- my $t = CGI::param('time') || $self->{info}->{display_log_time} || '';
+ # get security filter
+ my $filter = $self->get_client_filter();
my $query = "
SELECT Job.Name as name, Client.Name as clientname
- FROM Job INNER JOIN Client ON (Job.ClientId = Client.ClientId)
+ FROM Job INNER JOIN Client USING (ClientId) $filter
WHERE JobId = $arg->{jobid}
";
return $self->error("Can't find $arg->{jobid} in catalog");
}
+ # display only Error and Warning messages
+ $filter = '';
+ if (CGI::param('error')) {
+ $filter = " AND LogText $self->{sql}->{MATCH} 'Error|Warning' ";
+ }
+
+ my $logtext;
+ if (CGI::param('time') || $self->{info}->{display_log_time}) {
+ $logtext = $self->dbh_strcat('Time', " ' ' ", 'LogText');
+ } else {
+ $logtext = 'LogText';
+ }
+
$query = "
-SELECT Time AS time, LogText AS log
- FROM Log
- WHERE Log.JobId = $arg->{jobid}
- OR (Log.JobId = 0 AND Time >= (SELECT StartTime FROM Job WHERE JobId=$arg->{jobid})
- AND Time <= (SELECT COALESCE(EndTime,NOW()) FROM Job WHERE JobId=$arg->{jobid})
- )
+SELECT count(1) AS nbline, JobId AS jobid,
+ GROUP_CONCAT($logtext $self->{sql}->{CONCAT_SEP}) AS logtxt
+ FROM (
+ SELECT JobId, Time, LogText
+ FROM Log
+ WHERE ( Log.JobId = $arg->{jobid}
+ OR (Log.JobId = 0
+ AND Time >= (SELECT StartTime FROM Job WHERE JobId=$arg->{jobid})
+ AND Time <= (SELECT COALESCE(EndTime,NOW()) FROM Job WHERE JobId=$arg->{jobid})
+ ) ) $filter
ORDER BY LogId
LIMIT $arg->{limit}
OFFSET $arg->{offset}
+ ) AS temp
+ GROUP BY JobId
+
";
- my $log = $self->dbh_selectall_arrayref($query);
+ my $log = $self->dbh_selectrow_hashref($query);
unless ($log) {
return $self->error("Can't get log for jobid $arg->{jobid}");
}
- my $logtxt;
- if ($t) {
- # log contains \n
- $logtxt = join("", map { ($_->[0] . ' ' . $_->[1]) } @$log ) ;
- } else {
- $logtxt = join("", map { $_->[1] } @$log ) ;
- }
-
- $self->display({ lines=> $logtxt,
+ $self->display({ lines=> $log->{logtxt},
+ nbline => $log->{nbline},
jobid => $arg->{jobid},
name => $row->{name},
client => $row->{clientname},
}, 'display_log.tpl');
}
-
sub label_barcodes
{
my ($self) = @_ ;
+ $self->can_do('r_autochanger_mgnt');
my $arg = $self->get_form('ach', 'slots', 'drive');
}
my $slots = '';
+ my $slots_sql = '';
my $t = 300 ;
if ($arg->{slots}) {
$slots = join(",", @{ $arg->{slots} });
+ $slots_sql = " AND Slot IN ($slots) ";
$t += 60*scalar( @{ $arg->{slots} }) ;
}
UPDATE Media
SET LocationId = (SELECT LocationId
FROM Location
- WHERE Location = '$arg->{ach}'),
-
- RecyclePoolId = PoolId
+ WHERE Location = '$arg->{ach}')
- WHERE Media.PoolId = (SELECT PoolId
- FROM Pool
- WHERE Name = 'Scratch')
- AND (LocationId = 0 OR LocationId IS NULL)
+ WHERE (LocationId = 0 OR LocationId IS NULL)
+ $slots_sql
");
}
sub purge
{
my ($self) = @_;
+ $self->can_do('r_purge');
my @volume = CGI::param('media');
my $b = new Bconsole(pref => $self->{info}, timeout => 60);
- $self->display({
- content => $b->purge_volume(@volume),
- title => "Purge media",
- name => "purge volume=" . join(' volume=', @volume),
- }, "command.tpl");
+ foreach my $v (@volume) {
+ $self->display({
+ content => $b->purge_volume($v),
+ title => "Purge media",
+ name => "purge volume=$v",
+ }, "command.tpl");
+ }
$b->close();
}
sub prune
{
my ($self) = @_;
+ $self->can_do('r_prune');
my @volume = CGI::param('media');
unless (@volume) {
my $b = new Bconsole(pref => $self->{info}, timeout => 60);
- $self->display({
- content => $b->prune_volume(@volume),
- title => "Prune media",
- name => "prune volume=" . join(' volume=', @volume),
- }, "command.tpl");
-
+ foreach my $v (@volume) {
+ $self->display({
+ content => $b->prune_volume($v),
+ title => "Prune volume",
+ name => "prune volume=$v",
+ }, "command.tpl");
+ }
$b->close();
}
sub cancel_job
{
my ($self) = @_;
+ $self->can_do('r_cancel_job');
my $arg = $self->get_form('jobid');
unless ($arg->{jobid}) {
sub enable_disable_job
{
my ($self, $what) = @_ ;
+ $self->can_do('r_run_job');
my $name = CGI::param('job') || '';
unless ($name =~ /^[\w\d\.\-\s]+$/) {
sub run_job_select
{
my ($self) = @_;
+ $self->can_do('r_run_job');
+
my $b = $self->get_bconsole();
my $joblist = [ map { { name => $_ } } $b->list_job() ];
sub run_job_mod
{
my ($self) = @_;
+ $self->can_do('r_run_job');
+
my $b = $self->get_bconsole();
my $job = CGI::param('job') || '';
sub run_job
{
my ($self) = @_;
+ $self->can_do('r_run_job');
+
my $b = $self->get_bconsole();
my $jobs = [ map {{ name => $_ }} $b->list_job() ];
sub run_job_now
{
my ($self) = @_;
+ $self->can_do('r_run_job');
+
my $b = $self->get_bconsole();
# TODO: check input (don't use pool, level)