From 210edf6ae62be0f10f8ffcb74b12aa7796906708 Mon Sep 17 00:00:00 2001 From: Gabriel Viganotti Date: Thu, 16 Jan 2025 23:08:07 -0300 Subject: [PATCH] feaat: show node network IPs when home-network is disabled --- migrations/20250116191347_node_ips.sql | 1 + src/db_client.rs | 8 ++++++ src/docker_client.rs | 35 ++++++++++++++++++-------- src/node_instance.rs | 1 + src/nodes_list_view.rs | 26 +++++++++++++++++-- src/server_api.rs | 30 ++++++++++++++++------ style/tailwind.css | 13 ++++++++++ 7 files changed, 94 insertions(+), 20 deletions(-) create mode 100644 migrations/20250116191347_node_ips.sql diff --git a/migrations/20250116191347_node_ips.sql b/migrations/20250116191347_node_ips.sql new file mode 100644 index 0000000..81c7040 --- /dev/null +++ b/migrations/20250116191347_node_ips.sql @@ -0,0 +1 @@ +ALTER TABLE nodes ADD ips TEXT diff --git a/src/db_client.rs b/src/db_client.rs index 3fc73f8..40b98aa 100644 --- a/src/db_client.rs +++ b/src/db_client.rs @@ -64,6 +64,7 @@ struct CachedNodeMetadata { records: String, connected_peers: String, kbuckets_peers: String, + ips: String, } impl CachedNodeMetadata { @@ -101,6 +102,9 @@ impl CachedNodeMetadata { if let Ok(v) = self.kbuckets_peers.parse::() { info.kbuckets_peers = Some(v); } + if !self.ips.is_empty() { + info.ips = Some(self.ips.clone()); + } } } @@ -279,6 +283,10 @@ impl DbClient { updates.push("kbuckets_peers=?"); params.push(kbuckets_peers.to_string()); } + if let Some(ips) = &info.ips { + updates.push("ips=?"); + params.push(ips.clone()); + } if updates.is_empty() { return; // no updates to make diff --git a/src/docker_client.rs b/src/docker_client.rs index 240dcac..e813b1d 100644 --- a/src/docker_client.rs +++ b/src/docker_client.rs @@ -261,7 +261,8 @@ impl DockerClient { pub async fn start_container( &self, id: &ContainerId, - ) -> Result<(Option, Option), DockerClientError> { + get_ips: bool, + ) -> Result<(Option, Option, Option), DockerClientError> { let url = format!("{DOCKER_CONTAINERS_API}/{id}/start"); logging::log!("[START] Sending Docker request to START a container: {url} ..."); self.send_request(ReqMethod::post_empty_body(), &url, &[]) @@ -281,7 +282,7 @@ impl DockerClient { .await?; // let's try to retrieve new version - self.get_node_version_and_peer_id(id).await + self.get_node_version_and_peer_id(id, get_ips).await } // Request the Docker server to STOP a container matching the given id @@ -416,7 +417,8 @@ impl DockerClient { pub async fn upgrade_node_in_container( &self, id: &ContainerId, - ) -> Result, DockerClientError> { + get_ips: bool, + ) -> Result<(Option, Option), DockerClientError> { logging::log!("[UPGRADE] Sending Docker request to UPGRADE node within a container..."); let cmd = "./antup node -n -p /app".to_string(); @@ -442,22 +444,23 @@ impl DockerClient { } // let's try to retrieve new version, forget it if there is any error - let (new_version, _) = self - .get_node_version_and_peer_id(id) + let (new_version, _, ips) = self + .get_node_version_and_peer_id(id, get_ips) .await .unwrap_or_default(); // restart container to run with new node version self.restart_container(id).await?; - Ok(new_version) + Ok((new_version, ips)) } // Retrieve version of the node binary and its peer id pub async fn get_node_version_and_peer_id( &self, id: &ContainerId, - ) -> Result<(Option, Option), DockerClientError> { + get_ips: bool, + ) -> Result<(Option, Option, Option), DockerClientError> { let cmd = "/app/antnode --version | grep -oE 'Autonomi Node v[0-9]+\\.[0-9]+\\.[0-9]+.*$'" .to_string(); let (_, resp_str) = self @@ -481,14 +484,26 @@ impl DockerClient { }; logging::log!("Node peer id in container {id}: {peer_id:?}"); - Ok((version, peer_id)) + let ips = if get_ips { + let cmd = "hostname -I | sed 's/^[ \t]*//;s/[ \t]*$//;s/ /, /g'".to_string(); + let (_, ips) = self + .exec_in_container(id, cmd, "get node network IPs") + .await?; + logging::log!("Node IPs in container {id}: {ips}"); + Some(ips) + } else { + None + }; + + Ok((version, peer_id, ips)) } // Clears the node's PeerId within the containver and restarts it pub async fn regenerate_peer_id_in_container( &self, id: &ContainerId, - ) -> Result<(Option, Option), DockerClientError> { + get_ips: bool, + ) -> Result<(Option, Option, Option), DockerClientError> { logging::log!("[RECYCLE] Recycling container by clearing node's peer-id ..."); // we write an empty file at '/app/node_data/secret-key-recycle' so the container removes @@ -512,7 +527,7 @@ impl DockerClient { logging::log!("Finished recycling node container: {id}"); - self.get_node_version_and_peer_id(id).await + self.get_node_version_and_peer_id(id, get_ips).await } // Restart the container wich has given id diff --git a/src/node_instance.rs b/src/node_instance.rs index 08c74c7..2b5d54b 100644 --- a/src/node_instance.rs +++ b/src/node_instance.rs @@ -106,6 +106,7 @@ pub struct NodeInstanceInfo { pub kbuckets_peers: Option, pub shunned_count: Option, pub net_size: Option, + pub ips: Option, } impl NodeInstanceInfo { diff --git a/src/nodes_list_view.rs b/src/nodes_list_view.rs index e3f77fb..b3e3044 100644 --- a/src/nodes_list_view.rs +++ b/src/nodes_list_view.rs @@ -449,8 +449,30 @@ fn NodeInstanceView(

- "Home-network: " - {move || info.read().home_network} + "Home-network: " + "On" + } + } + > +

