-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmenu.php
128 lines (97 loc) · 3.63 KB
/
menu.php
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
<?php
function template($string, $templates) {
$template_pattern = '/\${(\w+)}/';
$matches = [];
$match_count = preg_match_all($template_pattern, $string, $matches);
if ($match_count) {
for ($i = 0; $i < $match_count; $i++) {
$string = str_replace($matches[0][$i], $templates[$matches[1][$i]], $string);
}
}
return $string;
}
function addFileTarget($root, $http_root, $path, $host) {
$pathinfo = pathinfo($path);
$extension = $pathinfo['extension'];
$target_name = $pathinfo['filename'];
$relative_path = str_replace($root, '', $path);
// ISOs get booted like SAN targets
if ($extension == 'iso') {
return [$target_name => "sanboot $host/$http_root/$relative_path"];
// EFI scripts get chainloaded
} else if ($extension == 'pxe') {
return [$target_name => "chain --autofree $host/$http_root/$relative_path"];
// TXT files contain custom entries
} else if ($extension == 'txt') {
return [$target_name => trim(file_get_contents($path))];
}
}
function walkDirectory($root, $http_root, $host) {
$targets = [];
$directory_name = basename($root);
// Attempt to load a config file
if (file_exists("$root/config.ini")) {
$kernel_targets = parse_ini_file("$root/config.ini", true);
}
if ( isset( $kernel_targets ) ) {
foreach( $kernel_targets as $target_name => $target ) {
$kernel = $target['kernel'];
$initrd = $target['initrd'];
$kernel_args = "initrd=$initrd " . $target['bootargs'];
$kernel_args = template($kernel_args, ['hostpath'=>"$host/$root/"]);
// TODO For debian
//$kernel_args = "nomodeset initrd=$initrd fetch=$host/squashfs";
$boot_cmd = "kernel $host/$http_root/$kernel $kernel_args && " .
"initrd $host/$http_root/$initrd && " .
"boot";
$targets[$target_name] = $boot_cmd;
}
return [$directory_name => $targets];
}
// $root isn't a netboot directory, iterate through every file
$files = new RecursiveDirectoryIterator($root,
RecursiveDirectoryIterator::SKIP_DOTS);
foreach($files as $file) {
$path = $file->getPathname();
if ($file->isDir()) {
$directory_targets = walkDirectory($path, $http_root, $host);
$targets = array_merge_recursive ($targets, $directory_targets);
} else if ($file->isFile()) {
$file_target = addFileTarget($root, $http_root, $path, $host);
if ($file_target)
$targets = array_merge_recursive ($targets, $file_target);
}
}
return [$directory_name => $targets];
}
function generateMenu($targets, $labels) {
$menu = [];
foreach($targets as $label => $target) {
if ( is_array($target) ) {
if ($labels) array_push($menu, "item --gap $label");
$menu = array_merge($menu, generateMenu($target, $labels));
} else {
$key = md5($target);
if ($labels) array_push($menu, "item $key - Boot $label");
else array_push($menu, "iseq \${boot} $key && $target ||");
}
}
return $menu;
}
function getMenu($root, $http_root) {
if (isset($_SERVER['HTTP_HOST'])) $host = 'http://'.$_SERVER['HTTP_HOST'].'/';
else $host = 'http://example.com/';
$menu = ["#!ipxe"];
array_push($menu, "menu Select Boot Option");
$targets = walkDirectory($root, $http_root, $host)[basename($root)];
$menu = array_merge($menu, generateMenu($targets, true));
// Display the menu selector
array_push($menu, "choose boot");
$menu = array_merge($menu, generateMenu($targets, false));
return $menu;
}
header("Content-Type: text/plain");
$config = parse_ini_file('config/config.ini');
$menu = getMenu($config['boot_root'], $config['http_root']);
foreach ($menu as $line)
echo("$line\n");