Merge pull request #724 from jb-alvarado/master
fix config reload/override config args, no path updates
This commit is contained in:
commit
ec781d23c9
@ -1,6 +1,6 @@
|
||||
FROM alpine:latest
|
||||
|
||||
ARG FFPLAYOUT_VERSION=0.24.0-beta1
|
||||
ARG FFPLAYOUT_VERSION=0.24.0-beta2
|
||||
ARG SHARED_STORAGE=false
|
||||
|
||||
ENV DB=/db
|
||||
@ -12,7 +12,7 @@ COPY <<-EOT /run.sh
|
||||
#!/bin/sh
|
||||
|
||||
if [ ! -f /db/ffplayout.db ]; then
|
||||
ffplayout -u admin -p admin -m contact@example.com --storage-path "/tv-media" --playlist-path "/playlists" --hls-path "/hls" --log-path "/logging" --shared-storage
|
||||
ffplayout -u admin -p admin -m contact@example.com --storage-root "/tv-media" --playlist-root "/playlists" --public-root "/public" --log-path "/logging" --shared-storage
|
||||
fi
|
||||
|
||||
/usr/bin/ffplayout -l "0.0.0.0:8787"
|
||||
|
@ -39,7 +39,7 @@ docker build -f nvidia.Dockerfile -t ffplayout-image:nvidia .
|
||||
example of command to start the container:
|
||||
|
||||
```BASH
|
||||
docker run -it -v /path/to/db:/db -v /path/to/storage:/tv-media -v /path/to/playlists:/playlists -v /path/to/hls:/hls -v /path/to/logging:/logging --name ffplayout -p 8787:8787 ffplayout-image
|
||||
docker run -it -v /path/to/db:/db -v /path/to/storage:/tv-media -v /path/to/playlists:/playlists -v /path/to/public:/public -v /path/to/logging:/logging --name ffplayout -p 8787:8787 ffplayout-image
|
||||
|
||||
# run in daemon mode
|
||||
docker run -d --name ffplayout -p 8787:8787 ffplayout-image
|
||||
|
@ -11,6 +11,6 @@ services:
|
||||
- ./data/storage:/tv-media
|
||||
- ./data/playlists:/playlists
|
||||
- ./data/logging:/logging
|
||||
- ./data/hls:/hls
|
||||
- ./data/public:/public
|
||||
ports:
|
||||
- '8787:8787'
|
||||
|
@ -1,6 +1,6 @@
|
||||
FROM alpine:latest
|
||||
|
||||
ARG FFPLAYOUT_VERSION=0.24.0-beta1
|
||||
ARG FFPLAYOUT_VERSION=0.24.0-beta2
|
||||
ARG SHARED_STORAGE=false
|
||||
|
||||
ENV DB=/db
|
||||
@ -14,7 +14,7 @@ COPY <<-EOT /run.sh
|
||||
#!/bin/sh
|
||||
|
||||
if [ ! -f /db/ffplayout.db ]; then
|
||||
ffplayout -u admin -p admin -m contact@example.com --storage-path "/tv-media" --playlist-path "/playlists" --hls-path "/hls" --log-path "/logging" --shared-storage
|
||||
ffplayout -u admin -p admin -m contact@example.com --storage-root "/tv-media" --playlist-root "/playlists" --public-root "/public" --log-path "/logging" --shared-storage
|
||||
fi
|
||||
|
||||
/usr/bin/ffplayout -l "0.0.0.0:8787"
|
||||
|
@ -1,6 +1,6 @@
|
||||
FROM nvidia/cuda:12.5.0-runtime-rockylinux9
|
||||
|
||||
ARG FFPLAYOUT_VERSION=0.24.0-beta1
|
||||
ARG FFPLAYOUT_VERSION=0.24.0-beta2
|
||||
ARG SHARED_STORAGE=false
|
||||
|
||||
ENV DB=/db
|
||||
@ -204,7 +204,7 @@ COPY <<-EOT /run.sh
|
||||
#!/bin/sh
|
||||
|
||||
if [ ! -f /db/ffplayout.db ]; then
|
||||
ffplayout -u admin -p admin -m contact@example.com --storage-path "/tv-media" --playlist-path "/playlists" --hls-path "/hls" --log-path "/logging" --shared-storage
|
||||
ffplayout -u admin -p admin -m contact@example.com --storage-root "/tv-media" --playlist-root "/playlists" --public-root "/public" --log-path "/logging" --shared-storage
|
||||
fi
|
||||
|
||||
/usr/bin/ffplayout -l "0.0.0.0:8787"
|
||||
|
@ -41,7 +41,7 @@ use tokio::fs;
|
||||
use crate::db::models::Role;
|
||||
use crate::utils::{
|
||||
channels::{create_channel, delete_channel},
|
||||
config::{PlayoutConfig, Template},
|
||||
config::{get_config, PlayoutConfig, Template},
|
||||
control::{control_state, send_message, ControlParams, Process, ProcessCtl},
|
||||
errors::ServiceError,
|
||||
files::{
|
||||
@ -475,9 +475,11 @@ async fn patch_channel(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
id: web::Path<i32>,
|
||||
data: web::Json<Channel>,
|
||||
controllers: web::Data<Mutex<ChannelController>>,
|
||||
role: AuthDetails<Role>,
|
||||
user: web::ReqData<UserMeta>,
|
||||
) -> Result<impl Responder, ServiceError> {
|
||||
let manager = controllers.lock().unwrap().get(*id).unwrap();
|
||||
let mut data = data.into_inner();
|
||||
|
||||
if !role.has_authority(&Role::GlobalAdmin) {
|
||||
@ -488,11 +490,11 @@ async fn patch_channel(
|
||||
data.storage_path = channel.storage_path;
|
||||
}
|
||||
|
||||
if handles::update_channel(&pool, *id, data).await.is_ok() {
|
||||
return Ok("Update Success");
|
||||
};
|
||||
handles::update_channel(&pool, *id, data).await?;
|
||||
let new_config = get_config(&pool, *id).await?;
|
||||
manager.update_config(new_config);
|
||||
|
||||
Err(ServiceError::InternalServerError)
|
||||
Ok("Update Success")
|
||||
}
|
||||
|
||||
/// **Create new Channel**
|
||||
@ -597,7 +599,7 @@ async fn update_advanced_config(
|
||||
let manager = controllers.lock().unwrap().get(*id).unwrap();
|
||||
|
||||
handles::update_advanced_configuration(&pool, *id, data.clone()).await?;
|
||||
let new_config = PlayoutConfig::new(&pool, *id).await;
|
||||
let new_config = get_config(&pool, *id).await?;
|
||||
|
||||
manager.update_config(new_config);
|
||||
|
||||
@ -653,7 +655,7 @@ async fn update_playout_config(
|
||||
let config_id = manager.config.lock().unwrap().general.id;
|
||||
|
||||
handles::update_configuration(&pool, config_id, data.clone()).await?;
|
||||
let new_config = PlayoutConfig::new(&pool, *id).await;
|
||||
let new_config = get_config(&pool, *id).await?;
|
||||
|
||||
manager.update_config(new_config);
|
||||
|
||||
|
@ -3,7 +3,6 @@ use argon2::{
|
||||
Argon2, PasswordHasher,
|
||||
};
|
||||
|
||||
use log::*;
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
use sqlx::{sqlite::SqliteQueryResult, Pool, Row, Sqlite};
|
||||
use tokio::task;
|
||||
@ -13,9 +12,8 @@ use crate::db::models::{Channel, GlobalSettings, Role, TextPreset, User};
|
||||
use crate::utils::{advanced_config::AdvancedConfig, config::PlayoutConfig, local_utc_offset};
|
||||
|
||||
pub async fn db_migrate(conn: &Pool<Sqlite>) -> Result<&'static str, Box<dyn std::error::Error>> {
|
||||
match sqlx::migrate!("../migrations").run(conn).await {
|
||||
Ok(_) => info!("Database migration successfully"),
|
||||
Err(e) => panic!("{e}"),
|
||||
if let Err(e) = sqlx::migrate!("../migrations").run(conn).await {
|
||||
panic!("{e}");
|
||||
}
|
||||
|
||||
if select_global(conn).await.is_err() {
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::io::{stdin, stdout, Write};
|
||||
|
||||
use sqlx::{migrate::MigrateDatabase, Pool, Sqlite, SqlitePool};
|
||||
|
||||
pub mod handles;
|
||||
@ -16,3 +18,23 @@ pub async fn db_pool() -> Result<Pool<Sqlite>, sqlx::Error> {
|
||||
|
||||
Ok(conn)
|
||||
}
|
||||
|
||||
pub async fn db_drop() {
|
||||
let mut drop_answer = String::new();
|
||||
|
||||
print!("Drop Database [Y/n]: ");
|
||||
stdout().flush().unwrap();
|
||||
|
||||
stdin()
|
||||
.read_line(&mut drop_answer)
|
||||
.expect("Did not enter a yes or no?");
|
||||
|
||||
let drop = drop_answer.trim().to_lowercase().starts_with('y');
|
||||
|
||||
if drop {
|
||||
match Sqlite::drop_database(db_path().unwrap()).await {
|
||||
Ok(_) => println!("Successfully dropped DB"),
|
||||
Err(e) => eprintln!("{e}"),
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use std::{
|
||||
collections::HashSet,
|
||||
env,
|
||||
fs::File,
|
||||
io::{self, stdin, stdout, Write},
|
||||
io,
|
||||
process::exit,
|
||||
sync::{atomic::AtomicBool, Arc, Mutex},
|
||||
thread,
|
||||
@ -14,7 +14,6 @@ use actix_web::{
|
||||
};
|
||||
use actix_web_grants::authorities::AttachAuthorities;
|
||||
use actix_web_httpauth::{extractors::bearer::BearerAuth, middleware::HttpAuthentication};
|
||||
use sqlx::{migrate::MigrateDatabase, Sqlite};
|
||||
|
||||
#[cfg(all(not(debug_assertions), feature = "embed_frontend"))]
|
||||
use actix_web_static_files::ResourceFiles;
|
||||
@ -25,7 +24,7 @@ use path_clean::PathClean;
|
||||
use ffplayout::{
|
||||
api::{auth, routes::*},
|
||||
db::{
|
||||
db_pool, handles,
|
||||
db_drop, db_pool, handles,
|
||||
models::{init_globales, UserMeta},
|
||||
},
|
||||
player::{
|
||||
@ -36,7 +35,6 @@ use ffplayout::{
|
||||
utils::{
|
||||
args_parse::run_args,
|
||||
config::get_config,
|
||||
db_path,
|
||||
logging::{init_logging, MailQueue},
|
||||
playlist::generate_playlist,
|
||||
},
|
||||
@ -292,23 +290,7 @@ async fn main() -> std::io::Result<()> {
|
||||
Arc::new(AtomicBool::new(false)),
|
||||
);
|
||||
} else if ARGS.drop_db {
|
||||
let mut drop_answer = String::new();
|
||||
|
||||
print!("Drop Database [Y/n]: ");
|
||||
stdout().flush().unwrap();
|
||||
|
||||
stdin()
|
||||
.read_line(&mut drop_answer)
|
||||
.expect("Did not enter a yes or no?");
|
||||
|
||||
let drop = drop_answer.trim().to_lowercase().starts_with('y');
|
||||
|
||||
if drop {
|
||||
match Sqlite::drop_database(db_path().unwrap()).await {
|
||||
Ok(_) => info!("Successfully dropped DB"),
|
||||
Err(e) => error!("{e}"),
|
||||
};
|
||||
}
|
||||
db_drop().await;
|
||||
} else if !ARGS.init {
|
||||
error!("Run ffplayout with parameters! Run ffplayout -h for more information.");
|
||||
}
|
||||
|
@ -453,8 +453,39 @@ pub async fn run_args(pool: &Pool<Sqlite>) -> Result<(), i32> {
|
||||
shared_storage: args.shared_storage,
|
||||
};
|
||||
|
||||
let mut channel = handles::select_channel(pool, &1)
|
||||
.await
|
||||
.expect("Select Channel 1");
|
||||
|
||||
if args.shared_storage {
|
||||
channel.hls_path = Path::new(&global.public_root)
|
||||
.join("1")
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
channel.playlist_path = Path::new(&global.playlist_root)
|
||||
.join("1")
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
channel.storage_path = Path::new(&global.storage_root)
|
||||
.join("1")
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
} else {
|
||||
channel.hls_path = global.public_root.clone();
|
||||
channel.playlist_path = global.playlist_root.clone();
|
||||
channel.storage_path = global.storage_root.clone();
|
||||
}
|
||||
|
||||
match handles::update_global(pool, global.clone()).await {
|
||||
Ok(_) => println!("Update global paths..."),
|
||||
Ok(_) => println!("Update globals done..."),
|
||||
Err(e) => {
|
||||
eprintln!("{e}");
|
||||
error_code = 1;
|
||||
}
|
||||
};
|
||||
|
||||
match handles::update_channel(pool, 1, channel).await {
|
||||
Ok(_) => println!("Update channel done..."),
|
||||
Err(e) => {
|
||||
eprintln!("{e}");
|
||||
error_code = 1;
|
||||
|
@ -11,7 +11,7 @@ use sqlx::{Pool, Sqlite};
|
||||
use super::logging::MailQueue;
|
||||
use crate::db::{handles, models::Channel};
|
||||
use crate::player::controller::{ChannelController, ChannelManager};
|
||||
use crate::utils::{config::PlayoutConfig, errors::ServiceError};
|
||||
use crate::utils::{config::get_config, errors::ServiceError};
|
||||
|
||||
async fn map_global_admins(conn: &Pool<Sqlite>) -> Result<(), ServiceError> {
|
||||
let channels = handles::select_related_channels(conn, None).await?;
|
||||
@ -88,7 +88,7 @@ pub async fn create_channel(
|
||||
handles::insert_advanced_configuration(conn, channel.id).await?;
|
||||
handles::insert_configuration(conn, channel.id, output_param).await?;
|
||||
|
||||
let config = PlayoutConfig::new(conn, channel.id).await;
|
||||
let config = get_config(conn, channel.id).await?;
|
||||
let m_queue = Arc::new(Mutex::new(MailQueue::new(channel.id, config.mail.clone())));
|
||||
let manager = ChannelManager::new(Some(conn.clone()), channel.clone(), config);
|
||||
|
||||
|
@ -184,12 +184,12 @@ pub struct Channel {
|
||||
}
|
||||
|
||||
impl Channel {
|
||||
pub fn new(config: &models::GlobalSettings) -> Self {
|
||||
pub fn new(config: &models::GlobalSettings, channel: models::Channel) -> Self {
|
||||
Self {
|
||||
logging_path: PathBuf::from(config.logging_path.clone()),
|
||||
hls_path: PathBuf::from(config.public_root.clone()),
|
||||
playlist_path: PathBuf::from(config.playlist_root.clone()),
|
||||
storage_path: PathBuf::from(config.storage_root.clone()),
|
||||
hls_path: PathBuf::from(channel.hls_path.clone()),
|
||||
playlist_path: PathBuf::from(channel.playlist_path.clone()),
|
||||
storage_path: PathBuf::from(channel.storage_path.clone()),
|
||||
shared_storage: config.shared_storage,
|
||||
}
|
||||
}
|
||||
@ -414,10 +414,12 @@ pub struct Storage {
|
||||
pub filler: PathBuf,
|
||||
pub extensions: Vec<String>,
|
||||
pub shuffle: bool,
|
||||
#[serde(skip_deserializing)]
|
||||
pub shared_storage: bool,
|
||||
}
|
||||
|
||||
impl Storage {
|
||||
fn new(config: &models::Configuration, path: PathBuf) -> Self {
|
||||
fn new(config: &models::Configuration, path: PathBuf, shared_storage: bool) -> Self {
|
||||
Self {
|
||||
help_text: config.storage_help.clone(),
|
||||
path,
|
||||
@ -429,6 +431,7 @@ impl Storage {
|
||||
.map(|s| s.to_string())
|
||||
.collect(),
|
||||
shuffle: config.storage_shuffle,
|
||||
shared_storage,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -553,6 +556,9 @@ impl PlayoutConfig {
|
||||
let global = handles::select_global(pool)
|
||||
.await
|
||||
.expect("Can't read globals");
|
||||
let channel = handles::select_channel(pool, &channel_id)
|
||||
.await
|
||||
.expect("Can't read channel");
|
||||
let config = handles::select_configuration(pool, channel_id)
|
||||
.await
|
||||
.expect("Can't read config");
|
||||
@ -560,7 +566,7 @@ impl PlayoutConfig {
|
||||
.await
|
||||
.expect("Can't read advanced config");
|
||||
|
||||
let mut channel = Channel::new(&global);
|
||||
let channel = Channel::new(&global, channel);
|
||||
let advanced = AdvancedConfig::new(adv_config);
|
||||
let general = General::new(&config);
|
||||
let mail = Mail::new(&config);
|
||||
@ -572,10 +578,6 @@ impl PlayoutConfig {
|
||||
let task = Task::new(&config);
|
||||
let mut output = Output::new(&config);
|
||||
|
||||
if global.shared_storage {
|
||||
channel.storage_path = channel.storage_path.join(channel_id.to_string());
|
||||
}
|
||||
|
||||
if !channel.storage_path.is_dir() {
|
||||
tokio::fs::create_dir_all(&channel.storage_path)
|
||||
.await
|
||||
@ -584,12 +586,8 @@ impl PlayoutConfig {
|
||||
});
|
||||
}
|
||||
|
||||
let mut storage = Storage::new(&config, channel.storage_path.clone());
|
||||
|
||||
if channel_id > 1 || !global.shared_storage {
|
||||
channel.playlist_path = channel.playlist_path.join(channel_id.to_string());
|
||||
channel.hls_path = channel.hls_path.join(channel_id.to_string());
|
||||
}
|
||||
let mut storage =
|
||||
Storage::new(&config, channel.storage_path.clone(), global.shared_storage);
|
||||
|
||||
if !channel.playlist_path.is_dir() {
|
||||
tokio::fs::create_dir_all(&channel.playlist_path)
|
||||
|
2
frontend
2
frontend
@ -1 +1 @@
|
||||
Subproject commit e183320e13bd972d632b841bde722fa7bbed70e5
|
||||
Subproject commit fd85411c773f86cd3cef02fdd8c3fd041d9af1a8
|
Loading…
Reference in New Issue
Block a user