This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Runs a deployment via the most appropriate backend |
||
5 | */ |
||
6 | class DeployJob extends DeploynautJob { |
||
7 | |||
8 | /** |
||
9 | * @var array |
||
10 | */ |
||
11 | public $args; |
||
12 | |||
13 | /** |
||
14 | * Poll the sigFile looking for a signal to self-deliver. |
||
15 | * This is useful if we don't know the PID of the worker - we can easily deliver signals |
||
16 | * if we only know the ClassName and ID of the DataObject. |
||
17 | */ |
||
18 | public function alarmHandler() { |
||
19 | $sigFile = $this->args['sigFile']; |
||
20 | if (file_exists($sigFile) && is_readable($sigFile) && is_writable($sigFile)) { |
||
21 | $signal = (int)file_get_contents($sigFile); |
||
22 | if (is_int($signal) && in_array((int)$signal, [ |
||
23 | // The following signals are trapped by both Resque and Rainforest. |
||
24 | SIGTERM, |
||
25 | SIGINT, |
||
26 | SIGQUIT, |
||
27 | // The following are Resque only. |
||
28 | SIGUSR1, |
||
29 | SIGUSR2, |
||
30 | SIGCONT |
||
31 | ])) { |
||
32 | echo sprintf( |
||
33 | '[-] Signal "%s" received, delivering to own process group, PID "%s".' . PHP_EOL, |
||
34 | $signal, |
||
35 | getmypid() |
||
36 | ); |
||
37 | |||
38 | // Mark the signal as received. |
||
39 | unlink($sigFile); |
||
40 | |||
41 | // Dispatch to own process group. |
||
42 | $pgid = posix_getpgid(getmypid()); |
||
43 | if ($pgid<=0) { |
||
44 | echo sprintf( |
||
45 | '[-] Unable to send signal to invalid PGID "%s".' . PHP_EOL, |
||
46 | $pgid |
||
47 | ); |
||
48 | } else { |
||
49 | posix_kill(-$pgid, $signal); |
||
50 | } |
||
51 | } |
||
52 | } |
||
53 | |||
54 | // Wake up again soon. |
||
55 | pcntl_alarm(1); |
||
56 | } |
||
57 | |||
58 | public function setUp() { |
||
59 | // Make this process a session leader so we can send signals |
||
60 | // to this job as a whole (including any subprocesses such as spawned by Symfony). |
||
61 | posix_setsid(); |
||
62 | |||
63 | if(function_exists('pcntl_alarm') && function_exists('pcntl_signal')) { |
||
64 | if (!empty($this->args['sigFile'])) { |
||
65 | echo sprintf('[-] Signal file requested, polling "%s".' . PHP_EOL, $this->args['sigFile']); |
||
66 | declare(ticks = 1); |
||
67 | pcntl_signal(SIGALRM, [$this, 'alarmHandler']); |
||
68 | pcntl_alarm(1); |
||
69 | } |
||
70 | } |
||
71 | |||
72 | $this->updateStatus(DNDeployment::TR_DEPLOY); |
||
73 | chdir(BASE_PATH); |
||
74 | } |
||
75 | |||
76 | public function perform() { |
||
77 | echo "[-] DeployJob starting" . PHP_EOL; |
||
78 | $log = new DeploynautLogFile($this->args['logfile']); |
||
79 | |||
80 | $deployment = DNDeployment::get()->byID($this->args['deploymentID']); |
||
81 | $environment = $deployment->Environment(); |
||
82 | $currentBuild = $environment->CurrentBuild(); |
||
83 | $project = $environment->Project(); |
||
84 | $backupDataTransfer = null; |
||
85 | $backupMode = !empty($this->args['backup_mode']) ? $this->args['backup_mode'] : 'db'; |
||
86 | |||
87 | // Perform pre-deploy backup here if required. Note that the backup is done here within |
||
88 | // the deploy job, so that the order of backup is done before deployment, and so it |
||
89 | // doesn't tie up another worker. It also puts the backup output into |
||
90 | // the same log as the deployment so there is visibility on what is going on. |
||
91 | // Note that the code has to be present for a backup to be performed, so the first |
||
92 | // deploy onto a clean environment will not be performing any backup regardless of |
||
93 | // whether the predeploy_backup option was passed or not. |
||
94 | // Sometimes predeploy_backup comes through as string false from the frontend. |
||
95 | View Code Duplication | if( |
|
0 ignored issues
–
show
|
|||
96 | !empty($this->args['predeploy_backup']) |
||
97 | && $this->args['predeploy_backup'] !== 'false' |
||
98 | && !empty($currentBuild) |
||
99 | ) { |
||
100 | $backupDataTransfer = DNDataTransfer::create(); |
||
101 | $backupDataTransfer->EnvironmentID = $environment->ID; |
||
102 | $backupDataTransfer->Direction = 'get'; |
||
103 | $backupDataTransfer->Mode = $backupMode; |
||
104 | $backupDataTransfer->ResqueToken = $deployment->ResqueToken; |
||
105 | $backupDataTransfer->AuthorID = $deployment->DeployerID; |
||
106 | $backupDataTransfer->write(); |
||
107 | |||
108 | $deployment->BackupDataTransferID = $backupDataTransfer->ID; |
||
109 | $deployment->write(); |
||
110 | } |
||
111 | |||
112 | try { |
||
113 | // Disallow concurrent deployments (don't rely on queuing implementation to restrict this) |
||
114 | // Only consider deployments started in the last 30 minutes (older jobs probably got stuck) |
||
115 | $runningDeployments = $environment->runningDeployments()->exclude('ID', $this->args['deploymentID']); |
||
116 | if($runningDeployments->count()) { |
||
117 | $runningDeployment = $runningDeployments->first(); |
||
118 | $message = sprintf( |
||
119 | 'Error: another deployment is in progress (started at %s by %s)', |
||
120 | $runningDeployment->dbObject('Created')->Nice(), |
||
121 | $runningDeployment->Deployer()->Title |
||
122 | ); |
||
123 | $log->write($message); |
||
124 | throw new \RuntimeException($message); |
||
125 | } |
||
126 | |||
127 | $this->performBackup($backupDataTransfer, $log); |
||
128 | $environment->Backend()->deploy( |
||
129 | $environment, |
||
130 | $log, |
||
131 | $project, |
||
132 | // Pass all args to give the backend full visibility. These args also contain |
||
133 | // all options from the DeploymentStrategy merged in, including sha. |
||
134 | $this->args |
||
135 | ); |
||
136 | } catch(Exception $e) { |
||
137 | // DeploynautJob will automatically trigger onFailure. |
||
138 | echo "[-] DeployJob failed" . PHP_EOL; |
||
139 | throw $e; |
||
140 | } |
||
141 | |||
142 | $this->updateStatus(DNDeployment::TR_COMPLETE); |
||
143 | echo "[-] DeployJob finished" . PHP_EOL; |
||
144 | } |
||
145 | |||
146 | public function onFailure(Exception $exception) { |
||
147 | $this->updateStatus(DNDeployment::TR_FAIL); |
||
148 | } |
||
149 | |||
150 | View Code Duplication | protected function performBackup($backupDataTransfer, \DeploynautLogFile $log) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
151 | if (!$backupDataTransfer) { |
||
152 | return false; |
||
153 | } |
||
154 | |||
155 | $log->write('Backing up existing data'); |
||
156 | try { |
||
157 | $backupDataTransfer->Environment()->Backend()->dataTransfer($backupDataTransfer, $log); |
||
158 | global $databaseConfig; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
159 | DB::connect($databaseConfig); |
||
160 | $backupDataTransfer->Status = 'Finished'; |
||
161 | $backupDataTransfer->write(); |
||
162 | } catch(Exception $e) { |
||
163 | global $databaseConfig; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
164 | DB::connect($databaseConfig); |
||
165 | $backupDataTransfer->Status = 'Failed'; |
||
166 | $backupDataTransfer->write(); |
||
167 | throw $e; |
||
168 | } |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * @param string $status Transition |
||
173 | * @global array $databaseConfig |
||
174 | */ |
||
175 | protected function updateStatus($status) { |
||
176 | global $databaseConfig; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
177 | DB::connect($databaseConfig); |
||
178 | $deployment = DNDeployment::get()->byID($this->args['deploymentID']); |
||
179 | $deployment->getMachine()->apply($status); |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * @return DNData |
||
184 | */ |
||
185 | protected function DNData() { |
||
186 | return DNData::inst(); |
||
187 | } |
||
188 | } |
||
189 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.