Skip to content

Commit

Permalink
Add button to forget host
Browse files Browse the repository at this point in the history
  • Loading branch information
Virv12 committed Oct 5, 2024
1 parent f065ce3 commit 8a0fd18
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 69 deletions.
151 changes: 84 additions & 67 deletions pixie-server/src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use axum::{
use futures::StreamExt;
use macaddr::MacAddr6;

use pixie_shared::{HttpConfig, StatusUpdate};
use pixie_shared::{HttpConfig, StatusUpdate, Unit};
use tokio::net::TcpListener;
use tokio_stream::wrappers::WatchStream;
use tower_http::{
Expand All @@ -21,6 +21,42 @@ use tower_http::{

use crate::state::State;

enum UnitSelector {
MacAddr(MacAddr6),
IpAddr(Ipv4Addr),
All,
Group(u8),
Image(String),
}

impl UnitSelector {
fn parse(state: &State, selector: String) -> Option<UnitSelector> {
if let Ok(mac) = selector.parse::<MacAddr6>() {
Some(UnitSelector::MacAddr(mac))
} else if let Ok(ip) = selector.parse::<Ipv4Addr>() {
Some(UnitSelector::IpAddr(ip))
} else if selector == "all" {
Some(UnitSelector::All)
} else if let Some(&group) = state.config.groups.get_by_first(&selector) {
Some(UnitSelector::Group(group))
} else if state.config.images.contains(&selector) {
Some(UnitSelector::Image(selector))
} else {
None
}
}

fn select(&self, unit: &Unit) -> bool {
match self {
UnitSelector::MacAddr(mac) => unit.mac == *mac,
UnitSelector::IpAddr(ip) => unit.static_ip() == *ip,
UnitSelector::All => true,
UnitSelector::Group(group) => unit.group == *group,
UnitSelector::Image(image) => unit.image == *image,
}
}
}

async fn action(
Path((unit_filter, action_name)): Path<(String, String)>,
extract::State(state): extract::State<Arc<State>>,
Expand All @@ -32,44 +68,21 @@ async fn action(
);
};

let mut updated = 0usize;
let Some(unit_selector) = UnitSelector::parse(&state, unit_filter) else {
return (
StatusCode::BAD_REQUEST,
"Invalid unit selector\n".to_owned(),
);
};

let mut updated = 0;
state.units.send_if_modified(|units| {
if let Ok(mac) = unit_filter.parse::<MacAddr6>() {
for unit in units.iter_mut() {
if unit.mac == mac {
unit.next_action = action;
updated += 1;
}
}
} else if let Ok(ip) = unit_filter.parse::<Ipv4Addr>() {
for unit in units.iter_mut() {
if unit.static_ip() == ip {
unit.next_action = action;
updated += 1;
}
}
} else if unit_filter == "all" {
for unit in units.iter_mut() {
for unit in units.iter_mut() {
if unit_selector.select(unit) {
unit.next_action = action;
updated += 1;
}
} else if let Some(&group) = state.config.groups.get_by_first(&unit_filter) {
for unit in units.iter_mut() {
if unit.group == group {
unit.next_action = action;
updated += 1;
}
}
} else if state.config.images.contains(&unit_filter) {
for unit in units.iter_mut() {
if unit.image == unit_filter {
unit.next_action = action;
updated += 1;
}
}
}

updated > 0
});

Expand All @@ -91,44 +104,21 @@ async fn image(
);
}

let mut updated = 0usize;
let Some(unit_selector) = UnitSelector::parse(&state, unit_filter) else {
return (
StatusCode::BAD_REQUEST,
"Invalid unit selector\n".to_owned(),
);
};

let mut updated = 0;
state.units.send_if_modified(|units| {
if let Ok(mac) = unit_filter.parse::<MacAddr6>() {
for unit in units.iter_mut() {
if unit.mac == mac {
unit.image = image.clone();
updated += 1;
}
}
} else if let Ok(ip) = unit_filter.parse::<Ipv4Addr>() {
for unit in units.iter_mut() {
if unit.static_ip() == ip {
unit.image = image.clone();
updated += 1;
}
}
} else if unit_filter == "all" {
for unit in units.iter_mut() {
for unit in units.iter_mut() {
if unit_selector.select(unit) {
unit.image = image.clone();
updated += 1;
}
} else if let Some(&group) = state.config.groups.get_by_first(&unit_filter) {
for unit in units.iter_mut() {
if unit.group == group {
unit.image = image.clone();
updated += 1;
}
}
} else if state.config.images.contains(&unit_filter) {
for unit in units.iter_mut() {
if unit.image == unit_filter {
unit.image = image.clone();
updated += 1;
}
}
}

updated > 0
});

Expand All @@ -139,9 +129,35 @@ async fn image(
}
}

async fn gc(extract::State(state): extract::State<Arc<State>>) -> String {
async fn forget(
Path(unit_filter): Path<String>,
extract::State(state): extract::State<Arc<State>>,
) -> impl IntoResponse {
let Some(unit_selector) = UnitSelector::parse(&state, unit_filter) else {
return (
StatusCode::BAD_REQUEST,
"Invalid unit selector\n".to_owned(),
);
};

let mut updated = 0;
state.units.send_if_modified(|units| {
let len_before = units.len();
units.retain(|unit| !unit_selector.select(unit));
updated = len_before - units.len();
updated > 0
});

if updated > 0 {
(StatusCode::OK, format!("{updated} computer(s) removed\n"))
} else {
(StatusCode::BAD_REQUEST, "Unknown PC\n".to_owned())
}
}

async fn gc(extract::State(state): extract::State<Arc<State>>) -> impl IntoResponse {
state.gc_chunks();
"".to_owned()
"Garbage collection completed\n"
}

async fn status(extract::State(state): extract::State<Arc<State>>) -> impl IntoResponse {
Expand Down Expand Up @@ -183,6 +199,7 @@ pub async fn main(state: Arc<State>) -> Result<()> {
.route("/admin/gc", get(gc))
.route("/admin/action/:unit/:action", get(action))
.route("/admin/image/:unit/:image", get(image))
.route("/admin/forget/:unit", get(forget))
.nest_service(
"/",
ServeDir::new(&admin_path).append_index_html_on_directories(true),
Expand Down
2 changes: 1 addition & 1 deletion pixie-server/src/ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub async fn main(state: Arc<State>) -> Result<()> {
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs();
state.set_ping(peer_mac, time, buf[..len].to_owned());
state.set_unit_ping(peer_mac, time, buf[..len].to_owned());
}

_ = signal.recv() => {
Expand Down
2 changes: 1 addition & 1 deletion pixie-server/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl State {
Ok(())
}

pub fn set_ping(&self, peer_mac: MacAddr6, time: u64, message: Vec<u8>) {
pub fn set_unit_ping(&self, peer_mac: MacAddr6, time: u64, message: Vec<u8>) {
self.units.send_if_modified(|units| {
let Some(unit) = units.iter_mut().find(|unit| unit.mac == peer_mac) else {
log::warn!("Got ping from unknown unit");
Expand Down
3 changes: 3 additions & 0 deletions pixie-web/Trunk.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[build]
public_url = "."
minify = "on_release"

[[proxy]]
backend = "http://localhost:8000/admin/"
7 changes: 7 additions & 0 deletions pixie-web/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ fn Group(
let url_boot = move || format!("admin/action/{}/reboot", mac());
let url_cancel = move || format!("admin/action/{}/wait", mac());
let url_register = move || format!("admin/action/{}/register", mac());
let url_forget = move || format!("admin/forget/{}", mac());

let fmt_ca = move || {
let unit = unit.get();
Expand Down Expand Up @@ -204,6 +205,11 @@ fn Group(
</ButtonGroup>
</td>
<td class="expand">{fmt_ca}</td>
<td>
<Button color=ButtonColor::Error on_click=move |_| send_req(url_forget())>
"forget"
</Button>
</td>
</tr>
}
.into_view()
Expand Down Expand Up @@ -248,6 +254,7 @@ fn Group(
<th>"next action"</th>
<th>"change action"</th>
<th>"current action"</th>
<th></th>
</tr>
<For each=move || 0..units.get().len() key=|x| *x children=render_unit/>
</Table>
Expand Down

0 comments on commit 8a0fd18

Please sign in to comment.