diff --git a/lib/formation/lxd.ex b/lib/formation/lxd.ex index 7a83ce7..d854779 100644 --- a/lib/formation/lxd.ex +++ b/lib/formation/lxd.ex @@ -152,7 +152,9 @@ defmodule Formation.Lxd do err_output |> String.split("\n") |> Enum.reject(fn err -> - err in ignored_errors + Enum.any?(ignored_errors, fn ignored_err -> + err =~ ignored_err + end) end) end diff --git a/lib/formation/lxd/alpine/package.ex b/lib/formation/lxd/alpine/package.ex index 0d06e98..e607fde 100644 --- a/lib/formation/lxd/alpine/package.ex +++ b/lib/formation/lxd/alpine/package.ex @@ -13,6 +13,7 @@ defmodule Formation.Lxd.Alpine.Package do @ignored_errors [ ~s(Run "rc-update add s6 default" to automatically start a s6 supervision tree on /run/service at boot time.), + ~s(* WARNING: {{package}} is already stopped), "" ] @@ -47,11 +48,13 @@ defmodule Formation.Lxd.Alpine.Package do ) do package_slugs = slugs(packages) + ignored_errors = process_errors(packages) + command = """ apk update && apk add --upgrade #{package_slugs} """ - Lxd.execute_and_log(client, slug, command, ignored_errors: @ignored_errors, project: project) + Lxd.execute_and_log(client, slug, command, ignored_errors: ignored_errors, project: project) end defp slugs(packages) do @@ -59,4 +62,14 @@ defmodule Formation.Lxd.Alpine.Package do |> Enum.map(fn package -> package.slug end) |> Enum.join(" ") end + + defp process_errors(packages) do + @ignored_errors + |> Enum.flat_map(fn error -> + Enum.map(packages, fn package -> + Mustache.render(error, %{package: package.slug}) + end) + end) + |> Enum.uniq() + end end diff --git a/mix.exs b/mix.exs index d4ac820..448d196 100644 --- a/mix.exs +++ b/mix.exs @@ -58,6 +58,7 @@ defmodule Formation.MixProject do {:tesla, "~> 1.7.0"}, {:postgrex, "~> 0.17.1"}, {:ecto, "~> 3.10"}, + {:mustache, "~> 0.5.0"}, # {:dep_from_hexpm, "~> 0.3.0"}, # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} {:exvcr, "~> 0.11", only: :test}, diff --git a/mix.lock b/mix.lock index 7338344..bfbf921 100644 --- a/mix.lock +++ b/mix.lock @@ -25,6 +25,7 @@ "mint": {:hex, :mint, "1.5.1", "8db5239e56738552d85af398798c80648db0e90f343c8469f6c6d8898944fb6f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4a63e1e76a7c3956abd2c72f370a0d0aecddc3976dea5c27eccbecfa5e7d5b1e"}, "mint_web_socket": {:hex, :mint_web_socket, "1.0.3", "aab42fff792a74649916236d0b01f560a0b3f03ca5dea693c230d1c44736b50e", [:mix], [{:mint, ">= 1.4.1 and < 2.0.0-0", [hex: :mint, repo: "hexpm", optional: false]}], "hexpm", "ca3810ca44cc8532e3dce499cc17f958596695d226bb578b2fbb88c09b5954b0"}, "mox": {:hex, :mox, "1.0.2", "dc2057289ac478b35760ba74165b4b3f402f68803dd5aecd3bfd19c183815d64", [:mix], [], "hexpm", "f9864921b3aaf763c8741b5b8e6f908f44566f1e427b2630e89e9a73b981fef2"}, + "mustache": {:hex, :mustache, "0.5.1", "1bfee8a68a8e72d47616541a93a632ae1684c1abc17c9eb5f7bfecb78d7496e5", [:mix], [], "hexpm", "524c9bbb6080a52d7b6806436b4e269e0224c785a228faf3293ef30a75016bfa"}, "nimble_options": {:hex, :nimble_options, "1.0.2", "92098a74df0072ff37d0c12ace58574d26880e522c22801437151a159392270e", [:mix], [], "hexpm", "fd12a8db2021036ce12a309f26f564ec367373265b53e25403f0ee697380f1b8"}, "nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"}, "nimble_pool": {:hex, :nimble_pool, "1.0.0", "5eb82705d138f4dd4423f69ceb19ac667b3b492ae570c9f5c900bb3d2f50a847", [:mix], [], "hexpm", "80be3b882d2d351882256087078e1b1952a28bf98d0a287be87e4a24a710b67a"}, diff --git a/test/formation/lxd_test.exs b/test/formation/lxd_test.exs index cf244d3..63d75de 100644 --- a/test/formation/lxd_test.exs +++ b/test/formation/lxd_test.exs @@ -100,6 +100,8 @@ defmodule Formation.LxdTest do cat /var/lib/something """ + error_text = "Failed to retrieve PID of executing child process" + Formation.LexdeeMock |> expect(:execute_command, fn _client, "example-test-1", command, _options -> assert cmd == command @@ -113,12 +115,117 @@ defmodule Formation.LxdTest do %{ body: %{ "status_code" => 400, - "err" => "Failed to retrieve PID of executing child process" + "err" => error_text } }} end) - assert {:error, _error} = Lxd.execute_and_log(client, "example-test-1", cmd) + assert {:error, error} = Lxd.execute_and_log(client, "example-test-1", cmd) + assert %{"err" => ^error_text} = error + end + + test "ignored error", %{client: client} do + cmd = """ + cat /var/lib/something + """ + + Formation.LexdeeMock + |> expect(:execute_command, fn _client, "example-test-1", command, _options -> + assert cmd == command + + {:ok, %{body: %{"id" => @uuid}}} + end) + + Formation.LexdeeMock + |> expect(:wait_for_operation, fn _client, _uuid, _options -> + {:ok, + %{ + body: %{ + "status_code" => 200, + "metadata" => %{ + "output" => %{ + "1" => "stdout.log", + "2" => "stderr.log" + } + } + } + }} + end) + + Formation.LexdeeMock + |> expect(:show_instance_log, fn _client, "example-test-1", "stdout.log", options -> + assert [query: [project: project]] = options + + assert project == "default" + + {:ok, %{body: "some-url"}} + end) + + Formation.LexdeeMock + |> expect(:show_instance_log, fn _client, "example-test-1", "stderr.log", options -> + assert [query: [project: project]] = options + + assert project == "default" + + {:ok, %{body: " * WARNING: some-package is already stopped"}} + end) + + assert {:ok, "some-url"} = + Lxd.execute_and_log(client, "example-test-1", cmd, + ignored_errors: ["* WARNING: some-package is already stopped"] + ) + end + + test "error not ignored", %{client: client} do + cmd = """ + cat /var/lib/something + """ + + Formation.LexdeeMock + |> expect(:execute_command, fn _client, "example-test-1", command, _options -> + assert cmd == command + + {:ok, %{body: %{"id" => @uuid}}} + end) + + Formation.LexdeeMock + |> expect(:wait_for_operation, fn _client, _uuid, _options -> + {:ok, + %{ + body: %{ + "status_code" => 200, + "metadata" => %{ + "output" => %{ + "1" => "stdout.log", + "2" => "stderr.log" + } + } + } + }} + end) + + Formation.LexdeeMock + |> expect(:show_instance_log, fn _client, "example-test-1", "stdout.log", options -> + assert [query: [project: project]] = options + + assert project == "default" + + {:ok, %{body: "some-url"}} + end) + + Formation.LexdeeMock + |> expect(:show_instance_log, fn _client, "example-test-1", "stderr.log", options -> + assert [query: [project: project]] = options + + assert project == "default" + + {:ok, %{body: "Some error happened"}} + end) + + assert {:error, "Some error happened"} = + Lxd.execute_and_log(client, "example-test-1", cmd, + ignored_errors: ["* WARNING: some-package is already stopped"] + ) end end