Skip to content

Commit 0f72d6b

Browse files
author
Jean Parpaillon
committed
Default delta updater can delta non-block resources
Requires fwup >= 1.10.0 Closes #885
1 parent 3e21b08 commit 0f72d6b

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

apps/nerves_hub_web_core/lib/nerves_hub_web_core/devices.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ defmodule NervesHubWebCore.Devices do
2323
alias NervesHubWebCore.Devices.{Device, DeviceCertificate, CACertificate}
2424
alias NervesHubWebCore.TaskSupervisor, as: Tasks
2525

26-
@min_fwup_delta_updatable_version ">=1.6.0"
26+
@min_fwup_delta_updatable_version ">=1.10.0"
2727

2828
def get_device(device_id), do: Repo.get(Device, device_id)
2929
def get_device!(device_id), do: Repo.get!(Device, device_id)

apps/nerves_hub_web_core/lib/nerves_hub_web_core/firmwares/delta_updater/default.ex

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,45 +31,75 @@ defmodule NervesHubWebCore.Firmwares.DeltaUpdater.Default do
3131
)
3232

3333
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+
36+
do_delta_file(source_path, target_path, output_path, work_dir)
37+
end
38+
39+
@impl NervesHubWebCore.Firmwares.DeltaUpdater
40+
def cleanup_firmware_delta_files(firmware_delta_path) do
41+
firmware_delta_path
42+
|> Path.dirname()
43+
|> File.rm_rf!()
44+
45+
:ok
46+
end
47+
48+
@impl NervesHubWebCore.Firmwares.DeltaUpdater
49+
def delta_updatable?(file_path) do
50+
{meta, 0} = System.cmd("unzip", ["-qqp", file_path, "meta.conf"])
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+
defp do_delta_file(source_path, target_path, output_path, work_dir) do
57+
File.mkdir_p(work_dir)
3558

3659
source_work_dir = Path.join(work_dir, "source")
3760
target_work_dir = Path.join(work_dir, "target")
3861
output_work_dir = Path.join(work_dir, "output")
3962

4063
File.mkdir_p(source_work_dir)
4164
File.mkdir_p(target_work_dir)
42-
File.mkdir_p(Path.join(output_work_dir, "data"))
65+
File.mkdir_p(output_work_dir)
4366

4467
{_, 0} = System.cmd("unzip", ["-qq", source_path, "-d", source_work_dir])
4568
{_, 0} = System.cmd("unzip", ["-qq", target_path, "-d", target_work_dir])
4669

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])
70+
for path <- Path.wildcard(target_work_dir <> "/**") do
71+
path = Regex.replace(~r/^#{target_work_dir}\//, path, "")
72+
unless File.dir?(Path.join(target_work_dir, path)) do
73+
:ok = handle_content(path, source_work_dir, target_work_dir, output_work_dir)
74+
end
75+
end
5376

54-
File.mkdir_p!(Path.dirname(output))
55-
File.cp!(target_path, output)
77+
{_, 0} = System.cmd("zip", ["-r", "-qq", output_path, "."], cd: output_work_dir)
78+
output_path
79+
end
5680

57-
{_, 0} = System.cmd("zip", ["-qq", output, "data/rootfs.img"], cd: output_work_dir)
58-
output
81+
defp handle_content("meta." <> _ = path, _source_dir, target_dir, out_dir) do
82+
do_copy(Path.join(target_dir, path), Path.join(out_dir, path))
5983
end
6084

61-
@impl NervesHubWebCore.Firmwares.DeltaUpdater
62-
def cleanup_firmware_delta_files(firmware_delta_path) do
63-
firmware_delta_path
64-
|> Path.dirname()
65-
|> File.rm_rf!()
85+
defp handle_content(path, source_dir, target_dir, out_dir) do
86+
do_delta(Path.join(source_dir, path), Path.join(target_dir, path), Path.join(out_dir, path))
87+
end
6688

67-
:ok
89+
defp do_copy(source, target) do
90+
target |> Path.dirname() |> File.mkdir_p!()
91+
File.cp(source, target)
6892
end
6993

70-
@impl NervesHubWebCore.Firmwares.DeltaUpdater
71-
def delta_updatable?(file_path) do
72-
{meta, 0} = System.cmd("unzip", ["-qqp", file_path, "meta.conf"])
73-
meta =~ "delta-source-raw-offset" && meta =~ "delta-source-raw-count"
94+
defp do_delta(source, target, out) do
95+
out |> Path.dirname() |> File.mkdir_p!()
96+
97+
with {_, 0} <-
98+
System.cmd("xdelta3", ["-A", "-S", "-f", "-s", source, target, out]) do
99+
:ok
100+
else
101+
{_, code} ->
102+
{:error, code}
103+
end
74104
end
75105
end

apps/nerves_hub_web_core/test/nerves_hub_web_core/devices/devices_test.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ defmodule NervesHubWebCore.DevicesTest do
1616
alias NervesHubWebCore.Devices.{DeviceCertificate, UpdatePayload}
1717
alias Ecto.Changeset
1818

19-
@valid_fwup_version "1.6.0"
19+
@valid_fwup_version "1.10.0"
2020

2121
setup do
2222
user = Fixtures.user_fixture()
@@ -616,7 +616,7 @@ defmodule NervesHubWebCore.DevicesTest do
616616

617617
deployment = Fixtures.deployment_fixture(org, target, %{name: "resolve-update"})
618618
device = Fixtures.device_fixture(org, product, source)
619-
{:ok, device} = Devices.update_firmware_metadata(device, %{fwup_version: "1.6.0"})
619+
{:ok, device} = Devices.update_firmware_metadata(device, %{fwup_version: "1.10.0"})
620620
%{firmware_metadata: %{fwup_version: fwup_version}} = device
621621

622622
firmware_delta = Fixtures.firmware_delta_fixture(source, target)
@@ -642,7 +642,7 @@ defmodule NervesHubWebCore.DevicesTest do
642642

643643
deployment = Fixtures.deployment_fixture(org, target, %{name: "resolve-update"})
644644
device = Fixtures.device_fixture(org, product, source)
645-
{:ok, device} = Devices.update_firmware_metadata(device, %{fwup_version: "1.6.0"})
645+
{:ok, device} = Devices.update_firmware_metadata(device, %{fwup_version: "1.10.0"})
646646
%{firmware_metadata: %{fwup_version: fwup_version}} = device
647647

648648
assert Devices.delta_updatable?(source, target, deployment, fwup_version)

0 commit comments

Comments
 (0)