View | Details | Raw Unified | Return to ticket 2134 | Differences between
and this patch

Collapse All | Expand All

(-)a/contribs/torque/qalter.pl (-232 / +232 lines)
Lines 1-232 Link Here
1
#! /usr/bin/perl -w
1
#! /usr/bin/perl -w
2
###############################################################################
2
###############################################################################
3
#
3
#
4
# qalter - PBS wrapper for changing job status using scontrol
4
# qalter - PBS wrapper for changing job status using scontrol
5
#
5
#
6
###############################################################################
6
###############################################################################
7
7
8
use strict;
8
use strict;
9
use FindBin;
9
use FindBin;
10
use Getopt::Long 2.24 qw(:config no_ignore_case);
10
use Getopt::Long 2.24 qw(:config no_ignore_case);
11
use lib "${FindBin::Bin}/../lib/perl";
11
use lib "${FindBin::Bin}/../lib/perl";
12
use autouse 'Pod::Usage' => qw(pod2usage);
12
use autouse 'Pod::Usage' => qw(pod2usage);
13
use Slurm ':all';
13
use Slurm ':all';
14
use Slurmdb ':all'; # needed for getting the correct cluster dims
14
use Slurmdb ':all'; # needed for getting the correct cluster dims
15
use Switch;
15
use Switch;
16
16
17
# ------------------------------------------------------------------
17
# ------------------------------------------------------------------
18
# This makes the assumption job_id will always be the last argument
18
# This makes the assumption job_id will always be the last argument
19
# -------------------------------------------------------------------
19
# -------------------------------------------------------------------
20
my $job_id = $ARGV[$#ARGV];
20
my $job_id = $ARGV[$#ARGV];
21
my (
21
my (
22
	$err,
22
	$err,
23
	$new_name,
23
	$new_name,
24
	$output,
24
	$output,
25
	$rerun,
25
	$rerun,
26
	$resp,
26
	$resp,
27
	$slurm,
27
	$slurm,
28
	$man,
28
	$man,
29
	$help
29
	$help
30
);
30
);
31
31
32
# Remove this
32
# Remove this
33
my $scontrol = "/usr/slurm/bin/scontrol";
33
my $scontrol = "/usr/slurm/bin/scontrol";
34
34
35
# ------------------------------
35
# ------------------------------
36
# Parse Command Line Arguments
36
# Parse Command Line Arguments
37
# ------------------------------
37
# ------------------------------
38
GetOptions(
38
GetOptions(
39
	'N=s'    => \$new_name,
39
	'N=s'    => \$new_name,
40
	'r=s'    => \$rerun,
40
	'r=s'    => \$rerun,
41
	'o=s'    => \$output,
41
	'o=s'    => \$output,
42
	'help|?' => \$help,
42
	'help|?' => \$help,
43
	'man'    => \$man
43
	'man'    => \$man
44
	)
44
	)
45
	or pod2usage(2);
45
	or pod2usage(2);
46
46
47
pod2usage(0) if $help;
47
pod2usage(0) if $help;
48
48
49
if ($man)
49
if ($man)
50
{
50
{
51
	if ($< == 0)    # Cannot invoke perldoc as root
51
	if ($< == 0)    # Cannot invoke perldoc as root
52
	{
52
	{
53
		my $id = eval { getpwnam("nobody") };
53
		my $id = eval { getpwnam("nobody") };
54
		$id = eval { getpwnam("nouser") } unless defined $id;
54
		$id = eval { getpwnam("nouser") } unless defined $id;
55
		$id = -2			  unless defined $id;
55
		$id = -2			  unless defined $id;
56
		$<  = $id;
56
		$<  = $id;
57
	}
57
	}
58
	$> = $<;			# Disengage setuid
58
	$> = $<;			# Disengage setuid
59
	$ENV{PATH} = "/bin:/usr/bin";	# Untaint PATH
59
	$ENV{PATH} = "/bin:/usr/bin";	# Untaint PATH
60
	delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
60
	delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
61
	if ($0 =~ /^([-\/\w\.]+)$/) {
61
	if ($0 =~ /^([-\/\w\.]+)$/) {
62
		$0 = $1;		# Untaint $0
62
		$0 = $1;		# Untaint $0
63
	} else {
63
	} else {
64
		die "Illegal characters were found in \$0 ($0)\n";
64
		die "Illegal characters were found in \$0 ($0)\n";
65
	}
65
	}
66
	pod2usage(-exitstatus => 0, -verbose => 2);
66
	pod2usage(-exitstatus => 0, -verbose => 2);
67
}
67
}
68
68
69
# ----------------------
69
# ----------------------
70
# Check input arguments
70
# Check input arguments
71
# ----------------------
71
# ----------------------
72
if (@ARGV < 1) {
72
if (@ARGV < 1) {
73
	pod2usage(-message=>"Missing Job ID", -verbose=>0); 
73
	pod2usage(-message=>"Missing Job ID", -verbose=>0); 
74
} else {
74
} else {
75
	$slurm = Slurm::new();
75
	$slurm = Slurm::new();
76
	$resp = $slurm->get_end_time($job_id);
76
	$resp = $slurm->get_end_time($job_id);
77
	if (not defined($resp)) {
77
	if (not defined($resp)) {
78
		pod2usage(-message=>"Job id $job_id not valid!", -verbose=>0); 
78
		pod2usage(-message=>"Job id $job_id not valid!", -verbose=>0); 
79
	}
79
	}
80
	if ((not defined($new_name)) and (not defined($rerun)) and (not defined($output))) {
80
	if ((not defined($new_name)) and (not defined($rerun)) and (not defined($output))) {
81
		pod2usage(-message=>"no argument given!", -verbose=>0); 
81
		pod2usage(-message=>"no argument given!", -verbose=>0); 
82
	}
82
	}
83
}
83
}
84
84
85
# --------------------------------------------
85
# --------------------------------------------
86
# Use Slurm's Perl API to change name of a job 
86
# Use Slurm's Perl API to change name of a job 
87
# --------------------------------------------
87
# --------------------------------------------
88
if ($new_name) {
88
if ($new_name) {
89
	my %update = ();
89
	my %update = ();
90
90
91
	$update{job_id}  = $job_id;
91
	$update{job_id}  = $job_id;
92
	$update{name}    = $new_name;
92
	$update{name}    = $new_name;
93
	if (Slurm->update_job(\%update)) {
93
	if (Slurm->update_job(\%update)) {
94
		$err = Slurm->get_errno();
94
		$err = Slurm->get_errno();
95
		$resp = Slurm->strerror($err);
95
		$resp = Slurm->strerror($err);
96
		pod2usage(-message=>"Job id $job_id name change error: $resp", -verbose=>0);
96
		pod2usage(-message=>"Job id $job_id name change error: $resp", -verbose=>0);
97
		exit(1);
97
		exit(1);
98
	}
98
	}
99
}
99
}
100
100
101
# ---------------------------------------------------
101
# ---------------------------------------------------
102
# Use Slurm's Perl API to change the requeue job flag
102
# Use Slurm's Perl API to change the requeue job flag
103
# ---------------------------------------------------
103
# ---------------------------------------------------
104
if ($rerun) {
104
if ($rerun) {
105
	my %update = ();
105
	my %update = ();
106
106
107
	$update{job_id}  = $job_id;
107
	$update{job_id}  = $job_id;
108
	if (($rerun eq "n") || ($rerun eq "N")) {
108
	if (($rerun eq "n") || ($rerun eq "N")) {
109
		$update{requeue} = 0;
109
		$update{requeue} = 0;
110
	} else {
110
	} else {
111
		$update{requeue} = 1;
111
		$update{requeue} = 1;
112
	}
112
	}
113
	if (Slurm->update_job(\%update)) {
113
	if (Slurm->update_job(\%update)) {
114
		$err = Slurm->get_errno();
114
		$err = Slurm->get_errno();
115
		$resp = Slurm->strerror($err);
115
		$resp = Slurm->strerror($err);
116
		pod2usage(-message=>"Job id $job_id requeue error: $resp", -verbose=>0);
116
		pod2usage(-message=>"Job id $job_id requeue error: $resp", -verbose=>0);
117
		exit(1);
117
		exit(1);
118
	}
118
	}
119
}
119
}
120
120
121
# ------------------------------------------------------------
121
# ------------------------------------------------------------
122
# Use Slurm's Perl API to change Comment string
122
# Use Slurm's Perl API to change Comment string
123
# Comment is used to relocate an output log file
123
# Comment is used to relocate an output log file
124
# ------------------------------------------------------------
124
# ------------------------------------------------------------
125
if ($output) {
125
if ($output) {
126
	# Example:
126
	# Example:
127
	# $comment="on:16337,stdout=/gpfsm/dhome/lgerner/tmp/slurm-16338.out,stdout=~lgerner/tmp/new16338.out";
127
	# $comment="on:16337,stdout=/gpfsm/dhome/lgerner/tmp/slurm-16338.out,stdout=~lgerner/tmp/new16338.out";
128
	#
128
	#
129
	my $comment;
129
	my $comment;
130
	my %update = ();
130
	my %update = ();
131
131
132
	# ---------------------------------------
132
	# ---------------------------------------
133
	# Get current comment string from job_id
133
	# Get current comment string from job_id
134
	# ---------------------------------------
134
	# ---------------------------------------
135
	my($job) = $slurm->load_job($job_id);
135
	my($job) = $slurm->load_job($job_id);
136
	$comment = $$job{'job_array'}[0]->{comment};
136
	$comment = $$job{'job_array'}[0]->{comment};
137
137
138
	# ----------------
138
	# ----------------
139
	# Split at stdout
139
	# Split at stdout
140
	# ----------------
140
	# ----------------
141
	if ($comment) {
141
	if ($comment) {
142
		my(@outlog) = split("stdout", $comment);
142
		my(@outlog) = split("stdout", $comment);
143
143
144
		# ---------------------------------
144
		# ---------------------------------
145
		# Only 1 stdout argument add a ','
145
		# Only 1 stdout argument add a ','
146
		# ---------------------------------
146
		# ---------------------------------
147
		if ($#outlog < 2) {
147
		if ($#outlog < 2) {
148
			$outlog[1] .= ","
148
			$outlog[1] .= ","
149
		}
149
		}
150
150
151
		# ------------------------------------------------
151
		# ------------------------------------------------
152
		# Add new log file location to the comment string
152
		# Add new log file location to the comment string
153
		# ------------------------------------------------
153
		# ------------------------------------------------
154
		$outlog[2] = "=".$output;
154
		$outlog[2] = "=".$output;
155
		$comment = join("stdout", @outlog);
155
		$comment = join("stdout", @outlog);
156
	} else {
156
	} else {
157
		$comment = "stdout=$output";
157
		$comment = "stdout=$output";
158
	}
158
	}
159
159
160
	# -------------------------------------------------
160
	# -------------------------------------------------
161
	# Make sure that "%j" is changed to current $job_id
161
	# Make sure that "%j" is changed to current $job_id
162
	# -------------------------------------------------
162
	# -------------------------------------------------
163
	$comment =~ s/%j/$job_id/g ;
163
	$comment =~ s/%j/$job_id/g ;
164
164
165
	# -----------------------------------------------------
165
	# -----------------------------------------------------
166
	# Update comment and print usage if there is a response
166
	# Update comment and print usage if there is a response
167
	# -----------------------------------------------------
167
	# -----------------------------------------------------
168
	$update{job_id}  = $job_id;
168
	$update{job_id}  = $job_id;
169
	$update{comment} = $comment;
169
	$update{comment} = $comment;
170
	if (Slurm->update_job(\%update)) {
170
	if (Slurm->update_job(\%update)) {
171
		$err = Slurm->get_errno();
171
		$err = Slurm->get_errno();
172
		$resp = Slurm->strerror($err);
172
		$resp = Slurm->strerror($err);
173
		pod2usage(-message=>"Job id $job_id comment change error: $resp", -verbose=>0);
173
		pod2usage(-message=>"Job id $job_id comment change error: $resp", -verbose=>0);
174
		exit(1);
174
		exit(1);
175
	}
175
	}
176
}
176
}
177
exit(0);
177
exit(0);
178
178
179
##############################################################################
179
##############################################################################
180
180
181
__END__
181
__END__
182
182
183
=head1 NAME
183
=head1 NAME
184
184
185
B<qalter> - alter a job name, the job rerun flag or the job output file name.
185
B<qalter> - alter a job name, the job rerun flag or the job output file name.
186
186
187
=head1 SYNOPSIS
187
=head1 SYNOPSIS
188
188
189
qalter [-N Name] 
189
qalter [-N Name] 
190
       [-r y|n]
190
       [-r y|n]
191
       [-o output file]
191
       [-o output file]
192
       <job ID>
192
       <job ID>
193
193
194
=head1 DESCRIPTION
194
=head1 DESCRIPTION
195
195
196
The B<qalter> updates job name, job rerun flag or job output(stdout) log location. 
196
The B<qalter> updates job name, job rerun flag or job output(stdout) log location. 
197
197
198
It is aimed to be feature-compatible with PBS' qsub.
198
It is aimed to be feature-compatible with PBS' qsub.
199
199
200
=head1 OPTIONS
200
=head1 OPTIONS
201
201
202
=over 4
202
=over 4
203
203
204
=item B<-N>
204
=item B<-N>
205
205
206
Update job name in the queue
206
Update job name in the queue
207
207
208
=item B<-r>
208
=item B<-r>
209
209
210
Alter a job rerunnable flag. "y" will allow a qrerun to be issued. "n" disable qrerun option.
210
Alter a job rerunnable flag. "y" will allow a qrerun to be issued. "n" disable qrerun option.
211
211
212
=item B<-o>
212
=item B<-o>
213
213
214
Alter a job output log file name (stdout). 
214
Alter a job output log file name (stdout). 
215
215
216
The job log will be move/rename after the job has B<terminated>.
216
The job log will be move/rename after the job has B<terminated>.
217
217
218
=item B<-?> | B<--help>
218
=item B<-?> | B<--help>
219
219
220
brief help message
220
brief help message
221
221
222
=item B<-man> 
222
=item B<-man> 
223
223
224
full documentation
224
full documentation
225
225
226
=back
226
=back
227
227
228
=head1 SEE ALSO
228
=head1 SEE ALSO
229
229
230
qrerun(1) qsub(1)
230
qrerun(1) qsub(1)
231
=cut
231
=cut
232
232

Return to ticket 2134