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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
|
(* virt-dib
* Copyright (C) 2015 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*)
(* Command line argument parsing. *)
open Std_utils
open Tools_utils
open Common_gettext.Gettext
open Getopt.OptionName
open Utils
open Printf
type cmdline = {
debug : int;
basepath : string;
elements : string list;
excluded_elements : string list;
element_paths : string list;
excluded_scripts : string list;
use_base : bool;
drive : string option;
drive_format : string option;
image_name : string;
fs_type : string;
size : int64;
root_label : string option;
install_type : string;
image_cache : string option;
mkfs_options : string option;
is_ramdisk : bool;
ramdisk_element : string;
extra_packages : string list;
memsize : int option;
network : bool;
smp : int option;
delete_on_failure : bool;
formats : Output_format.set;
arch : string;
envvars : string list;
checksum : bool;
python : string option;
}
let parse_cmdline () =
let usage_msg =
sprintf (f_"\
%s: run diskimage-builder elements to generate images
virt-dib -B DIB-LIB -p ELEMENTS-PATH elements...
A short summary of the options is given below. For detailed help please
read the man page virt-dib(1).
")
prog in
let elements = ref [] in
let append_element element = List.push_front element elements in
let excluded_elements = ref [] in
let append_excluded_element element = List.push_front element excluded_elements in
let element_paths = ref [] in
let append_element_path arg = List.push_front arg element_paths in
let excluded_scripts = ref [] in
let append_excluded_script arg = List.push_front arg excluded_scripts in
let debug = ref 0 in
let set_debug arg =
if arg < 0 then
error (f_"--debug parameter must be >= 0");
debug := arg in
let basepath = ref "" in
let image_name = ref "image" in
let fs_type = ref "ext4" in
let size = ref (unit_GB 5) in
let set_size arg = size := parse_size arg in
let memsize = ref None in
let set_memsize arg = memsize := Some arg in
let network = ref true in
let smp = ref None in
let set_smp arg = smp := Some arg in
let formats = ref None in
let set_format arg =
let fmts = List.remove_duplicates (String.nsplit "," arg) in
let fmtset =
List.fold_left (
fun fmtset fmt ->
try Output_format.add_to_set fmt fmtset
with Not_found ->
error (f_"invalid format ‘%s’ in --formats") fmt
) Output_format.empty_set fmts in
formats := Some fmtset in
let envvars = ref [] in
let append_envvar arg = List.push_front arg envvars in
let use_base = ref true in
let arch = ref "" in
let drive = ref None in
let set_drive arg = drive := Some arg in
let drive_format = ref None in
let set_drive_format arg = drive_format := Some arg in
let root_label = ref None in
let set_root_label arg = root_label := Some arg in
let install_type = ref "source" in
let image_cache = ref None in
let set_image_cache arg = image_cache := Some arg in
let delete_on_failure = ref true in
let is_ramdisk = ref false in
let ramdisk_element = ref "ramdisk" in
let mkfs_options = ref None in
let set_mkfs_options arg = mkfs_options := Some arg in
let extra_packages = ref [] in
let append_extra_packages arg =
List.push_front_list (List.rev (String.nsplit "," arg)) extra_packages in
let checksum = ref false in
let python = ref None in
let set_python arg = python := Some arg in
let argspec = [
[ S 'p'; L"element-path" ], Getopt.String ("path", append_element_path), s_"Add new a elements location";
[ L"exclude-element" ], Getopt.String ("element", append_excluded_element),
s_"Exclude the specified element";
[ L"exclude-script" ], Getopt.String ("script", append_excluded_script),
s_"Exclude the specified script";
[ L"envvar" ], Getopt.String ("envvar[=value]", append_envvar), s_"Carry/set this environment variable";
[ L"skip-base" ], Getopt.Clear use_base, s_"Skip the inclusion of the ‘base’ element";
[ L"root-label" ], Getopt.String ("label", set_root_label), s_"Label for the root fs";
[ L"install-type" ], Getopt.Set_string ("type", install_type), s_"Installation type";
[ L"image-cache" ], Getopt.String ("directory", set_image_cache), s_"Location for cached images";
[ L"mkfs-options" ], Getopt.String ("option", set_mkfs_options),
s_"Add mkfs options";
[ L"extra-packages" ], Getopt.String ("pkg,...", append_extra_packages),
s_"Add extra packages to install";
[ L"checksum" ], Getopt.Set checksum, s_"Generate MD5 and SHA256 checksum files";
[ L"python" ], Getopt.String ("python", set_python), s_"Set Python interpreter";
[ L"ramdisk" ], Getopt.Set is_ramdisk, "Switch to a ramdisk build";
[ L"ramdisk-element" ], Getopt.Set_string ("name", ramdisk_element), s_"Main element for building ramdisks";
[ L"name" ], Getopt.Set_string ("name", image_name), s_"Name of the image";
[ L"fs-type" ], Getopt.Set_string ("fs", fs_type), s_"Filesystem for the image";
[ L"size" ], Getopt.String ("size", set_size), s_"Set output disk size";
[ L"formats" ], Getopt.String ("qcow2,tgz,...", set_format), s_"Output formats";
[ L"arch" ], Getopt.Set_string ("arch", arch), s_"Output architecture";
[ L"drive" ], Getopt.String ("path", set_drive), s_"Optional drive for caches";
[ L"drive-format" ], Getopt.String (s_"format", set_drive_format), s_"Format of optional drive";
[ S 'm'; L"memsize" ], Getopt.Int ("mb", set_memsize), s_"Set memory size";
[ L"network" ], Getopt.Set network, s_"Enable appliance network (default)";
[ L"no-network" ], Getopt.Clear network, s_"Disable appliance network";
[ L"smp" ], Getopt.Int ("vcpus", set_smp), s_"Set number of vCPUs";
[ L"no-delete-on-failure" ], Getopt.Clear delete_on_failure,
s_"Don’t delete output file on failure";
[ L"debug" ], Getopt.Int ("level", set_debug), s_"Set debug level";
[ S 'B' ], Getopt.Set_string ("path", basepath), s_"Base path of diskimage-builder library";
] in
let argspec = argspec @ Output_format.extra_args () in
let opthandle = create_standard_options argspec ~anon_fun:append_element ~machine_readable:true usage_msg in
Getopt.parse opthandle.getopt;
let debug = !debug in
let basepath = !basepath in
let elements = List.rev !elements in
let excluded_elements = List.rev !excluded_elements in
let element_paths = List.rev !element_paths in
let excluded_scripts = List.rev !excluded_scripts in
let image_name = !image_name in
let fs_type = !fs_type in
let size = !size in
let memsize = !memsize in
let network = !network in
let smp = !smp in
let formats = !formats in
let envvars = !envvars in
let use_base = !use_base in
let arch = !arch in
let drive = !drive in
let drive_format = !drive_format in
let root_label = !root_label in
let install_type = !install_type in
let image_cache = !image_cache in
let delete_on_failure = !delete_on_failure in
let is_ramdisk = !is_ramdisk in
let ramdisk_element = !ramdisk_element in
let mkfs_options = !mkfs_options in
let extra_packages = List.rev !extra_packages in
let checksum = !checksum in
let python = !python in
(* No elements and machine-readable mode? Print some facts. *)
(match elements, machine_readable () with
| [], Some { pr } ->
pr "virt-dib\n";
let formats_list = Output_format.list_formats () in
List.iter (pr "output:%s\n") formats_list;
exit 0
| _, _ -> ()
);
if basepath = "" then
error (f_"-B must be specified");
let formats =
match formats with
| None -> Output_format.add_to_set "qcow2" Output_format.empty_set
| Some fmtset ->
if Output_format.set_cardinal fmtset = 0 then
error (f_"the list of output formats cannot be empty");
fmtset in
if elements = [] then
error (f_"at least one distribution root element must be specified");
let python = Option.map get_required_tool python in
{ debug = debug; basepath = basepath; elements = elements;
excluded_elements = excluded_elements; element_paths = element_paths;
excluded_scripts = excluded_scripts; use_base = use_base; drive = drive;
drive_format = drive_format; image_name = image_name; fs_type = fs_type;
size = size; root_label = root_label; install_type = install_type;
image_cache = image_cache; mkfs_options = mkfs_options;
is_ramdisk = is_ramdisk; ramdisk_element = ramdisk_element;
extra_packages = extra_packages; memsize = memsize; network = network;
smp = smp; delete_on_failure = delete_on_failure;
formats = formats; arch = arch; envvars = envvars;
checksum = checksum; python = python;
}
|