Can delete an OTA update
This commit is contained in:
parent
2e4a2b68dd
commit
eafa8e6a4b
@ -31,6 +31,13 @@ pub fn get_ota_update(platform: OTAPlatform, version: &semver::Version) -> anyho
|
|||||||
Ok(std::fs::read(path)?)
|
Ok(std::fs::read(path)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete an OTA update
|
||||||
|
pub fn delete_update(platform: OTAPlatform, version: &semver::Version) -> anyhow::Result<()> {
|
||||||
|
let path = AppConfig::get().path_ota_update(platform, version);
|
||||||
|
std::fs::remove_file(path)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the list of OTA software updates for a platform
|
/// Get the list of OTA software updates for a platform
|
||||||
pub fn get_ota_updates_for_platform(platform: OTAPlatform) -> anyhow::Result<Vec<OTAUpdate>> {
|
pub fn get_ota_updates_for_platform(platform: OTAPlatform) -> anyhow::Result<Vec<OTAUpdate>> {
|
||||||
let ota_path = AppConfig::get().ota_platform_dir(platform);
|
let ota_path = AppConfig::get().ota_platform_dir(platform);
|
||||||
|
@ -195,7 +195,10 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
|
|||||||
"/web_api/ota/{platform}/{version}",
|
"/web_api/ota/{platform}/{version}",
|
||||||
web::get().to(ota_controller::download_firmware),
|
web::get().to(ota_controller::download_firmware),
|
||||||
)
|
)
|
||||||
// TODO : delete an OTA file
|
.route(
|
||||||
|
"/web_api/ota/{platform}/{version}",
|
||||||
|
web::delete().to(ota_controller::delete_update),
|
||||||
|
)
|
||||||
.route("/web_api/ota", web::get().to(ota_controller::list_all_ota))
|
.route("/web_api/ota", web::get().to(ota_controller::list_all_ota))
|
||||||
.route(
|
.route(
|
||||||
"/web_api/ota/{platform}",
|
"/web_api/ota/{platform}",
|
||||||
|
@ -74,6 +74,17 @@ pub async fn download_firmware(path: web::Path<SpecificOTAVersionPath>) -> HttpR
|
|||||||
.body(firmware))
|
.body(firmware))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete an uploaded firmware update
|
||||||
|
pub async fn delete_update(path: web::Path<SpecificOTAVersionPath>) -> HttpResult {
|
||||||
|
if !ota_manager::update_exists(path.platform, &path.version)? {
|
||||||
|
return Ok(HttpResponse::NotFound().json("The requested update was not found!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ota_manager::delete_update(path.platform, &path.version)?;
|
||||||
|
|
||||||
|
Ok(HttpResponse::Accepted().finish())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the list of all OTA updates
|
/// Get the list of all OTA updates
|
||||||
pub async fn list_all_ota() -> HttpResult {
|
pub async fn list_all_ota() -> HttpResult {
|
||||||
Ok(HttpResponse::Ok().json(ota_manager::get_all_ota_updates()?))
|
Ok(HttpResponse::Ok().json(ota_manager::get_all_ota_updates()?))
|
||||||
|
@ -40,8 +40,18 @@ export class OTAAPI {
|
|||||||
/**
|
/**
|
||||||
* Get the link to download an OTA update
|
* Get the link to download an OTA update
|
||||||
*/
|
*/
|
||||||
static DownloadOTAUpdateURL(platform: string, version: string): string {
|
static DownloadOTAUpdateURL(update: OTAUpdate): string {
|
||||||
return APIClient.backendURL() + `/ota/${platform}/${version}`;
|
return APIClient.backendURL() + `/ota/${update.platform}/${update.version}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an update
|
||||||
|
*/
|
||||||
|
static async DeleteUpdate(update: OTAUpdate): Promise<void> {
|
||||||
|
await APIClient.exec({
|
||||||
|
method: "DELETE",
|
||||||
|
uri: `/ota/${update.platform}/${update.version}`,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
import DownloadIcon from "@mui/icons-material/Download";
|
import DownloadIcon from "@mui/icons-material/Download";
|
||||||
import FileUploadIcon from "@mui/icons-material/FileUpload";
|
import FileUploadIcon from "@mui/icons-material/FileUpload";
|
||||||
import {
|
import {
|
||||||
@ -18,6 +19,10 @@ import { UploadUpdateDialog } from "../dialogs/UploadUpdateDialog";
|
|||||||
import { AsyncWidget } from "../widgets/AsyncWidget";
|
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||||
import { RouterLink } from "../widgets/RouterLink";
|
import { RouterLink } from "../widgets/RouterLink";
|
||||||
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
|
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
|
||||||
|
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
|
||||||
|
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
|
||||||
|
import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider";
|
||||||
|
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
|
||||||
|
|
||||||
export function OTARoute(): React.ReactElement {
|
export function OTARoute(): React.ReactElement {
|
||||||
const [list, setList] = React.useState<string[] | undefined>();
|
const [list, setList] = React.useState<string[] | undefined>();
|
||||||
@ -84,13 +89,45 @@ function _OTARoute(p: { platforms: Array<string> }): React.ReactElement {
|
|||||||
ready={!!list}
|
ready={!!list}
|
||||||
errMsg="Failed to load the list of OTA updates!"
|
errMsg="Failed to load the list of OTA updates!"
|
||||||
load={load}
|
load={load}
|
||||||
build={() => <_OTAList list={list!} />}
|
build={() => <_OTAList list={list!} onReload={reload} />}
|
||||||
/>
|
/>
|
||||||
</SolarEnergyRouteContainer>
|
</SolarEnergyRouteContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _OTAList(p: { list: OTAUpdate[] }): React.ReactElement {
|
function _OTAList(p: {
|
||||||
|
list: OTAUpdate[];
|
||||||
|
onReload: () => void;
|
||||||
|
}): React.ReactElement {
|
||||||
|
const alert = useAlert();
|
||||||
|
const confirm = useConfirm();
|
||||||
|
const loadingMessage = useLoadingMessage();
|
||||||
|
const snackbar = useSnackbar();
|
||||||
|
|
||||||
|
const deleteUpdate = async (update: OTAUpdate) => {
|
||||||
|
if (
|
||||||
|
!(await confirm(
|
||||||
|
`Do you really want to delete the update for platform ${update.platform} version ${update.version}?`
|
||||||
|
))
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
loadingMessage.show("Deleting update...");
|
||||||
|
|
||||||
|
await OTAAPI.DeleteUpdate(update);
|
||||||
|
|
||||||
|
snackbar("The update was successfully deleted!");
|
||||||
|
|
||||||
|
p.onReload();
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to delete update!", e);
|
||||||
|
alert(`Failed to delete the update! ${e}`);
|
||||||
|
} finally {
|
||||||
|
loadingMessage.hide();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableContainer component={Paper}>
|
<TableContainer component={Paper}>
|
||||||
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
||||||
@ -110,14 +147,17 @@ function _OTAList(p: { list: OTAUpdate[] }): React.ReactElement {
|
|||||||
<TableCell align="center">{filesize(row.file_size)}</TableCell>
|
<TableCell align="center">{filesize(row.file_size)}</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
<Tooltip title="Download a copy of the firmware">
|
<Tooltip title="Download a copy of the firmware">
|
||||||
<RouterLink
|
<RouterLink to={OTAAPI.DownloadOTAUpdateURL(row)}>
|
||||||
to={OTAAPI.DownloadOTAUpdateURL(row.platform, row.version)}
|
|
||||||
>
|
|
||||||
<IconButton>
|
<IconButton>
|
||||||
<DownloadIcon />
|
<DownloadIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Tooltip title="Delete firmware update">
|
||||||
|
<IconButton onClick={() => deleteUpdate(row)}>
|
||||||
|
<DeleteIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
Loading…
Reference in New Issue
Block a user