+
+ "Home-network: " + "Off" +
+
+ "IPs: " +
+
+
+ {move || info.get().ips.unwrap_or_default()} +
+
+
+

"Created: " diff --git a/src/server_api.rs b/src/server_api.rs index b93c7cf..5d9ac96 100644 --- a/src/server_api.rs +++ b/src/server_api.rs @@ -186,7 +186,10 @@ async fn helper_start_node_instance( .update_node_status(&container_id, NodeStatus::Restarting) .await; - let (version, peer_id) = context.docker_client.start_container(&container_id).await?; + let (version, peer_id, ips) = context + .docker_client + .start_container(&container_id, true) + .await?; context .db_client .update_node_metadata_fields( @@ -194,6 +197,7 @@ async fn helper_start_node_instance( &[ ("bin_version", &version.unwrap_or_default()), ("peer_id", &peer_id.unwrap_or_default()), + ("ips", &ips.unwrap_or_default()), ], ) .await; @@ -233,7 +237,11 @@ async fn helper_stop_node_instance( .db_client .update_node_metadata_fields( &container_id, - &[("connected_peers", "0"), ("kbuckets_peers", "0")], + &[ + ("connected_peers", "0"), + ("kbuckets_peers", "0"), + ("ips", ""), + ], ) .await; context @@ -271,7 +279,7 @@ pub(crate) async fn helper_upgrade_node_instance( node_status_locked: &ImmutableNodeStatus, db_client: &DbClient, docker_client: &DockerClient, -) -> Result, DockerClientError> { +) -> Result<(Option, Option), DockerClientError> { // TODO: use docker 'extract' api to simply copy the new node binary into the container. node_status_locked .insert( @@ -283,9 +291,11 @@ pub(crate) async fn helper_upgrade_node_instance( .update_node_status(container_id, NodeStatus::Upgrading) .await; - let res = docker_client.upgrade_node_in_container(container_id).await; + let res = docker_client + .upgrade_node_in_container(container_id, true) + .await; - if let Ok(ref new_version) = res { + if let Ok((ref new_version, ref ips)) = res { logging::log!( "Node binary upgraded to v{} in container {container_id}.", new_version.as_deref().unwrap_or("[unknown]") @@ -295,7 +305,10 @@ pub(crate) async fn helper_upgrade_node_instance( db_client .update_node_metadata_fields( container_id, - &[("bin_version", new_version.as_deref().unwrap_or_default())], + &[ + ("bin_version", new_version.as_deref().unwrap_or_default()), + ("ips", ips.as_deref().unwrap_or_default()), + ], ) .await; db_client @@ -379,9 +392,9 @@ pub async fn recycle_node_instance(container_id: ContainerId) -> Result<(), Serv .update_node_status(&container_id, NodeStatus::Recycling) .await; - let (version, peer_id) = context + let (version, peer_id, ips) = context .docker_client - .regenerate_peer_id_in_container(&container_id) + .regenerate_peer_id_in_container(&container_id, true) .await?; context @@ -391,6 +404,7 @@ pub async fn recycle_node_instance(container_id: ContainerId) -> Result<(), Serv &[ ("bin_version", &version.unwrap_or_default()), ("peer_id", &peer_id.unwrap_or_default()), + ("ips", &ips.unwrap_or_default()), ], ) .await; diff --git a/style/tailwind.css b/style/tailwind.css index 02f8f40..51655b9 100644 --- a/style/tailwind.css +++ b/style/tailwind.css @@ -53,3 +53,16 @@ .btn-manage-nodes-action { @apply flex justify-center items-center w-[52px] h-[52px] text-gray-500 hover:text-gray-900 bg-white rounded-full border border-gray-200 dark:border-gray-600 shadow-sm dark:hover:text-white dark:text-gray-400 hover:bg-gray-50 dark:bg-gray-700 dark:hover:bg-gray-600 focus:ring-4 focus:ring-gray-300 focus:outline-none dark:focus:ring-gray-400; } + +@keyframes slide { + 0% { + transform: translateX(25%); /* Start off-screen to the right */ + } + 100% { + transform: translateX(-85%); /* Slide out of view to the left */ + } +} + +.animate-slide { + animation: slide 25s linear infinite; /* Apply the sliding animation */ +} \ No newline at end of file