chore: rename app from ProxmoxDesktop to Clustri
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# ProxmoxDesktop
|
||||
# Clustri
|
||||
|
||||
A cross-platform desktop client for managing Proxmox VE servers and clusters. The backend is Rust on Tauri 2; the UI is React 19 with TypeScript, Vite, and Tailwind CSS v4.
|
||||
|
||||
@@ -9,7 +9,7 @@ A cross-platform desktop client for managing Proxmox VE servers and clusters. Th
|
||||
- Manage multiple simultaneous connections to servers and clusters.
|
||||
- Authenticate with an API token or with a username and password. Password mode uses ticket-based auth (PVEAuthCookie plus CSRF token).
|
||||
- Credentials live in the OS keyring. API tokens never touch disk.
|
||||
- Connections persist to `{app-config-dir}/proxmoxdesktop/connections.json`. The last active connection reconnects on launch.
|
||||
- Connections persist to `{app-config-dir}/clustri/connections.json`. The last active connection reconnects on launch.
|
||||
|
||||
### Cluster support
|
||||
|
||||
@@ -171,7 +171,7 @@ source $HOME/.cargo/env
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd ProxmoxDesktop
|
||||
cd clustri
|
||||
npm install
|
||||
```
|
||||
|
||||
@@ -250,7 +250,7 @@ When adding a connection you need:
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
ProxmoxDesktop/
|
||||
clustri/
|
||||
├── src/ # React frontend
|
||||
│ ├── components/
|
||||
│ │ ├── ui/ # base components (buttons, dialogs, toasts)
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>ProxmoxDesktop</title>
|
||||
<title>Clustri</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
Generated
+2
-2
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "proxmoxdesktop",
|
||||
"name": "clustri",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "proxmoxdesktop",
|
||||
"name": "clustri",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@fontsource-variable/geist": "^5.3.0",
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "proxmoxdesktop",
|
||||
"name": "clustri",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
|
||||
Generated
+29
-29
@@ -411,6 +411,35 @@ dependencies = [
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clustri"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"hex",
|
||||
"httpmock",
|
||||
"keyring",
|
||||
"percent-encoding",
|
||||
"rcgen",
|
||||
"reqwest 0.12.28",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-shell",
|
||||
"tempfile",
|
||||
"thiserror 2.0.19",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-tungstenite",
|
||||
"url",
|
||||
"uuid",
|
||||
"x509-cert",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.58"
|
||||
@@ -2704,35 +2733,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proxmox-desktop"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"hex",
|
||||
"httpmock",
|
||||
"keyring",
|
||||
"percent-encoding",
|
||||
"rcgen",
|
||||
"reqwest 0.12.28",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-shell",
|
||||
"tempfile",
|
||||
"thiserror 2.0.19",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-tungstenite",
|
||||
"url",
|
||||
"uuid",
|
||||
"x509-cert",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.41.0"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "proxmox-desktop"
|
||||
name = "clustri"
|
||||
version = "0.1.0"
|
||||
description = "A cross-platform desktop application for managing Proxmox VE servers"
|
||||
authors = ["you"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"identifier": "default",
|
||||
"description": "Default capabilities for ProxmoxDesktop",
|
||||
"description": "Default capabilities for Clustri",
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"default":{"identifier":"default","description":"Default capabilities for ProxmoxDesktop","local":true,"windows":["main"],"permissions":["core:default","core:event:default","core:event:allow-listen","core:event:allow-emit","core:event:allow-emit-to","core:window:default","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-set-focus","core:window:allow-is-visible","shell:allow-execute","shell:default"]}}
|
||||
{"default":{"identifier":"default","description":"Default capabilities for Clustri","local":true,"windows":["main"],"permissions":["core:default","core:event:default","core:event:allow-listen","core:event:allow-emit","core:event:allow-emit-to","core:window:default","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-set-focus","core:window:allow-is-visible","shell:allow-execute","shell:default"]}}
|
||||
@@ -370,7 +370,7 @@ impl Connection {
|
||||
}
|
||||
|
||||
fn keyring_service() -> &'static str {
|
||||
"proxmox-desktop"
|
||||
"clustri"
|
||||
}
|
||||
|
||||
fn keyring_entry(connection_id: &str, field: &str) -> crate::Result<keyring::Entry> {
|
||||
|
||||
@@ -129,11 +129,11 @@ struct AppState {
|
||||
|
||||
/// Returns the path of the persisted connections file.
|
||||
///
|
||||
/// Lives at `{app_config_dir}/proxmoxdesktop/connections.json`; the parent
|
||||
/// Lives at `{app_config_dir}/clustri/connections.json`; the parent
|
||||
/// directory is created lazily when the file is first written.
|
||||
fn connections_file(app: &tauri::AppHandle) -> Result<PathBuf> {
|
||||
let dir = app.path().app_config_dir()?;
|
||||
Ok(dir.join("proxmoxdesktop").join("connections.json"))
|
||||
Ok(dir.join("clustri").join("connections.json"))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -939,7 +939,7 @@ pub fn run() {
|
||||
.build()?;
|
||||
|
||||
let _tray = TrayIconBuilder::with_id("main-tray")
|
||||
.tooltip("ProxmoxDesktop")
|
||||
.tooltip("Clustri")
|
||||
.icon(app.default_window_icon().cloned().expect("no default icon"))
|
||||
.menu(&menu)
|
||||
.on_menu_event(move |app, event| match event.id.as_ref() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
proxmox_desktop::run()
|
||||
clustri::run()
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "ProxmoxDesktop",
|
||||
"productName": "Clustri",
|
||||
"version": "0.1.0",
|
||||
"identifier": "com.proxmoxdesktop.app",
|
||||
"identifier": "dev.clustri.app",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
"devUrl": "http://localhost:1420",
|
||||
@@ -12,7 +12,7 @@
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "ProxmoxDesktop",
|
||||
"title": "Clustri",
|
||||
"width": 1200,
|
||||
"height": 800,
|
||||
"resizable": true,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//! error mapping, query parameters, and URL construction.
|
||||
|
||||
use httpmock::prelude::*;
|
||||
use proxmox_desktop::{api_request, AuthContext, AuthMode, Error};
|
||||
use clustri::{api_request, AuthContext, AuthMode, Error};
|
||||
use reqwest::Client;
|
||||
use reqwest::Method as RMethod;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//! called directly on an added connection without `connect()`.
|
||||
|
||||
use httpmock::prelude::*;
|
||||
use proxmox_desktop::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
|
||||
use clustri::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
|
||||
|
||||
/// Builds a `ConnectionManager` with a single token-mode connection whose
|
||||
/// primary endpoint points at the mock server. `node` pins the storage node.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//! directly on an added connection without `connect()`.
|
||||
|
||||
use httpmock::prelude::*;
|
||||
use proxmox_desktop::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
|
||||
use clustri::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
|
||||
|
||||
/// Builds a `ConnectionManager` with a single token-mode connection whose
|
||||
/// primary endpoint points at `url`.
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
//! `body_includes` assertions use the encoded form (e.g. `:` becomes `%3A`).
|
||||
|
||||
use httpmock::prelude::*;
|
||||
use proxmox_desktop::{
|
||||
use clustri::{
|
||||
AddDiskConfig, AddNICConfig, ConnectionConfig, ConnectionManager, EditNICConfig,
|
||||
EndpointConfig, Error,
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//! directly on an added connection without `connect()`.
|
||||
|
||||
use httpmock::prelude::*;
|
||||
use proxmox_desktop::{
|
||||
use clustri::{
|
||||
BackupJobConfig, ConnectionConfig, ConnectionManager, CreateSnapshotConfig, EndpointConfig,
|
||||
Error,
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
use httpmock::prelude::*;
|
||||
use httpmock::Mock;
|
||||
use proxmox_desktop::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
|
||||
use clustri::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
|
||||
|
||||
const TOKEN: &str = "root@pam!cluster-token";
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
use httpmock::prelude::*;
|
||||
use httpmock::Mock;
|
||||
use proxmox_desktop::{derive_node_url, ConnectionConfig, ConnectionManager, EndpointConfig};
|
||||
use clustri::{derive_node_url, ConnectionConfig, ConnectionManager, EndpointConfig};
|
||||
|
||||
const TOKEN: &str = "root@pam!discovery-token";
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
use httpmock::prelude::*;
|
||||
use httpmock::Mock;
|
||||
use proxmox_desktop::{
|
||||
use clustri::{
|
||||
api_request, AuthContext, AuthMode, ConnectionConfig, ConnectionManager, EndpointConfig, Error,
|
||||
};
|
||||
use reqwest::Client;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! request layer falls back to the OS keyring.
|
||||
|
||||
use httpmock::prelude::*;
|
||||
use proxmox_desktop::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
|
||||
use clustri::{ConnectionConfig, ConnectionManager, EndpointConfig, Error};
|
||||
|
||||
/// Builds a token-mode connection config with a real token set.
|
||||
fn token_config(id: &str, url: &str, token: &str, accept_untrusted: bool) -> ConnectionConfig {
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
//! Each test spawns a local TLS server with a freshly generated self-signed
|
||||
//! certificate and exercises the capture/verify helpers against it.
|
||||
|
||||
use proxmox_desktop::tls::{
|
||||
use clustri::tls::{
|
||||
capture_fingerprint, fetch_certificate_info, verify_pin, verify_server_certificate,
|
||||
};
|
||||
use proxmox_desktop::Error;
|
||||
use clustri::Error;
|
||||
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
|
||||
use rustls::ServerConfig;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
@@ -100,7 +100,7 @@ export function TerminalConsole({ connectionId, node, vmid, onError, onConnected
|
||||
if (!isTauriMode && !cancelled) {
|
||||
// Dev mode mock terminal
|
||||
terminal.writeln('\x1b[1;32m╔══════════════════════════════════════════╗\x1b[0m')
|
||||
terminal.writeln('\x1b[1;32m║ ProxmoxDesktop - Terminal Console ║\x1b[0m')
|
||||
terminal.writeln('\x1b[1;32m║ Clustri - Terminal Console ║\x1b[0m')
|
||||
terminal.writeln('\x1b[1;32m╚══════════════════════════════════════════╝\x1b[0m')
|
||||
terminal.writeln('')
|
||||
terminal.writeln(`\x1b[33mNode: ${node} | VMID: ${vmid} | Type: LXC\x1b[0m`)
|
||||
|
||||
@@ -43,7 +43,7 @@ export function Sidebar({ onAddConnection, activeView, onNavigate }: SidebarProp
|
||||
</div>
|
||||
<div className="min-w-0 leading-tight">
|
||||
<h1 className="truncate text-sm font-semibold tracking-tight text-foreground">
|
||||
ProxmoxDesktop
|
||||
Clustri
|
||||
</h1>
|
||||
<p className="text-[10px] font-medium uppercase tracking-[0.14em] text-muted-foreground">
|
||||
Ops Console
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { ThemeSwitcher } from '@/components/settings/ThemeSwitcher'
|
||||
import { ConnectionManager } from '@/components/settings/ConnectionManager'
|
||||
import { ExternalLink } from 'lucide-react'
|
||||
|
||||
export function SettingsPage() {
|
||||
return (
|
||||
@@ -59,17 +58,6 @@ export function SettingsPage() {
|
||||
<span className="text-sm text-muted-foreground">Platform</span>
|
||||
<span className="font-mono text-sm font-medium">Tauri + React</span>
|
||||
</div>
|
||||
<div className="pt-2 border-t">
|
||||
<a
|
||||
href="https://github.com/proxmoxdesktop"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1.5 text-sm text-primary hover:underline"
|
||||
>
|
||||
View on GitHub
|
||||
<ExternalLink className="h-3.5 w-3.5" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -25,11 +25,11 @@ function applyTheme(theme: Theme) {
|
||||
root.classList.add(theme)
|
||||
}
|
||||
|
||||
localStorage.setItem('proxmoxdesktop-theme', theme)
|
||||
localStorage.setItem('clustri-theme', theme)
|
||||
}
|
||||
|
||||
function getInitialTheme(): Theme {
|
||||
const stored = localStorage.getItem('proxmoxdesktop-theme')
|
||||
const stored = localStorage.getItem('clustri-theme')
|
||||
if (stored === 'light' || stored === 'dark' || stored === 'system') {
|
||||
return stored
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user