@@ -31,31 +31,9 @@ defmodule NervesHub.Firmwares.DeltaUpdater.Default do
31
31
)
32
32
33
33
output_filename = uuid <> ".fw"
34
- output = Path . join ( work_dir , output_filename ) |> Path . expand ( )
34
+ output_path = Path . join ( work_dir , output_filename ) |> Path . expand ( )
35
35
36
- source_work_dir = Path . join ( work_dir , "source" )
37
- target_work_dir = Path . join ( work_dir , "target" )
38
- output_work_dir = Path . join ( work_dir , "output" )
39
-
40
- File . mkdir_p ( source_work_dir )
41
- File . mkdir_p ( target_work_dir )
42
- File . mkdir_p ( Path . join ( output_work_dir , "data" ) )
43
-
44
- { _ , 0 } = System . cmd ( "unzip" , [ "-qq" , source_path , "-d" , source_work_dir ] )
45
- { _ , 0 } = System . cmd ( "unzip" , [ "-qq" , target_path , "-d" , target_work_dir ] )
46
-
47
- source_rootfs = Path . join ( [ source_work_dir , "data" , "rootfs.img" ] )
48
- target_rootfs = Path . join ( [ target_work_dir , "data" , "rootfs.img" ] )
49
- out_rootfs = Path . join ( [ output_work_dir , "data" , "rootfs.img" ] )
50
-
51
- { _ , 0 } =
52
- System . cmd ( "xdelta3" , [ "-A" , "-S" , "-f" , "-s" , source_rootfs , target_rootfs , out_rootfs ] )
53
-
54
- File . mkdir_p! ( Path . dirname ( output ) )
55
- File . cp! ( target_path , output )
56
-
57
- { _ , 0 } = System . cmd ( "zip" , [ "-qq" , output , "data/rootfs.img" ] , cd: output_work_dir )
58
- output
36
+ do_delta_file ( source_path , target_path , output_path , work_dir )
59
37
end
60
38
61
39
@ impl NervesHub.Firmwares.DeltaUpdater
@@ -70,6 +48,73 @@ defmodule NervesHub.Firmwares.DeltaUpdater.Default do
70
48
@ impl NervesHub.Firmwares.DeltaUpdater
71
49
def delta_updatable? ( file_path ) do
72
50
{ meta , 0 } = System . cmd ( "unzip" , [ "-qqp" , file_path , "meta.conf" ] )
73
- meta =~ "delta-source-raw-offset" && meta =~ "delta-source-raw-count"
51
+
52
+ ( meta =~ "delta-source-raw-offset" && meta =~ "delta-source-raw-count" ) or
53
+ ( meta =~ "delta-source-fat-offset" && meta =~ "delta-source-fat-path" )
54
+ end
55
+
56
+ def do_delta_file ( source_path , target_path , output_path , work_dir ) do
57
+ File . mkdir_p ( work_dir )
58
+
59
+ source_work_dir = Path . join ( work_dir , "source" )
60
+ target_work_dir = Path . join ( work_dir , "target" )
61
+ output_work_dir = Path . join ( work_dir , "output" )
62
+
63
+ File . mkdir_p ( source_work_dir )
64
+ File . mkdir_p ( target_work_dir )
65
+ File . mkdir_p ( output_work_dir )
66
+
67
+ { _ , 0 } = System . cmd ( "unzip" , [ "-qq" , source_path , "-d" , source_work_dir ] )
68
+ { _ , 0 } = System . cmd ( "unzip" , [ "-qq" , target_path , "-d" , target_work_dir ] )
69
+
70
+ _ =
71
+ for absolute <- Path . wildcard ( target_work_dir <> "/**" ) , not File . dir? ( absolute ) do
72
+ path = Path . relative_to ( absolute , target_work_dir )
73
+
74
+ if String . starts_with? ( path , "meta." ) do
75
+ File . cp! ( Path . join ( target_work_dir , path ) , Path . join ( output_work_dir , path ) )
76
+ else
77
+ args = [
78
+ "-A" ,
79
+ "-S" ,
80
+ "-f" ,
81
+ "-s" ,
82
+ Path . join ( source_work_dir , path ) ,
83
+ Path . join ( target_work_dir , path ) ,
84
+ Path . join ( output_work_dir , path )
85
+ ]
86
+
87
+ { _ , 0 } = System . cmd ( "xdelta3" , args )
88
+ end
89
+ end
90
+
91
+ # firmware archive files order matters:
92
+ # 1. meta.conf.ed25519 (optional)
93
+ # 2. meta.conf
94
+ # 3. other...
95
+ [
96
+ "meta.conf.*" ,
97
+ "meta.conf" ,
98
+ "data"
99
+ ]
100
+ |> Enum . each ( & add_to_zip ( & 1 , output_work_dir , output_path ) )
101
+
102
+ output_path
103
+ end
104
+
105
+ defp add_to_zip ( glob , workdir , output ) do
106
+ workdir
107
+ |> Path . join ( glob )
108
+ |> Path . wildcard ( )
109
+ |> case do
110
+ [ ] ->
111
+ :ok
112
+
113
+ paths ->
114
+ args = [ "-r" , "-qq" , output | Enum . map ( paths , & Path . relative_to ( & 1 , workdir ) ) ]
115
+ { _ , 0 } = System . cmd ( "zip" , args , cd: workdir )
116
+
117
+ :ok
118
+ end
74
119
end
75
120
end
0 commit comments