-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathcrontab.php
More file actions
156 lines (124 loc) · 4.47 KB
/
crontab.php
File metadata and controls
156 lines (124 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?php
/*
Recipe for adding crontab jobs.
This recipe creates a new section in the crontab file with the configured jobs.
The section is identified by the *crontab:identifier* variable, by default the application name.
## Configuration
- *crontab:jobs* - An array of strings with crontab lines.
## Usage
```php
require 'contrib/crontab.php';
after('deploy:success', 'crontab:sync');
add('crontab:jobs', [
'* * * * * cd {{current_path}} && {{bin/php}} artisan schedule:run >> /dev/null 2>&1',
]);
```
*/
namespace Deployer;
use function Deployer\Support\escape_shell_argument;
// Get path to bin
set('bin/crontab', function () {
return which('crontab');
});
// Set the identifier used in the crontab, application name by default
set('crontab:identifier', function () {
return get('application', 'application');
});
// Use sudo to run crontab. When running crontab with sudo, you can use the `-u` parameter to change a crontab for a different user.
set('crontab:use_sudo', false);
desc('Sync crontab jobs');
task('crontab:sync', function () {
$cronJobsLocal = array_map(
fn($job) => parse($job),
get('crontab:jobs', []),
);
if (count($cronJobsLocal) == 0) {
writeln("Nothing to sync - configure crontab:jobs");
return;
}
$cronJobs = getRemoteCrontab();
$identifier = get('crontab:identifier');
$sectionStart = "###< $identifier";
$sectionEnd = "###> $identifier";
// find our cronjob section
$start = array_search($sectionStart, $cronJobs);
$end = array_search($sectionEnd, $cronJobs);
if ($start === false || $end === false) {
// Move the duplicates over when first generating the section
foreach ($cronJobs as $index => $cronJob) {
if (in_array($cronJob, $cronJobsLocal)) {
unset($cronJobs[$index]);
writeln("Crontab: Found existing job in crontab, moving it to the section");
}
}
// Create the section
$cronJobs[] = $sectionStart;
$cronJobs = [...$cronJobs, ...$cronJobsLocal];
$cronJobs[] = $sectionEnd;
writeln("Crontab: Found no section, created the section with configured jobs");
} else {
// Replace the existing section
array_splice($cronJobs, $start + 1, $end - $start - 1, $cronJobsLocal);
writeln("Crontab: Found existing section, replaced with configured jobs");
}
setRemoteCrontab($cronJobs);
});
desc('Remove crontab jobs');
task('crontab:remove', function () {
$cronJobsLocal = array_map(
fn($job) => parse($job),
get('crontab:jobs', []),
);
$cronJobs = getRemoteCrontab();
$identifier = get('crontab:identifier');
$sectionStart = "###< $identifier";
$sectionEnd = "###> $identifier";
// Find our cronjob section
$start = array_search($sectionStart, $cronJobs);
$end = array_search($sectionEnd, $cronJobs);
if ($start && $end) {
// Remove the existing section
array_splice($cronJobs, $start + 1, $end - $start - 1);
writeln("Crontab: Found existing section, removed jobs");
} elseif (count($cronJobsLocal) > 0) {
$foundJobs = false;
// Remove individual jobs if no section is present
foreach ($cronJobs as $index => $cronJob) {
if (in_array($cronJob, $cronJobsLocal)) {
unset($cronJobs[$index]);
$foundJobs = true;
}
}
if ($foundJobs) {
writeln("Crontab: Found existing jobs in crontab, removed jobs");
} else {
writeln("Crontab: No existing jobs in crontab, skipping");
return;
}
} else {
writeln("Crontab: Found no section and crontab:jobs is not configured, skipping");
return;
}
setRemoteCrontab($cronJobs);
});
function setRemoteCrontab(array $lines): void
{
$sudo = get('crontab:use_sudo') ? 'sudo' : '';
$tmpCrontabPath = sprintf('/tmp/%s', uniqid('crontab_save_'));
if (test("[ -f '$tmpCrontabPath' ]")) {
run("unlink '$tmpCrontabPath'");
}
foreach ($lines as $line) {
run("echo " . escape_shell_argument($line) . " >> $tmpCrontabPath");
}
run("$sudo {{bin/crontab}} " . $tmpCrontabPath);
run('unlink ' . $tmpCrontabPath);
}
function getRemoteCrontab(): array
{
$sudo = get('crontab:use_sudo') ? 'sudo' : '';
if (!test("$sudo {{bin/crontab}} -l >> /dev/null 2>&1")) {
return [];
}
return explode(PHP_EOL, run("$sudo {{bin/crontab}} -l"));
}