---
src/build.ml | 43 ++++++++++++++++++++++++++-----------------
src/chroot.ml | 12 +++++++-----
src/dpkg.ml | 17 +++++++++++++++--
src/ext2.ml | 8 +++++++-
4 files changed, 55 insertions(+), 25 deletions(-)
diff --git a/src/build.ml b/src/build.ml
index 9225184..205701b 100644
--- a/src/build.ml
+++ b/src/build.ml
@@ -106,11 +106,7 @@ let rec build debug
*)
let files = get_all_files packages in
let files =
- filter_map (
- function
- | { ft_config = false; ft_path = path } -> Some path
- | { ft_config = true } -> None
- ) files in
+ List.filter (fun file -> not file.ft_config) files in
if debug >= 1 then
printf "supermin: build: %d files\n%!" (List.length files);
@@ -120,9 +116,11 @@ let rec build debug
*)
let files =
List.filter (
- fun path ->
- try ignore (lstat path); true
- with Unix_error (err, fn, _) -> false
+ fun file ->
+ try ignore (lstat file.ft_source_path); true
+ with Unix_error (err, fn, _) ->
+ try ignore (lstat file.ft_path); true
+ with Unix_error (err, fn, _) -> false
) files in
if debug >= 1 then
@@ -139,9 +137,9 @@ let rec build debug
else (
let fn_flags = [FNM_NOESCAPE] in
List.filter (
- fun path ->
+ fun file ->
List.for_all (
- fun pattern -> not (fnmatch pattern path fn_flags)
+ fun pattern -> not (fnmatch pattern file.ft_path fn_flags)
) appliance.excludefiles
) files
) in
@@ -159,7 +157,9 @@ let rec build debug
) appliance.hostfiles in
let hostfiles = List.map Array.to_list hostfiles in
let hostfiles = List.flatten hostfiles in
- files @ hostfiles
+ files @ (List.map
+ (fun path -> {ft_path = path; ft_source_path = path; ft_config =
false})
+ hostfiles)
) in
if debug >= 1 then
@@ -326,7 +326,9 @@ and isalnum = function
* symlink.
*)
and munge files =
- let files = List.sort compare files in
+ let paths =
+ List.sort compare
+ (List.map (fun file -> file.ft_path) files) in
let rec stat_is_dir dir =
try (stat dir).st_kind = S_DIR with Unix_error _ -> false
@@ -336,7 +338,7 @@ and munge files =
in
let insert_dir, dir_seen =
- let h = Hashtbl.create (List.length files) in
+ let h = Hashtbl.create (List.length paths) in
let insert_dir dir = Hashtbl.replace h dir true in
let dir_seen dir = Hashtbl.mem h dir in
insert_dir, dir_seen
@@ -385,10 +387,17 @@ and munge files =
(* Have we seen this parent directory before? *)
let dir = Filename.dirname file in
if not (dir_seen dir) then
- loop (dir :: file :: rest)
+ loop (dir :: rest)
else
- file :: loop rest
+ loop rest
in
- let files = loop files in
+ let dir_paths = loop paths in
+
+ let dirs = List.map (fun path ->
+ {ft_path = path; ft_source_path = path; ft_config = false}
+ ) dir_paths in
+ let files = List.filter (fun file ->
+ not (dir_seen file.ft_path)
+ ) files in
- files
+ dirs @ files
diff --git a/src/chroot.ml b/src/chroot.ml
index 1e1ddb2..b5c1e53 100644
--- a/src/chroot.ml
+++ b/src/chroot.ml
@@ -20,13 +20,15 @@ open Unix
open Printf
open Utils
+open Package_handler
let build_chroot debug files outputdir =
List.iter (
- fun path ->
+ fun file ->
try
+ let path = file.ft_source_path in
let st = lstat path in
- let opath = outputdir // path in
+ let opath = outputdir // file.ft_path in
match st.st_kind with
| S_DIR ->
(* Note we fix up the permissions of directories in a second
@@ -65,9 +67,9 @@ let build_chroot debug files outputdir =
(* Second pass: fix up directory permissions in reverse. *)
let dirs = filter_map (
- fun path ->
- let st = lstat path in
- if st.st_kind = S_DIR then Some (path, st) else None
+ fun file ->
+ let st = lstat file.ft_source_path in
+ if st.st_kind = S_DIR then Some (file.ft_path, st) else None
) files in
List.iter (
fun (path, st) ->
diff --git a/src/dpkg.ml b/src/dpkg.ml
index 5a650b8..efc8123 100644
--- a/src/dpkg.ml
+++ b/src/dpkg.ml
@@ -155,6 +155,17 @@ let dpkg_get_all_requires pkgs =
loop pkgs
let dpkg_get_all_files pkgs =
+ let cmd = sprintf "%s --list" Config.dpkg_divert in
+ let lines = run_command_get_lines cmd in
+ let diversions = Hashtbl.create (List.length lines) in
+ List.iter (
+ fun line ->
+ let items = string_split " " line in
+ match items with
+ | ["diversion"; "of"; path; "to"; real_path;
"by"; pkg] ->
+ Hashtbl.add diversions path real_path
+ | _ -> ()
+ ) lines;
let cmd =
sprintf "%s --listfiles %s | grep '^/' | grep -v '^/.$' | sort
-u"
Config.dpkg_query
@@ -166,8 +177,10 @@ let dpkg_get_all_files pkgs =
let config =
try string_prefix "/etc/" path && (lstat path).st_kind = S_REG
with Unix_error _ -> false in
- let cmd = sprintf "%s --truename %s" Config.dpkg_divert path in
- { ft_path = path; ft_source_path = path; ft_config = config }
+ let source_path =
+ try Hashtbl.find diversions path
+ with Not_found -> path in
+ { ft_path = path; ft_source_path = source_path; ft_config = config }
) lines
let dpkg_download_all_packages pkgs dir =
diff --git a/src/ext2.ml b/src/ext2.ml
index 701f52e..ccaa81f 100644
--- a/src/ext2.ml
+++ b/src/ext2.ml
@@ -21,6 +21,7 @@ open Printf
open Utils
open Ext2fs
+open Package_handler
(* The ext2 image that we build always has a fixed size, and we 'hope'
* that the files fit in (otherwise we'll get an error). Note that
@@ -66,7 +67,12 @@ let build_ext2 debug basedir files modpath kernel_version appliance =
printf "supermin: ext2: copying files from host filesystem\n%!";
(* Copy files from host filesystem. *)
- List.iter (fun path -> ext2fs_copy_file_from_host fs path path) files;
+ List.iter (fun file ->
+ if file_exists file.ft_source_path then
+ ext2fs_copy_file_from_host fs file.ft_source_path file.ft_path
+ else
+ ext2fs_copy_file_from_host fs file.ft_path file.ft_path
+ ) files;
if debug >= 1 then
printf "supermin: ext2: copying kernel modules\n%!";
--
1.9.0