Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(app-commands): use new url semantics with URN #64

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
251 changes: 120 additions & 131 deletions Cargo.lock

Large diffs are not rendered by default.

59 changes: 12 additions & 47 deletions src/args.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,8 @@
use core::fmt;
use semver::{Error as SemverError, Version};
use std::{path::PathBuf, str::FromStr};
use std::path::PathBuf;

use clap::{Args, Parser, Subcommand};

#[derive(Debug, Clone)]
pub enum VersionEnum {
Version(Version),
Latest,
Nightly,
}

impl FromStr for VersionEnum {
type Err = SemverError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == "latest" {
Ok(VersionEnum::Latest)
} else if s == "nightly" {
Ok(VersionEnum::Nightly)
} else {
// Remove the 'v' prefix if present
let version_str = if s.starts_with('v') || s.starts_with('V') { &s[1..] } else { s };

let version = Version::parse(version_str)?;
Ok(VersionEnum::Version(version))
}
}
}

impl fmt::Display for VersionEnum {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
VersionEnum::Version(version) => write!(f, "{}", version),
VersionEnum::Latest => write!(f, "latest"),
VersionEnum::Nightly => write!(f, "nightly"),
}
}
}
use crate::structs::{urn::Urn, version::VersionEnum};

#[derive(Debug, Subcommand)]
pub enum RuntipiMainCommand {
Expand Down Expand Up @@ -111,32 +76,32 @@ pub enum AppSubcommand {

#[derive(Debug, Args)]
pub struct StartApp {
/// The id of the app to start
pub id: String,
/// The urn of the app to start
pub urn: Urn,
}

#[derive(Debug, Args)]
pub struct StopApp {
/// The id of the app to stop
pub id: String,
/// The urn of the app to stop
pub urn: Urn,
}

#[derive(Debug, Args)]
pub struct UninstallApp {
/// The id of the app to uninstall
pub id: String,
/// The urn of the app to uninstall
pub urn: Urn,
}

#[derive(Debug, Args)]
pub struct ResetApp {
/// The id of the app to reset
pub id: String,
/// The urn of the app to reset
pub urn: Urn,
}

#[derive(Debug, Args)]
pub struct UpdateApp {
/// The id of the app to update
pub id: String,
/// The urn of the app to update
pub urn: Urn,
}

#[derive(Debug, Args)]
Expand Down
6 changes: 3 additions & 3 deletions src/assets/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
depends_on:
runtipi:
condition: service_healthy
image: traefik:v3.1.4
image: traefik:v3.2
restart: unless-stopped
ports:
- ${NGINX_PORT:-80}:80
Expand Down Expand Up @@ -123,12 +123,12 @@ services:
traefik.http.routers.socket-secure.entrypoints: websecure
traefik.http.routers.socket-secure.tls.certresolver: myresolver
# Local domain
traefik.http.routers.socket-local-insecure.rule: Host(`${LOCAL_DOMAIN}`) && PathPrefix("/api/socket.io")
traefik.http.routers.socket-local-insecure.rule: Host(`${LOCAL_DOMAIN}`) && PathPrefix(`/api/socket.io`)
traefik.http.routers.socket-local-insecure.entrypoints: web
traefik.http.routers.socket-local-insecure.service: socket
traefik.http.routers.socket-local-insecure.middlewares: redirect-to-https
# Secure
traefik.http.routers.socket-local.rule: Host(`${LOCAL_DOMAIN}`) && PathPrefix("/api/socket.io")
traefik.http.routers.socket-local.rule: Host(`${LOCAL_DOMAIN}`) && PathPrefix(`/api/socket.io`)
traefik.http.routers.socket-local.entrypoints: websecure
traefik.http.routers.socket-local.tls: true
traefik.http.routers.socket-local.service: socket
Expand Down
31 changes: 16 additions & 15 deletions src/commands/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,38 +39,39 @@ pub fn run(args: AppCommand, env_map: EnvMap) {

match args.subcommand {
AppSubcommand::Start(args) => {
let spin = spinner::new(&format!("Starting app {}...", args.id));
let url = format!("{}/{}/{}", base_url, args.id, "start");
let spin = spinner::new(&format!("Starting app {}...", args.urn));
let url = format!("{}/{}/{}", base_url, args.urn, "start");
println!("url: {}", url);
let api_response = api_request(url, Method::POST, "{}");
let error_message = format!("Failed to start app {}. See logs/error.log for more details.", args.id);
let error_message = format!("Failed to start app {}. See logs/error.log for more details.", args.urn);
handle_api_response(spin, api_response, "App started successfully!", &error_message);
}
AppSubcommand::Stop(args) => {
let spin = spinner::new(&format!("Stopping app {}...", args.id));
let url = format!("{}/{}/{}", base_url, args.id, "stop");
let spin = spinner::new(&format!("Stopping app {}...", args.urn));
let url = format!("{}/{}/{}", base_url, args.urn, "stop");
let api_response = api_request(url, Method::POST, "{}");
let error_message = format!("Failed to stop app {}. See logs/error.log for more details.", args.id);
let error_message = format!("Failed to stop app {}. See logs/error.log for more details.", args.urn);
handle_api_response(spin, api_response, "App stopped successfully!", &error_message);
}
AppSubcommand::Uninstall(args) => {
let spin = spinner::new(&format!("Uninstalling app {}...", args.id));
let url = format!("{}/{}/{}", base_url, args.id, "uninstall");
let spin = spinner::new(&format!("Uninstalling app {}...", args.urn));
let url = format!("{}/{}/{}", base_url, args.urn, "uninstall");
let api_response = api_request(url, Method::DELETE, "{\"removeBackups\": false}");
let error_message = format!("Failed to uninstall app {}. See logs/error.log for more details.", args.id);
let error_message = format!("Failed to uninstall app {}. See logs/error.log for more details.", args.urn);
handle_api_response(spin, api_response, "App uninstalled successfully!", &error_message);
}
AppSubcommand::Reset(args) => {
let spin = spinner::new(&format!("Resetting app {}...", args.id));
let url = format!("{}/{}/{}", base_url, args.id, "reset");
let spin = spinner::new(&format!("Resetting app {}...", args.urn));
let url = format!("{}/{}/{}", base_url, args.urn, "reset");
let api_response = api_request(url, Method::POST, "{}");
let error_message = format!("Failed to reset app {}. See logs/error.log for more details.", args.id);
let error_message = format!("Failed to reset app {}. See logs/error.log for more details.", args.urn);
handle_api_response(spin, api_response, "App reset successfully!", &error_message);
}
AppSubcommand::Update(args) => {
let spin = spinner::new(&format!("Updating app {}...", args.id));
let url = format!("{}/{}/{}", base_url, args.id, "update");
let spin = spinner::new(&format!("Updating app {}...", args.urn));
let url = format!("{}/{}/{}", base_url, args.urn, "update");
let api_response = api_request(url, Method::PATCH, "{\"performBackup\": true}");
let error_message = format!("Failed to update app {}. See logs/error.log for more details.", args.id);
let error_message = format!("Failed to update app {}. See logs/error.log for more details.", args.urn);
handle_api_response(spin, api_response, "App updated successfully!", &error_message);
}
AppSubcommand::StartAll(_) => {
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod args;
mod commands;
mod components;
mod structs;
mod utils;

use args::RuntipiArgs;
Expand Down
2 changes: 2 additions & 0 deletions src/structs/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod urn;
pub mod version;
23 changes: 23 additions & 0 deletions src/structs/urn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use core::fmt;
use std::str::FromStr;

#[derive(Debug, Clone)]
pub struct Urn(String);

impl FromStr for Urn {
type Err = &'static str;

fn from_str(input: &str) -> Result<Self, Self::Err> {
if input.split_once(':').is_some() {
Ok(Self(input.to_string()))
} else {
Err("Must be <app-name>:<app-store-name>")
}
}
}

impl fmt::Display for Urn {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
39 changes: 39 additions & 0 deletions src/structs/version.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use core::fmt;
use std::str::FromStr;

use semver::{Error as SemverError, Version};

#[derive(Debug, Clone)]
pub enum VersionEnum {
Version(Version),
Latest,
Nightly,
}

impl FromStr for VersionEnum {
type Err = SemverError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == "latest" {
Ok(VersionEnum::Latest)
} else if s == "nightly" {
Ok(VersionEnum::Nightly)
} else {
// Remove the 'v' prefix if present
let version_str = if s.starts_with('v') || s.starts_with('V') { &s[1..] } else { s };

let version = Version::parse(version_str)?;
Ok(VersionEnum::Version(version))
}
}
}

impl fmt::Display for VersionEnum {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
VersionEnum::Version(version) => write!(f, "{}", version),
VersionEnum::Latest => write!(f, "latest"),
VersionEnum::Nightly => write!(f, "nightly"),
}
}
}
3 changes: 2 additions & 1 deletion src/utils/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use hex::encode;

use sha2::{Digest, Sha256};
use std::io::{Error, ErrorKind, Write};
use std::path::Path;
use std::{env, fs};
use std::{fs::File, path::PathBuf};

Expand Down Expand Up @@ -38,7 +39,7 @@ pub fn get_internal_ip() -> String {
"0.0.0.0".to_string()
}

pub fn get_seed(root_folder: &PathBuf) -> Result<String, Error> {
pub fn get_seed(root_folder: &Path) -> Result<String, Error> {
let seed_file_path = root_folder.join("state").join("seed");
let seed = std::fs::read_to_string(&seed_file_path);

Expand Down
Loading