boot: Stop hard-coding the bridge name. master
authorRichard W.M. Jones <rjones@redhat.com>
Thu, 18 Jan 2018 11:31:02 +0000 (11:31 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Thu, 18 Jan 2018 11:31:02 +0000 (11:31 +0000)
mclu_boot.ml

index a87d710..9c1cb94 100644 (file)
@@ -26,6 +26,10 @@ open Printf
 
 open Utils
 
+let ws_rex = Pcre.regexp "\\s+"
+let br_rex = Pcre.regexp "^br\\d+"
+let virbr_rex = Pcre.regexp "^virbr\\d+"
+
 let memory = ref 0L                     (* 0 = choose for me *)
 let set_memory s =
   try memory := bytes_of_human_size s
@@ -187,6 +191,53 @@ Try: `mclu on %s'\n" hostname hostname;
              remote_image ^ ".nvram")
     | _ -> None in
 
+  (* Get the name of the remote bridge. *)
+  let bridge =
+    let cmd =
+      sprintf "ssh root@%s brctl show | sort" (quote hostname) in
+    if verbose then printf "%s\n%!" cmd;
+    let chan = Unix.open_process_in cmd in
+    let lines = ref [] in
+    (try while true do lines := input_line chan :: !lines done
+     with End_of_file -> ());
+    let stat = Unix.close_process_in chan in
+    (match stat with
+     | Unix.WEXITED 0 -> ()
+     | Unix.WEXITED i ->
+        eprintf "mclu: 'brctl show' exited with error %d\n" i;
+        exit 1
+     | Unix.WSIGNALED i ->
+        eprintf "mclu: 'brctl show' killed by signal %d\n" i;
+        exit 1
+     | Unix.WSTOPPED i ->
+        eprintf "mclu: 'brctl show' stopped by signal %d\n" i;
+        exit 1
+    );
+    let lines = List.rev !lines in
+    (* A heuristic: Use brX, but if none exist, try virbrX. *)
+    let brname = ref None in
+    let virbrname = ref None in
+    List.iter (
+      fun line ->
+        match Pcre.split ~rex:ws_rex line with
+        | str :: _ when Pcre.pmatch ~rex:br_rex str ->
+           if !brname = None then
+             brname := Some str
+        | str :: _ when Pcre.pmatch ~rex:virbr_rex str ->
+           if !virbrname = None then
+             virbrname := Some str
+        | _ -> ()
+    ) lines;
+
+    match !brname with
+    | Some br -> br
+    | None ->
+       match !virbrname with
+       | Some br -> br
+       | None ->
+          eprintf "mclu: Could not get remote bridge name\n";
+          exit 1 in
+
   (* Get ready to generate the guest XML. *)
   let vcpus = !vcpus in
   let vcpus =
@@ -294,7 +345,6 @@ Try: `mclu on %s'\n" hostname hostname;
         else
           "" in
 
-    (* XXX Don't hard-code bridge name here. *)
     let network_model =
       match template_info with
       | { Template.network_model = None } -> "virtio"
@@ -302,10 +352,10 @@ Try: `mclu on %s'\n" hostname hostname;
     let xml = xml ^ sprintf "\
     <interface type='bridge'>
       <mac address='%s'/>
-      <source bridge='br0'/>
+      <source bridge='%s'/>
       <model type='%s'/>
     </interface>
-" mac_addr network_model in
+" mac_addr bridge network_model in
 
     let xml = xml ^ "\
     <serial type='pty'>
@@ -403,8 +453,7 @@ Try: `mclu on %s'\n" hostname hostname;
     let fpf fs = fprintf chan fs in
     fpf "#!/bin/bash\n";
     fpf "set -e\n";
-    (* XXX Don't hard-code network_bridge here. *)
-    fpf "export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=br0\n";
+    fpf "export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=%s\n" bridge;
     fpf "export base_image=%s\n" (quote template_info.Template.base_image);
     fpf "export format=%s\n" (quote format);
     fpf "export guest_arch=%s\n" (quote guest_arch);