diff --git a/.gitignore b/.gitignore
index 0c6c638..a69cd41 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch
+/zig_compiler
# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump
diff --git a/config/config.exs b/config/config.exs
index b40de2b..fdb6cbd 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -66,6 +66,10 @@ config :compass_admin, CompassAdmin.Agents.GatewayAgent,
input: ["\n"],
execute: "pyinfra prod-nodes.py prod-nginx-deploy.py"
+config :compass_admin, CompassAdmin.Agents.ProxyAgent,
+ input: [""],
+ execute: "pyinfra prod-nodes.py prod-proxy-restart.py"
+
config :compass_admin, CompassAdminWeb.ConfigurationLive,
execute:
"cd {config_dir} && git config user.name {username} && git config user.email {useremail} && git add {config_path} && git commit -m '{commit_message}' && git push"
diff --git a/lib/compass_admin/agents/proxy_agent.ex b/lib/compass_admin/agents/proxy_agent.ex
new file mode 100644
index 0000000..3ce59f7
--- /dev/null
+++ b/lib/compass_admin/agents/proxy_agent.ex
@@ -0,0 +1,61 @@
+defmodule CompassAdmin.Agents.ProxyAgent do
+ use GenServer
+
+ alias CompassAdmin.User
+ alias CompassAdmin.Agents.DeployAgent
+
+ @agent_svn "proxy_v1"
+
+ def start_link(_) do
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
+ end
+
+ def init(_) do
+ {:ok, DeployAgent.init(@agent_svn)}
+ end
+
+ def execute(trigger_id) do
+ GenServer.cast(__MODULE__, {:deploy, trigger_id})
+ end
+
+ def get_state() do
+ GenServer.call(__MODULE__, :get_state)
+ end
+
+ def update_deploy_state(deploy_state, last_deploy_id, last_deploy_result) do
+ GenServer.cast(
+ __MODULE__,
+ {:update_deploy_state, deploy_state, last_deploy_id, last_deploy_result}
+ )
+ end
+
+ def append_log(log) do
+ GenServer.cast(__MODULE__, {:append, log})
+ end
+
+ def handle_call(:get_state, _from, state) do
+ {:reply, state, state}
+ end
+
+ def handle_cast({:update_deploy_state, deploy_state, last_deploy_id, last_deploy_result}, state) do
+ {:noreply,
+ DeployAgent.update_deploy_state(
+ state,
+ deploy_state,
+ last_deploy_id,
+ last_deploy_result
+ )}
+ end
+
+ def handle_cast({:append, log}, state) do
+ {:noreply, DeployAgent.append_log(state, log)}
+ end
+
+ def handle_cast({:deploy, trigger_id}, state) do
+ {:noreply, DeployAgent.deploy(__MODULE__, state, trigger_id, User.frontend_dev_role())}
+ end
+
+ def handle_info(_msg, state) do
+ {:noreply, state}
+ end
+end
diff --git a/lib/compass_admin/application.ex b/lib/compass_admin/application.ex
index 5be3890..166ae82 100644
--- a/lib/compass_admin/application.ex
+++ b/lib/compass_admin/application.ex
@@ -65,7 +65,8 @@ defmodule CompassAdmin.Application do
# Deployment agents
{CompassAdmin.Agents.GatewayAgent, []},
{CompassAdmin.Agents.BackendAgent, []},
- {CompassAdmin.Agents.FrontendAgent, []}
+ {CompassAdmin.Agents.FrontendAgent, []},
+ {CompassAdmin.Agents.ProxyAgent, []},
] |> Enum.reject(&is_nil/1)
CompassAdmin.Plug.MetricsExporter.setup()
diff --git a/lib/compass_admin_web/live/backoffice/layout.ex b/lib/compass_admin_web/live/backoffice/layout.ex
index b604558..adabc62 100644
--- a/lib/compass_admin_web/live/backoffice/layout.ex
+++ b/lib/compass_admin_web/live/backoffice/layout.ex
@@ -91,6 +91,11 @@ defmodule CompassAdminWeb.Live.Backoffice.Layout do
label: "Backend Applications",
link: "/admin/deployments/backend",
icon: ruby_icon()
+ },
+ %{
+ label: "Proxy Applications",
+ link: "/admin/deployments/proxy",
+ icon: proxy_icon()
}
]
},
diff --git a/lib/compass_admin_web/live/proxy_deployment_live.ex b/lib/compass_admin_web/live/proxy_deployment_live.ex
new file mode 100644
index 0000000..ecf1392
--- /dev/null
+++ b/lib/compass_admin_web/live/proxy_deployment_live.ex
@@ -0,0 +1,88 @@
+defmodule CompassAdminWeb.ProxyDeploymentLive do
+ use CompassAdminWeb, :live_view
+
+ alias CompassAdmin.User
+ alias CompassAdmin.Agents.ProxyAgent
+
+ import CompassAdmin.Utils, only: [apm_call: 3]
+
+ @impl true
+ def mount(_params, %{"current_user" => current_user}, socket) do
+ if connected?(socket), do: Process.send_after(self(), :refresh, 5000)
+
+ state = apm_call(ProxyAgent, :get_state, [])
+ last_deploy_user = User.find(state.last_deploy_id, preloads: :login_binds)
+ last_trigger_user = User.find(state.last_trigger_id, preloads: :login_binds)
+ last_deployer = if last_deploy_user, do: List.first(last_deploy_user.login_binds)
+ last_trigger = if last_trigger_user, do: List.first(last_trigger_user.login_binds)
+ can_deploy = current_user.role_level >= User.frontend_dev_role()
+
+ {:ok,
+ assign(socket,
+ title: "Proxy recent deployment logs",
+ agent_state: state,
+ can_deploy: can_deploy,
+ current_user: current_user,
+ last_trigger: last_trigger,
+ last_deployer: last_deployer
+ )}
+ end
+
+ @impl true
+ def handle_params(_params, _uri, socket) do
+ case socket.assigns.live_action do
+ :index ->
+ {:noreply, assign(socket, action: :index)}
+ end
+ end
+
+ @impl true
+ def handle_info(:refresh, socket) do
+ Process.send_after(self(), :refresh, 5000)
+
+ state = apm_call(ProxyAgent, :get_state, [])
+ last_deploy_user = User.find(state.last_deploy_id, preloads: :login_binds)
+ last_trigger_user = User.find(state.last_trigger_id, preloads: :login_binds)
+ last_deployer = if last_deploy_user, do: List.first(last_deploy_user.login_binds)
+ last_trigger = if last_trigger_user, do: List.first(last_trigger_user.login_binds)
+
+ {:noreply,
+ assign(socket,
+ agent_state: state,
+ last_trigger: last_trigger,
+ last_deployer: last_deployer
+ )}
+ end
+
+ @impl true
+ def handle_event("deploy", _value, socket) do
+ apm_call(ProxyAgent, :execute, [socket.assigns.current_user.id])
+ Process.sleep(1000)
+ state = apm_call(ProxyAgent, :get_state, [])
+ last_deploy_user = User.find(state.last_deploy_id, preloads: :login_binds)
+ last_trigger_user = User.find(state.last_trigger_id, preloads: :login_binds)
+ last_deployer = if last_deploy_user, do: List.first(last_deploy_user.login_binds)
+ last_trigger = if last_trigger_user, do: List.first(last_trigger_user.login_binds)
+
+ {:noreply,
+ assign(socket,
+ agent_state: state,
+ last_trigger: last_trigger,
+ last_deployer: last_deployer
+ )}
+ end
+
+ @impl true
+ def render(assigns) do
+ ~H"""
+ <.deployment_page
+ title={@title}
+ agent_state={@agent_state}
+ last_trigger={@last_trigger}
+ last_deployer={@last_deployer}
+ can_deploy={@can_deploy}
+ >
+
+ """
+ end
+end
diff --git a/lib/compass_admin_web/router.ex b/lib/compass_admin_web/router.ex
index ac138e3..3251743 100644
--- a/lib/compass_admin_web/router.ex
+++ b/lib/compass_admin_web/router.ex
@@ -40,6 +40,7 @@ defmodule CompassAdminWeb.Router do
live "/gitee/issues", GiteeIssuesLive, :index
live "/gitee/issues/bulk", GiteeIssuesLive, :bulk
+ live "/deployments/proxy", ProxyDeploymentLive, :index
live "/deployments/gateway", GatewayDeploymentLive, :index
live "/deployments/backend", BackendDeploymentLive, :index
live "/deployments/frontend", FrontendDeploymentLive, :index
diff --git a/lib/compass_admin_web/views/icons_helpers.ex b/lib/compass_admin_web/views/icons_helpers.ex
index 5e04b27..6558b3d 100644
--- a/lib/compass_admin_web/views/icons_helpers.ex
+++ b/lib/compass_admin_web/views/icons_helpers.ex
@@ -65,6 +65,19 @@ defmodule CompassAdminWeb.View.IconsHelpers do
"""
end
+ def proxy_icon() do
+ """
+
+ """
+ end
+
def ruby_icon() do
"""