1
|
#!/usr/local/bin/php -q
|
2
|
<?php
|
3
|
/*
|
4
|
* rebuild_package_binaries.sh
|
5
|
* Copyright (C) 2010, 2011 Scott Ullrich <sullrich@gmail.com>
|
6
|
* Copyright (C) 2010, 2011 Jim Pingle <jim@pingle.org>
|
7
|
* All rights reserved.
|
8
|
*
|
9
|
* Redistribution and use in source and binary forms, with or without
|
10
|
* modification, are permitted provided that the following conditions are met:
|
11
|
*
|
12
|
* 1. Redistributions of source code must retain the above copyright notice,
|
13
|
* this list of conditions and the following disclaimer.
|
14
|
*
|
15
|
* 2. Redistributions in binary form must reproduce the above copyright
|
16
|
* notice, this list of conditions and the following disclaimer in the
|
17
|
* documentation and/or other materials provided with the distribution.
|
18
|
*
|
19
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
20
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
21
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
22
|
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
23
|
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
* POSSIBILITY OF SUCH DAMAGE.
|
29
|
*/
|
30
|
|
31
|
if(file_exists("/etc/inc/")) {
|
32
|
require("/etc/inc/functions.inc");
|
33
|
require("/etc/inc/util.inc");
|
34
|
require("/etc/inc/xmlparse.inc");
|
35
|
$handled = true;
|
36
|
}
|
37
|
|
38
|
if(file_exists("/home/pfsense/pfSense/etc/inc") && !$handled) {
|
39
|
require("/home/pfsense/pfSense/etc/inc/functions.inc");
|
40
|
require("/home/pfsense/pfSense/etc/inc/util.inc");
|
41
|
require("/home/pfsense/pfSense/etc/inc/xmlparse.inc");
|
42
|
$handled = true;
|
43
|
}
|
44
|
|
45
|
if(file_exists("/usr/home/pfsense/pfSenseGITREPO/pfSenseGITREPO/etc/inc") && !$handled) {
|
46
|
require("/usr/home/pfsense/pfSenseGITREPO/pfSenseGITREPO/etc/inc/functions.inc");
|
47
|
require("/usr/home/pfsense/pfSenseGITREPO/pfSenseGITREPO/etc/inc/util.inc");
|
48
|
require("/usr/home/pfsense/pfSenseGITREPO/pfSenseGITREPO/etc/inc/xmlparse.inc");
|
49
|
$handled = true;
|
50
|
}
|
51
|
|
52
|
function usage() {
|
53
|
global $argv;
|
54
|
echo "Usage: {$argv[0]} -x <path to pkg xml> [-p <package name>] [-d]\n";
|
55
|
echo " Flags:\n";
|
56
|
echo " -c csup hostname\n";
|
57
|
echo " -d Use DESTDIR when building.\n";
|
58
|
echo " -j Use a chroot for building each invocation\n";
|
59
|
echo " -l Location of chroot for building.\n";
|
60
|
echo " -p Package name to build a single package and its dependencies.\n";
|
61
|
echo " -q quiet mode - surpresses command output\n";
|
62
|
echo " -r remove chroot contents on each builder run.\n";
|
63
|
echo " -s pfSense version to pass to set_version.sh during chroot build\n";
|
64
|
echo " -x XML file containing package data.\n";
|
65
|
echo " Examples:\n";
|
66
|
echo " {$argv[0]} -x /home/pfsense/packages/pkg_info.8.xml\n";
|
67
|
echo " {$argv[0]} -x /home/pfsense/packages/pkg_info.8.xml -p squid\n";
|
68
|
echo " {$argv[0]} -x /home/pfsense/packages/pkg_info.8.xml -j -l/usr/local/pkgchroot -ccvsup.livebsd.com\n";
|
69
|
exit;
|
70
|
}
|
71
|
|
72
|
function overlay_pfPort($port_path) {
|
73
|
$pfports = "/home/pfsense/tools/pfPorts";
|
74
|
// If a pfport exists, overlay that folder onto $port_path
|
75
|
$port_name = basename($port_path);
|
76
|
if (file_exists("{$pfports}/{$port_name}") && is_dir("{$pfports}/{$port_name}") && is_file("{$pfports}/{$port_name}/Makefile")) {
|
77
|
echo ">>> Overelaying pfPort {$port_name} onto {$port_path} ... ";
|
78
|
if (file_exists($port_path) && is_dir($port_path)) {
|
79
|
echo "Preserving old port in {$port_path}.orig ...";
|
80
|
system("/bin/rm -rf {$port_path}.orig");
|
81
|
system("/bin/mv {$port_path} {$port_path}.orig");
|
82
|
}
|
83
|
system("/bin/cp -R {$pfports}/{$port_name} {$port_path}");
|
84
|
echo "Done.\n";
|
85
|
}
|
86
|
}
|
87
|
|
88
|
function csup($csup_host, $supfile, $chrootchroot = "", $quiet_mode = "") {
|
89
|
echo ">>> Update sources from file {$supfile}\n";
|
90
|
if($chrootchroot)
|
91
|
system("/usr/sbin/chroot {$chrootchroot} csup -L0 -h {$csup_host} {$supfile} {$quiet_mode}");
|
92
|
else
|
93
|
system("/usr/bin/csup -h {$csup_host} {$supfile} {$quiet_mode}");
|
94
|
}
|
95
|
|
96
|
function chroot_command($chroot_location, $command_to_run) {
|
97
|
file_put_contents("{$chroot_location}/cmd.sh", $command_to_run);
|
98
|
exec("/bin/chmod a+rx {$chroot_location}/cmd.sh");
|
99
|
`/usr/sbin/chroot {$chroot_location} /cmd.sh`;
|
100
|
}
|
101
|
|
102
|
$options = getopt("x:p:d:jl:c:rqs:");
|
103
|
|
104
|
if(!isset($options['x']))
|
105
|
usage();
|
106
|
|
107
|
// Set the XML filename that we are processing
|
108
|
$xml_filename = $options['x'];
|
109
|
|
110
|
$pkg = parse_xml_config_pkg($xml_filename, "pfsensepkgs");
|
111
|
if(!$pkg) {
|
112
|
echo "!!! An error occurred while trying to process {$xml_filename}. Exiting.\n";
|
113
|
exit;
|
114
|
}
|
115
|
|
116
|
// Set csup hostname
|
117
|
if($options['c'] <> "") {
|
118
|
echo ">>> Setting csup hostname to {$options['c']} \n";
|
119
|
$csup_host = $options['c'];
|
120
|
} else {
|
121
|
echo ">>> Setting csup hostname to cvsup.livebsd.com \n";
|
122
|
$csup_host = "cvsup.livebsd.com";
|
123
|
}
|
124
|
|
125
|
if(isset($options['q']))
|
126
|
$quiet_mode = "</dev/null 2>&1";
|
127
|
|
128
|
if($options['s'] <> "")
|
129
|
$set_version = $options['s'];
|
130
|
|
131
|
// Set and ouput initial flags
|
132
|
if($pkg['copy_packages_to_host_ssh_port'] &&
|
133
|
$pkg['copy_packages_to_host_ssh'] &&
|
134
|
$pkg['copy_packages_to_folder_ssh']) {
|
135
|
$copy_packages_to_folder_ssh = $pkg['copy_packages_to_folder_ssh'];
|
136
|
$copy_packages_to_host_ssh = $pkg['copy_packages_to_host_ssh'];
|
137
|
$copy_packages_to_host_ssh_port = $pkg['copy_packages_to_host_ssh_port'];
|
138
|
echo ">>> Setting the following RSYNC/SSH parameters: \n";
|
139
|
echo " copy_packages_to_folder_ssh: $copy_packages_to_folder_ssh\n";
|
140
|
echo " copy_packages_to_host_ssh: $copy_packages_to_host_ssh\n";
|
141
|
echo " copy_packages_to_host_ssh_port: $copy_packages_to_host_ssh_port\n";
|
142
|
}
|
143
|
|
144
|
// Handle chroot building
|
145
|
if(isset($options['j']) && $options['l'] <> "") {
|
146
|
if(!file_exists("/usr/src/COPYRIGHT")) {
|
147
|
echo ">>> /usr/src/ is not populated. Populating, please wait...\n";
|
148
|
csup($csup_host, "/usr/share/examples/cvsup/standard-supfile", $quiet_mode);
|
149
|
}
|
150
|
$file_system_root = "{$options['l']}";
|
151
|
echo ">>> Preparing chroot {$options['l']} ...\n";
|
152
|
// Nuke old chroot
|
153
|
if(is_dir($options['l'])) {
|
154
|
if(is_dir("{$options['l']}/dev")) {
|
155
|
echo ">>> Unmounting {$options['l']}/dev\n";
|
156
|
system("umount {$options['l']}/dev 2>/dev/null");
|
157
|
}
|
158
|
if(isset($options['r'])) {
|
159
|
echo ">>> Removing {$options['l']}\n";
|
160
|
system("chflags -R noschg {$options['l']}/*");
|
161
|
system("rm -rf {$options['l']}");
|
162
|
}
|
163
|
}
|
164
|
// Create new chroot structure
|
165
|
echo ">>> Creating chroot structure...\n";
|
166
|
system("cd /usr/src && mkdir -p {$options['l']}");
|
167
|
system("cd /usr/src && mkdir -p {$options['l']}/etc");
|
168
|
system("cd /usr/src && mkdir -p {$options['l']}/dev");
|
169
|
system("mkdir -p {$options['l']}/home/pfsense");
|
170
|
echo ">>> Building world...\n";
|
171
|
exec("cd /usr/src && make world NO_CLEAN=yes DESTDIR={$options['l']} {$quiet_mode}");
|
172
|
echo ">>> Building distribution...\n";
|
173
|
exec("cd /usr/src && make distribution NO_CLEAN=yes DESTDIR={$options['l']} {$quiet_mode}");
|
174
|
// Mount devs and populate resolv.conf
|
175
|
system("mount -t devfs devfs {$options['l']}/dev");
|
176
|
system("cp /etc/resolv.conf {$options['l']}/etc/");
|
177
|
system("cp -R /home/pfsense/tools {$options['l']}/home/pfsense/");
|
178
|
// Invoke csup and populate /usr/ports inside chroot
|
179
|
//csup($csup_host, "/usr/share/examples/cvsup/ports-supfile", $options['l'], $quiet_mode);
|
180
|
echo ">>> Applying kernel patches and make includes...\n";
|
181
|
exec("rm -rf {$options['l']}/tmp/pf*");
|
182
|
$command_to_run = "#!/bin/sh\n";
|
183
|
if($set_version)
|
184
|
$command_to_run .= "cd /home/pfsense/tools/builder_scripts && ./set_version.sh {$set_version}\n";
|
185
|
$command_to_run .= "cd /home/pfsense/tools/builder_scripts && ./build.sh --apply-patches\n";
|
186
|
$command_to_run .= "cd /usr/pfSensesrc/src && make includes\n";
|
187
|
chroot_command($options['l'], $command_to_run);
|
188
|
} else {
|
189
|
// Invoke csup and populate /usr/ports on host (non-chroot)
|
190
|
$file_system_root = "/";
|
191
|
exec("rm -rf /tmp/pf*");
|
192
|
//csup($csup_host, "/usr/share/examples/cvsup/ports-supfile", $quiet_mode);
|
193
|
echo ">>> Applying kernel patches...\n";
|
194
|
if($set_version)
|
195
|
exec("cd /home/pfsense/tools/builder_scripts && ./set_version.sh {$set_version}");
|
196
|
exec("cd /home/pfsense/tools/builder_scripts && ./build.sh --apply-patches");
|
197
|
echo ">>> Running make includes...\n";
|
198
|
exec("cd /usr/pfSensesrc/src && make includes");
|
199
|
}
|
200
|
|
201
|
echo ">>> pfSense package binary builder is starting.\n";
|
202
|
|
203
|
// Safety check - should no fail since we sync ports above with csup
|
204
|
if(!is_dir("{$file_system_root}/usr/ports")) {
|
205
|
echo "!!! {$file_system_root}/usr/ports/ not found. Please run portsnap fetch extract\n";
|
206
|
exit;
|
207
|
}
|
208
|
|
209
|
// Ensure that the All directory exists in packages staging area
|
210
|
if(!is_dir("{$file_system_root}/usr/ports/packages/All"))
|
211
|
system("mkdir -p {$file_system_root}/usr/ports/packages/All");
|
212
|
|
213
|
// Loop through all packages and build pacakge with
|
214
|
// build_options if the port/package has this defined.
|
215
|
foreach($pkg['packages']['package'] as $pkg) {
|
216
|
if (isset($options['p']) && (strtolower($options['p']) != strtolower($pkg['name'])))
|
217
|
continue;
|
218
|
if($pkg['build_port_path']) {
|
219
|
foreach($pkg['build_port_path'] as $build) {
|
220
|
overlay_pfPort($build);
|
221
|
$buildname = basename($build);
|
222
|
if(isset($options['d'])) {
|
223
|
$DESTDIR="DESTDIR=/usr/pkg/{$buildname}";
|
224
|
echo ">>> Using $DESTDIR \n";
|
225
|
} else
|
226
|
$DESTDIR="";
|
227
|
$build_options="";
|
228
|
if($pkg['build_options'])
|
229
|
$build_options = $pkg['build_options'];
|
230
|
/*
|
231
|
if(file_exists("/var/db/ports/{$buildname}/options")) {
|
232
|
echo ">>> Using /var/db/ports/{$buildname}/options \n";
|
233
|
$portopts = split("\n", file_get_contents("/var/db/ports/{$buildname}/options"));
|
234
|
foreach ($portopts as $po) {
|
235
|
if (substr($po, 0, 1) != '#')
|
236
|
$build_options .= " " . $po;
|
237
|
}
|
238
|
}
|
239
|
*/
|
240
|
echo ">>> Processing {$build}\n";
|
241
|
if(!empty($build_options)) {
|
242
|
if(!isset($options['q']))
|
243
|
echo " BUILD_OPTIONS: {$build_options}\n";
|
244
|
$build_options = '"' . str_replace(';', '" "', $build_options) . '"';
|
245
|
}
|
246
|
// Build in chroot if defined.
|
247
|
if(isset($options['j']) && $options['l']) {
|
248
|
$command_to_run = "#!/bin/sh\n";
|
249
|
$command_to_run .= "if [ ! -L /usr/home ]; then\n";
|
250
|
$command_to_run .= " ln -s /home/ /usr/home\n";
|
251
|
$command_to_run .= "fi\n";
|
252
|
$command_to_run .= "cd {$build} && make BATCH=yes {$build_options} FORCE_PKG_REGISTER=yes WITHOUT=\"X11 DOCS EXAMPLES MAN INFO\" clean depends package-recursive {$DESTDIR} clean {$quiet_mode}\n";
|
253
|
chroot_command($options['l'], $command_to_run);
|
254
|
} else {
|
255
|
$command_to_run = "cd {$build} && make BATCH=yes {$build_options} FORCE_PKG_REGISTER=yes WITHOUT=\"X11 DOCS EXAMPLES MAN INFO\" clean depends package-recursive {$DESTDIR} clean {$quiet_mode}";
|
256
|
if(!isset($options['q']))
|
257
|
echo ">> Build Command: {$command_to_run}\n";
|
258
|
shell_exec($command_to_run);
|
259
|
}
|
260
|
}
|
261
|
}
|
262
|
}
|
263
|
|
264
|
echo ">>> {$file_system_root}/usr/ports/packages/All now contains:\n";
|
265
|
system("ls {$file_system_root}/usr/ports/packages/All");
|
266
|
|
267
|
// Copy created packages to the package server via rsync
|
268
|
if($copy_packages_to_folder_ssh) {
|
269
|
echo ">>> Copying packages to {$copy_packages_to_host_ssh}\n";
|
270
|
system("/usr/local/bin/rsync -ave ssh --timeout=60 --rsh='ssh -p{$copy_packages_to_host_ssh_port}' {$file_system_root}/usr/ports/packages/All/* {$copy_packages_to_host_ssh}:{$copy_packages_to_folder_ssh}/");
|
271
|
}
|
272
|
|
273
|
echo ">>> Package binary build run ended.\n";
|
274
|
|
275
|
?>
|