Merge branch 'master' of ssh://proxdev.maurer-it.com/rust/proxmox-backup

This commit is contained in:
Dietmar Maurer 2021-01-21 10:56:52 +01:00
commit d543587d34
122 changed files with 521 additions and 614 deletions

View File

@ -72,7 +72,7 @@ fn extract_acl_node_data(
}
}
for (group, roles) in &node.groups {
if let Some(_) = token_user {
if token_user.is_some() {
continue;
}
@ -210,7 +210,7 @@ pub fn update_acl(
let top_level_privs = user_info.lookup_privs(&current_auth_id, &["access", "acl"]);
if top_level_privs & PRIV_PERMISSIONS_MODIFY == 0 {
if let Some(_) = group {
if group.is_some() {
bail!("Unprivileged users are not allowed to create group ACL item.");
}

View File

@ -46,7 +46,7 @@ fn list_roles() -> Result<Value, Error> {
let mut priv_list = Vec::new();
for (name, privilege) in PRIVILEGES.iter() {
if privs & privilege > 0 {
priv_list.push(name.clone());
priv_list.push(name);
}
}
list.push(json!({ "roleid": role, "privs": priv_list, "comment": comment }));

View File

@ -331,13 +331,11 @@ fn list_tfa(rpcenv: &mut dyn RpcEnvironment) -> Result<Vec<TfaUser>, Error> {
entries: to_data(data),
});
}
} else {
if let Some(data) = { tfa_data }.remove(authid.user()) {
out.push(TfaUser {
userid: authid.into(),
entries: to_data(data),
});
}
} else if let Some(data) = { tfa_data }.remove(authid.user()) {
out.push(TfaUser {
userid: authid.into(),
entries: to_data(data),
});
}
Ok(out)

View File

@ -169,7 +169,7 @@ pub fn list_users(
})
.collect()
} else {
iter.map(|user: user::User| UserWithTokens::new(user))
iter.map(UserWithTokens::new)
.collect()
};
@ -230,7 +230,7 @@ pub fn create_user(
let (mut config, _digest) = user::config()?;
if let Some(_) = config.sections.get(user.userid.as_str()) {
if config.sections.get(user.userid.as_str()).is_some() {
bail!("user '{}' already exists.", user.userid);
}
@ -595,7 +595,7 @@ pub fn generate_token(
let tokenid = Authid::from((userid.clone(), Some(tokenname.clone())));
let tokenid_string = tokenid.to_string();
if let Some(_) = config.sections.get(&tokenid_string) {
if config.sections.get(&tokenid_string).is_some() {
bail!("token '{}' for user '{}' already exists.", tokenname.as_str(), userid);
}
@ -603,7 +603,7 @@ pub fn generate_token(
token_shadow::set_secret(&tokenid, &secret)?;
let token = user::ApiToken {
tokenid: tokenid.clone(),
tokenid,
comment,
enable,
expire,

View File

@ -440,8 +440,8 @@ pub fn list_snapshots (
let files = info
.files
.into_iter()
.map(|x| BackupContent {
filename: x.to_string(),
.map(|filename| BackupContent {
filename,
size: None,
crypt_mode: None,
})
@ -662,11 +662,11 @@ pub fn verify(
_ => bail!("parameters do not specify a backup group or snapshot"),
}
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = WorkerTask::new_thread(
worker_type,
Some(worker_id.clone()),
Some(worker_id),
auth_id.clone(),
to_stdout,
move |worker| {
@ -711,7 +711,7 @@ pub fn verify(
verify_all_backups(datastore, worker.clone(), worker.upid(), owner, None)?
};
if failed_dirs.len() > 0 {
if !failed_dirs.is_empty() {
worker.log("Failed to verify the following snapshots/groups:");
for dir in failed_dirs {
worker.log(format!("\t{}", dir));
@ -855,7 +855,7 @@ fn prune(
// We use a WorkerTask just to have a task log, but run synchrounously
let worker = WorkerTask::new("prune", Some(worker_id), auth_id.clone(), true)?;
let worker = WorkerTask::new("prune", Some(worker_id), auth_id, true)?;
if keep_all {
worker.log("No prune selection - keeping all files.");
@ -935,7 +935,7 @@ fn start_garbage_collection(
let job = Job::new("garbage_collection", &store)
.map_err(|_| format_err!("garbage collection already running"))?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = crate::server::do_garbage_collection_job(job, datastore, &auth_id, None, to_stdout)
.map_err(|err| format_err!("unable to start garbage collection job on datastore {} - {}", store, err))?;
@ -1009,7 +1009,7 @@ fn get_datastore_list(
}
}
Ok(list.into())
Ok(list)
}
#[sortable]
@ -1066,7 +1066,7 @@ fn download_file(
.map_err(|err| http_err!(BAD_REQUEST, "File open failed: {}", err))?;
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
.map_ok(|bytes| hyper::body::Bytes::from(bytes.freeze()))
.map_ok(|bytes| bytes.freeze())
.map_err(move |err| {
eprintln!("error during streaming of '{:?}' - {}", &path, err);
err
@ -1341,10 +1341,10 @@ fn catalog(
if filepath != "root" {
components = base64::decode(filepath)?;
if components.len() > 0 && components[0] == '/' as u8 {
if !components.is_empty() && components[0] == b'/' {
components.remove(0);
}
for component in components.split(|c| *c == '/' as u8) {
for component in components.split(|c| *c == b'/') {
if let Some(entry) = catalog_reader.lookup(&current, component)? {
current = entry;
} else {
@ -1357,7 +1357,7 @@ fn catalog(
for direntry in catalog_reader.read_dir(&current)? {
let mut components = components.clone();
components.push('/' as u8);
components.push(b'/');
components.extend(&direntry.name);
let path = base64::encode(components);
let text = String::from_utf8_lossy(&direntry.name);
@ -1487,13 +1487,13 @@ fn pxar_file_download(
check_priv_or_backup_owner(&datastore, backup_dir.group(), &auth_id, PRIV_DATASTORE_READ)?;
let mut components = base64::decode(&filepath)?;
if components.len() > 0 && components[0] == '/' as u8 {
if !components.is_empty() && components[0] == b'/' {
components.remove(0);
}
let mut split = components.splitn(2, |c| *c == '/' as u8);
let mut split = components.splitn(2, |c| *c == b'/');
let pxar_name = std::str::from_utf8(split.next().unwrap())?;
let file_path = split.next().ok_or(format_err!("filepath looks strange '{}'", filepath))?;
let file_path = split.next().ok_or_else(|| format_err!("filepath looks strange '{}'", filepath))?;
let (manifest, files) = read_backup_index(&datastore, &backup_dir)?;
for file in files {
if file.filename == pxar_name && file.crypt_mode == Some(CryptMode::Encrypt) {
@ -1520,7 +1520,7 @@ fn pxar_file_download(
let root = decoder.open_root().await?;
let file = root
.lookup(OsStr::from_bytes(file_path)).await?
.ok_or(format_err!("error opening '{:?}'", file_path))?;
.ok_or_else(|| format_err!("error opening '{:?}'", file_path))?;
let body = match file.kind() {
EntryKind::File { .. } => Body::wrap_stream(

View File

@ -58,7 +58,7 @@ pub fn list_sync_jobs(
}
})
.filter(|job: &SyncJobStatus| {
let as_config: SyncJobConfig = job.clone().into();
let as_config: SyncJobConfig = job.into();
check_sync_job_read_access(&user_info, &auth_id, &as_config)
}).collect();
@ -81,13 +81,13 @@ pub fn list_sync_jobs(
job.last_run_state = state;
job.last_run_endtime = endtime;
let last = job.last_run_endtime.unwrap_or_else(|| starttime);
let last = job.last_run_endtime.unwrap_or(starttime);
job.next_run = (|| -> Option<i64> {
let schedule = job.schedule.as_ref()?;
let event = parse_calendar_event(&schedule).ok()?;
// ignore errors
compute_next_event(&event, last, false).unwrap_or_else(|_| None)
compute_next_event(&event, last, false).unwrap_or(None)
})();
}

View File

@ -86,13 +86,13 @@ pub fn list_verification_jobs(
job.last_run_state = state;
job.last_run_endtime = endtime;
let last = job.last_run_endtime.unwrap_or_else(|| starttime);
let last = job.last_run_endtime.unwrap_or(starttime);
job.next_run = (|| -> Option<i64> {
let schedule = job.schedule.as_ref()?;
let event = parse_calendar_event(&schedule).ok()?;
// ignore errors
compute_next_event(&event, last, false).unwrap_or_else(|_| None)
compute_next_event(&event, last, false).unwrap_or(None)
})();
}

View File

@ -138,7 +138,7 @@ async move {
}
};
let backup_dir = BackupDir::with_group(backup_group.clone(), backup_time)?;
let backup_dir = BackupDir::with_group(backup_group, backup_time)?;
let _last_guard = if let Some(last) = &last_backup {
if backup_dir.backup_time() <= last.backup_dir.backup_time() {

View File

@ -465,7 +465,7 @@ impl BackupEnvironment {
state.ensure_unfinished()?;
// test if all writer are correctly closed
if state.dynamic_writers.len() != 0 || state.fixed_writers.len() != 0 {
if !state.dynamic_writers.is_empty() || !state.fixed_writers.is_empty() {
bail!("found open index writer - unable to finish backup");
}

View File

@ -120,11 +120,11 @@ pub fn create_datastore(param: Value) -> Result<(), Error> {
let _lock = open_file_locked(datastore::DATASTORE_CFG_LOCKFILE, std::time::Duration::new(10, 0), true)?;
let datastore: datastore::DataStoreConfig = serde_json::from_value(param.clone())?;
let datastore: datastore::DataStoreConfig = serde_json::from_value(param)?;
let (mut config, _digest) = datastore::config()?;
if let Some(_) = config.sections.get(&datastore.name) {
if config.sections.get(&datastore.name).is_some() {
bail!("datastore '{}' already exists.", datastore.name);
}

View File

@ -96,13 +96,13 @@ pub fn create_remote(password: String, param: Value) -> Result<(), Error> {
let _lock = open_file_locked(remote::REMOTE_CFG_LOCKFILE, std::time::Duration::new(10, 0), true)?;
let mut data = param.clone();
let mut data = param;
data["password"] = Value::from(base64::encode(password.as_bytes()));
let remote: remote::Remote = serde_json::from_value(data)?;
let (mut config, _digest) = remote::config()?;
if let Some(_) = config.sections.get(&remote.name) {
if config.sections.get(&remote.name).is_some() {
bail!("remote '{}' already exists.", remote.name);
}

View File

@ -154,14 +154,14 @@ pub fn create_sync_job(
let _lock = open_file_locked(sync::SYNC_CFG_LOCKFILE, std::time::Duration::new(10, 0), true)?;
let sync_job: sync::SyncJobConfig = serde_json::from_value(param.clone())?;
let sync_job: sync::SyncJobConfig = serde_json::from_value(param)?;
if !check_sync_job_modify_access(&user_info, &auth_id, &sync_job) {
bail!("permission check failed");
}
let (mut config, _digest) = sync::config()?;
if let Some(_) = config.sections.get(&sync_job.id) {
if config.sections.get(&sync_job.id).is_some() {
bail!("job '{}' already exists.", sync_job.id);
}
@ -514,7 +514,7 @@ acl:1:/remote/remote1/remotestore1:write@pbs:RemoteSyncOperator
// unless they have Datastore.Modify as well
job.store = "localstore3".to_string();
job.owner = Some(read_auth_id.clone());
job.owner = Some(read_auth_id);
assert_eq!(check_sync_job_modify_access(&user_info, &write_auth_id, &job), true);
job.owner = None;
assert_eq!(check_sync_job_modify_access(&user_info, &write_auth_id, &job), true);

View File

@ -98,7 +98,7 @@ pub fn create_verification_job(
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let user_info = CachedUserInfo::new()?;
let verification_job: verify::VerificationJobConfig = serde_json::from_value(param.clone())?;
let verification_job: verify::VerificationJobConfig = serde_json::from_value(param)?;
user_info.check_privs(&auth_id, &["datastore", &verification_job.store], PRIV_DATASTORE_VERIFY, false)?;
@ -106,7 +106,7 @@ pub fn create_verification_job(
let (mut config, _digest) = verify::config()?;
if let Some(_) = config.sections.get(&verification_job.id) {
if config.sections.get(&verification_job.id).is_some() {
bail!("job '{}' already exists.", verification_job.id);
}

View File

@ -16,7 +16,7 @@ pub async fn create_download_response(path: PathBuf) -> Result<Response<Body>, E
};
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
.map_ok(|bytes| hyper::body::Bytes::from(bytes.freeze()));
.map_ok(|bytes| bytes.freeze());
let body = Body::wrap_stream(payload);

View File

@ -121,7 +121,7 @@ async fn termproxy(
)?;
let mut command = Vec::new();
match cmd.as_ref().map(|x| x.as_str()) {
match cmd.as_deref() {
Some("login") | None => {
command.push("login");
if userid == "root@pam" {

View File

@ -35,18 +35,15 @@ use crate::api2::types::{Authid, APTUpdateInfo, NODE_SCHEMA, UPID_SCHEMA};
/// List available APT updates
fn apt_update_available(_param: Value) -> Result<Value, Error> {
match apt::pkg_cache_expired() {
Ok(false) => {
if let Ok(Some(cache)) = apt::read_pkg_state() {
return Ok(json!(cache.package_status));
}
},
_ => (),
if let Ok(false) = apt::pkg_cache_expired() {
if let Ok(Some(cache)) = apt::read_pkg_state() {
return Ok(json!(cache.package_status));
}
}
let cache = apt::update_cache()?;
return Ok(json!(cache.package_status));
Ok(json!(cache.package_status))
}
fn do_apt_update(worker: &WorkerTask, quiet: bool) -> Result<(), Error> {
@ -90,8 +87,8 @@ fn do_apt_update(worker: &WorkerTask, quiet: bool) -> Result<(), Error> {
type: bool,
description: r#"Send notification mail about new package updates availanle to the
email address configured for 'root@pam')."#,
optional: true,
default: false,
optional: true,
},
quiet: {
description: "Only produces output suitable for logging, omitting progress indicators.",
@ -116,7 +113,7 @@ pub fn apt_update_database(
) -> Result<String, Error> {
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
// FIXME: change to non-option in signature and drop below once we have proxmox-api-macro 0.2.3
let quiet = quiet.unwrap_or(API_METHOD_APT_UPDATE_DATABASE_PARAM_DEFAULT_QUIET);
let notify = notify.unwrap_or(API_METHOD_APT_UPDATE_DATABASE_PARAM_DEFAULT_NOTIFY);
@ -196,7 +193,7 @@ fn apt_get_changelog(
}
}, Some(&name));
if pkg_info.len() == 0 {
if pkg_info.is_empty() {
bail!("Package '{}' not found", name);
}
@ -205,7 +202,7 @@ fn apt_get_changelog(
if changelog_url.starts_with("http://download.proxmox.com/") {
let changelog = crate::tools::runtime::block_on(http::get_string(changelog_url, None))
.map_err(|err| format_err!("Error downloading changelog from '{}': {}", changelog_url, err))?;
return Ok(json!(changelog));
Ok(json!(changelog))
} else if changelog_url.starts_with("https://enterprise.proxmox.com/") {
let sub = match subscription::read_subscription()? {
@ -229,7 +226,7 @@ fn apt_get_changelog(
let changelog = crate::tools::runtime::block_on(http::get_string(changelog_url, Some(&auth_header)))
.map_err(|err| format_err!("Error downloading changelog from '{}': {}", changelog_url, err))?;
return Ok(json!(changelog));
Ok(json!(changelog))
} else {
let mut command = std::process::Command::new("apt-get");
@ -237,7 +234,7 @@ fn apt_get_changelog(
command.arg("-qq"); // don't display download progress
command.arg(name);
let output = crate::tools::run_command(command, None)?;
return Ok(json!(output));
Ok(json!(output))
}
}

View File

@ -138,7 +138,7 @@ pub fn initialize_disk(
rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> {
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;

View File

@ -132,7 +132,7 @@ pub fn create_datastore_disk(
rpcenv: &mut dyn RpcEnvironment,
) -> Result<String, Error> {
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
@ -164,7 +164,7 @@ pub fn create_datastore_disk(
let manager = DiskManage::new();
let disk = manager.clone().disk_by_name(&disk)?;
let disk = manager.disk_by_name(&disk)?;
let partition = create_single_linux_partition(&disk)?;
create_file_system(&partition, filesystem)?;
@ -212,8 +212,7 @@ pub fn delete_datastore_disk(name: String) -> Result<(), Error> {
let (config, _) = crate::config::datastore::config()?;
let datastores: Vec<DataStoreConfig> = config.convert_to_typed_array("datastore")?;
let conflicting_datastore: Option<DataStoreConfig> = datastores.into_iter()
.filter(|ds| ds.path == path)
.next();
.find(|ds| ds.path == path);
if let Some(conflicting_datastore) = conflicting_datastore {
bail!("Can't remove '{}' since it's required by datastore '{}'",

View File

@ -254,7 +254,7 @@ pub fn create_zpool(
rpcenv: &mut dyn RpcEnvironment,
) -> Result<String, Error> {
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;

View File

@ -137,7 +137,7 @@ pub fn set_subscription(
let server_id = tools::get_hardware_address()?;
let info = subscription::check_subscription(key, server_id.to_owned())?;
let info = subscription::check_subscription(key, server_id)?;
subscription::write_subscription(info)
.map_err(|e| format_err!("Error writing subscription status - {}", e))?;

View File

@ -513,7 +513,7 @@ pub fn list_tasks(
.collect();
let mut count = result.len() + start as usize;
if result.len() > 0 && result.len() >= limit { // we have a 'virtual' entry as long as we have any new
if !result.is_empty() && result.len() >= limit { // we have a 'virtual' entry as long as we have any new
count += 1;
}

View File

@ -88,7 +88,7 @@ pub fn do_sync_job(
let worker_future = async move {
let delete = sync_job.remove_vanished.unwrap_or(true);
let sync_owner = sync_job.owner.unwrap_or(Authid::root_auth_id().clone());
let sync_owner = sync_job.owner.unwrap_or_else(|| Authid::root_auth_id().clone());
let (client, src_repo, tgt_store) = get_pull_parameters(&sync_job.store, &sync_job.remote, &sync_job.remote_store).await?;
worker.log(format!("Starting datastore sync job '{}'", job_id));

View File

@ -150,16 +150,16 @@ fn upgrade_to_backup_reader_protocol(
}
});
let abort_future = abort_future
.map(|_| Err(format_err!("task aborted")));
.map(|_| -> Result<(), anyhow::Error> { Err(format_err!("task aborted")) });
use futures::future::Either;
futures::future::select(req_fut, abort_future)
.map(move |res| {
let _guard = _guard;
match res {
Either::Left((Ok(res), _)) => Ok(res),
Either::Left((Ok(_), _)) => Ok(()),
Either::Left((Err(err), _)) => Err(err),
Either::Right((Ok(res), _)) => Ok(res),
Either::Right((Ok(_), _)) => Ok(()),
Either::Right((Err(err), _)) => Err(err),
}
})

View File

@ -127,49 +127,46 @@ fn datastore_status(
rrd_mode,
);
match (total_res, used_res) {
(Some((start, reso, total_list)), Some((_, _, used_list))) => {
let mut usage_list: Vec<f64> = Vec::new();
let mut time_list: Vec<u64> = Vec::new();
let mut history = Vec::new();
if let (Some((start, reso, total_list)), Some((_, _, used_list))) = (total_res, used_res) {
let mut usage_list: Vec<f64> = Vec::new();
let mut time_list: Vec<u64> = Vec::new();
let mut history = Vec::new();
for (idx, used) in used_list.iter().enumerate() {
let total = if idx < total_list.len() {
total_list[idx]
for (idx, used) in used_list.iter().enumerate() {
let total = if idx < total_list.len() {
total_list[idx]
} else {
None
};
match (total, used) {
(Some(total), Some(used)) if total != 0.0 => {
time_list.push(start + (idx as u64)*reso);
let usage = used/total;
usage_list.push(usage);
history.push(json!(usage));
},
_ => {
history.push(json!(null))
}
}
}
entry["history-start"] = start.into();
entry["history-delta"] = reso.into();
entry["history"] = history.into();
// we skip the calculation for datastores with not enough data
if usage_list.len() >= 7 {
if let Some((a,b)) = linear_regression(&time_list, &usage_list) {
if b != 0.0 {
let estimate = (1.0 - a) / b;
entry["estimated-full-date"] = Value::from(estimate.floor() as u64);
} else {
None
};
match (total, used) {
(Some(total), Some(used)) if total != 0.0 => {
time_list.push(start + (idx as u64)*reso);
let usage = used/total;
usage_list.push(usage);
history.push(json!(usage));
},
_ => {
history.push(json!(null))
}
entry["estimated-full-date"] = Value::from(0);
}
}
entry["history-start"] = start.into();
entry["history-delta"] = reso.into();
entry["history"] = history.into();
// we skip the calculation for datastores with not enough data
if usage_list.len() >= 7 {
if let Some((a,b)) = linear_regression(&time_list, &usage_list) {
if b != 0.0 {
let estimate = (1.0 - a) / b;
entry["estimated-full-date"] = Value::from(estimate.floor() as u64);
} else {
entry["estimated-full-date"] = Value::from(0);
}
}
}
},
_ => {},
}
}
list.push(entry);

View File

@ -87,14 +87,14 @@ pub fn backup(
// early check before starting worker
check_drive_exists(&drive_config, &pool_config.drive)?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let eject_media = eject_media.unwrap_or(false);
let export_media_set = export_media_set.unwrap_or(false);
let upid_str = WorkerTask::new_thread(
"tape-backup",
Some(store.clone()),
Some(store),
auth_id,
to_stdout,
move |worker| {

View File

@ -226,7 +226,7 @@ pub fn erase_media(
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = WorkerTask::new_thread(
"erase-media",
@ -267,7 +267,7 @@ pub fn rewind(
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = WorkerTask::new_thread(
"rewind-media",
@ -353,7 +353,7 @@ pub fn label_media(
let (config, _digest) = config::drive::config()?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = WorkerTask::new_thread(
"label-media",
@ -595,7 +595,7 @@ pub fn clean_drive(
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = WorkerTask::new_thread(
"clean-drive",
@ -722,7 +722,7 @@ pub fn update_inventory(
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = WorkerTask::new_thread(
"inventory-update",
@ -735,7 +735,7 @@ pub fn update_inventory(
let label_text_list = changer.online_media_label_texts()?;
if label_text_list.is_empty() {
worker.log(format!("changer device does not list any media labels"));
worker.log("changer device does not list any media labels".to_string());
}
let state_path = Path::new(TAPE_STATUS_DIR);
@ -752,11 +752,9 @@ pub fn update_inventory(
let label_text = label_text.to_string();
if !read_all_labels.unwrap_or(false) {
if let Some(_) = inventory.find_media_by_label_text(&label_text) {
worker.log(format!("media '{}' already inventoried", label_text));
continue;
}
if !read_all_labels.unwrap_or(false) && inventory.find_media_by_label_text(&label_text).is_some() {
worker.log(format!("media '{}' already inventoried", label_text));
continue;
}
if let Err(err) = changer.load_media(&label_text) {
@ -824,7 +822,7 @@ pub fn barcode_label_media(
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = WorkerTask::new_thread(
"barcode-label-media",
@ -1002,7 +1000,7 @@ pub fn catalog_media(
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = WorkerTask::new_thread(
"catalog-media",
@ -1060,10 +1058,8 @@ pub fn catalog_media(
let _lock = MediaPool::lock(status_path, &pool)?;
if MediaCatalog::exists(status_path, &media_id.label.uuid) {
if !force {
bail!("media catalog exists (please use --force to overwrite)");
}
if MediaCatalog::exists(status_path, &media_id.label.uuid) && !force {
bail!("media catalog exists (please use --force to overwrite)");
}
restore_media(&worker, &mut drive, &media_id, None, verbose)?;

View File

@ -197,7 +197,6 @@ pub fn destroy_media(label_text: String, force: Option<bool>,) -> Result<(), Err
}
let uuid = media_id.label.uuid.clone();
drop(media_id);
inventory.remove_media(&uuid)?;

View File

@ -115,7 +115,7 @@ pub fn restore(
// early check before starting worker
check_drive_exists(&drive_config, &pool_config.drive)?;
let to_stdout = if rpcenv.env_type() == RpcEnvironmentType::CLI { true } else { false };
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
let upid_str = WorkerTask::new_thread(
"tape-restore",
@ -128,7 +128,7 @@ pub fn restore(
let members = inventory.compute_media_set_members(&media_set_uuid)?;
let media_list = members.media_list().clone();
let media_list = members.media_list();
let mut media_id_list = Vec::new();
@ -234,7 +234,6 @@ pub fn restore_media(
Some(reader) => reader,
};
let target = target.clone();
restore_archive(worker, reader, current_file_number, target, &mut catalog, verbose)?;
}
@ -344,36 +343,26 @@ fn restore_chunk_archive<'a>(
let mut decoder = ChunkArchiveDecoder::new(reader);
let result: Result<_, Error> = proxmox::try_block!({
loop {
match decoder.next_chunk()? {
Some((digest, blob)) => {
while let Some((digest, blob)) = decoder.next_chunk()? {
if let Some(datastore) = datastore {
let chunk_exists = datastore.cond_touch_chunk(&digest, false)?;
if !chunk_exists {
blob.verify_crc()?;
if let Some(datastore) = datastore {
let chunk_exists = datastore.cond_touch_chunk(&digest, false)?;
if !chunk_exists {
blob.verify_crc()?;
if blob.crypt_mode()? == CryptMode::None {
blob.decode(None, Some(&digest))?; // verify digest
}
if verbose {
worker.log(format!("Insert chunk: {}", proxmox::tools::digest_to_hex(&digest)));
}
datastore.insert_chunk(&blob, &digest)?;
} else {
if verbose {
worker.log(format!("Found existing chunk: {}", proxmox::tools::digest_to_hex(&digest)));
}
}
} else {
if verbose {
worker.log(format!("Found chunk: {}", proxmox::tools::digest_to_hex(&digest)));
}
if blob.crypt_mode()? == CryptMode::None {
blob.decode(None, Some(&digest))?; // verify digest
}
chunks.push(digest);
if verbose {
worker.log(format!("Insert chunk: {}", proxmox::tools::digest_to_hex(&digest)));
}
datastore.insert_chunk(&blob, &digest)?;
} else if verbose {
worker.log(format!("Found existing chunk: {}", proxmox::tools::digest_to_hex(&digest)));
}
None => break,
} else if verbose {
worker.log(format!("Found chunk: {}", proxmox::tools::digest_to_hex(&digest)));
}
chunks.push(digest);
}
Ok(())
});
@ -390,7 +379,7 @@ fn restore_chunk_archive<'a>(
// check if this is an aborted stream without end marker
if let Ok(false) = reader.has_end_marker() {
worker.log(format!("missing stream end marker"));
worker.log("missing stream end marker".to_string());
return Ok(None);
}
@ -407,7 +396,7 @@ fn restore_snapshot_archive<'a>(
let mut decoder = pxar::decoder::sync::Decoder::from_std(reader)?;
match try_restore_snapshot_archive(&mut decoder, snapshot_path) {
Ok(()) => return Ok(true),
Ok(()) => Ok(true),
Err(err) => {
let reader = decoder.input();
@ -422,7 +411,7 @@ fn restore_snapshot_archive<'a>(
}
// else the archive is corrupt
return Err(err);
Err(err)
}
}
}

View File

@ -1092,7 +1092,7 @@ fn test_cert_fingerprint_schema() -> Result<(), anyhow::Error> {
];
for fingerprint in invalid_fingerprints.iter() {
if let Ok(_) = parse_simple_value(fingerprint, &schema) {
if parse_simple_value(fingerprint, &schema).is_ok() {
bail!("test fingerprint '{}' failed - got Ok() while exception an error.", fingerprint);
}
}
@ -1133,7 +1133,7 @@ fn test_proxmox_user_id_schema() -> Result<(), anyhow::Error> {
];
for name in invalid_user_ids.iter() {
if let Ok(_) = parse_simple_value(name, &Userid::API_SCHEMA) {
if parse_simple_value(name, &Userid::API_SCHEMA).is_ok() {
bail!("test userid '{}' failed - got Ok() while exception an error.", name);
}
}

View File

@ -277,7 +277,7 @@ impl PartialEq<&str> for RealmRef {
impl PartialEq<RealmRef> for Realm {
fn eq(&self, rhs: &RealmRef) -> bool {
self.0 == &rhs.0
self.0 == rhs.0
}
}
@ -638,7 +638,7 @@ impl std::str::FromStr for Authid {
.iter()
.rposition(|&b| b == b'!')
.map(|pos| if pos < name_len { id.len() } else { pos })
.unwrap_or(id.len());
.unwrap_or_else(|| id.len());
if realm_end == id.len() - 1 {
bail!("empty token name in userid");
@ -670,7 +670,7 @@ impl TryFrom<String> for Authid {
.iter()
.rposition(|&b| b == b'!')
.map(|pos| if pos < name_len { data.len() } else { pos })
.unwrap_or(data.len());
.unwrap_or_else(|| data.len());
if realm_end == data.len() - 1 {
bail!("empty token name in userid");

View File

@ -97,7 +97,7 @@ where
let info = this
.index
.chunk_info(idx)
.ok_or(io_format_err!("could not get digest"))?;
.ok_or_else(|| io_format_err!("could not get digest"))?;
this.current_chunk_offset = offset;
this.current_chunk_idx = idx;

View File

@ -137,18 +137,12 @@ impl DirEntry {
/// Check if DirEntry is a directory
pub fn is_directory(&self) -> bool {
match self.attr {
DirEntryAttribute::Directory { .. } => true,
_ => false,
}
matches!(self.attr, DirEntryAttribute::Directory { .. })
}
/// Check if DirEntry is a symlink
pub fn is_symlink(&self) -> bool {
match self.attr {
DirEntryAttribute::Symlink { .. } => true,
_ => false,
}
matches!(self.attr, DirEntryAttribute::Symlink { .. })
}
}
@ -591,6 +585,7 @@ impl <R: Read + Seek> CatalogReader<R> {
///
/// Stores 7 bits per byte, Bit 8 indicates the end of the sequence (when not set).
/// If the value is negative, we end with a zero byte (0x00).
#[allow(clippy::neg_multiply)]
pub fn catalog_encode_i64<W: Write>(writer: &mut W, v: i64) -> Result<(), Error> {
let mut enc = Vec::new();
@ -611,7 +606,7 @@ pub fn catalog_encode_i64<W: Write>(writer: &mut W, v: i64) -> Result<(), Error>
break;
}
enc.push((128 | (d & 127)) as u8);
d = d >> 7;
d >>= 7;
}
writer.write_all(&enc)?;
@ -623,6 +618,7 @@ pub fn catalog_encode_i64<W: Write>(writer: &mut W, v: i64) -> Result<(), Error>
/// We currently read maximal 11 bytes, which give a maximum of 70 bits + sign.
/// this method is compatible with catalog_encode_u64 iff the
/// value encoded is <= 2^63 (values > 2^63 cannot be represented in an i64)
#[allow(clippy::neg_multiply)]
pub fn catalog_decode_i64<R: Read>(reader: &mut R) -> Result<i64, Error> {
let mut v: u64 = 0;
@ -665,7 +661,7 @@ pub fn catalog_encode_u64<W: Write>(writer: &mut W, v: u64) -> Result<(), Error>
break;
}
enc.push((128 | (d & 127)) as u8);
d = d >> 7;
d >>= 7;
}
writer.write_all(&enc)?;

View File

@ -441,8 +441,7 @@ impl Shell {
R: 'static,
{
let shell: &mut Shell = unsafe { std::mem::transmute(SHELL.unwrap()) };
let result = call(&mut *shell).await;
result
call(&mut *shell).await
}
pub async fn shell(mut self) -> Result<(), Error> {

View File

@ -18,7 +18,7 @@ impl <W: Write> ChecksumWriter<W> {
let hasher = crc32fast::Hasher::new();
let signer = match config {
Some(config) => {
let tied_signer = Tied::new(config.clone(), |config| {
let tied_signer = Tied::new(config, |config| {
Box::new(unsafe { (*config).data_signer() })
});
Some(tied_signer)

View File

@ -44,7 +44,7 @@ fn digest_to_prefix(digest: &[u8]) -> PathBuf {
buf.push(HEX_CHARS[(digest[0] as usize) &0xf]);
buf.push(HEX_CHARS[(digest[1] as usize) >> 4]);
buf.push(HEX_CHARS[(digest[1] as usize) & 0xf]);
buf.push('/' as u8);
buf.push(b'/');
let path = unsafe { String::from_utf8_unchecked(buf)};
@ -80,7 +80,7 @@ impl ChunkStore {
let default_options = CreateOptions::new();
match create_path(&base, Some(default_options.clone()), Some(options.clone())) {
match create_path(&base, Some(default_options), Some(options.clone())) {
Err(err) => bail!("unable to create chunk store '{}' at {:?} - {}", name, base, err),
Ok(res) => if ! res { nix::unistd::chown(&base, Some(uid), Some(gid))? },
}
@ -113,9 +113,8 @@ impl ChunkStore {
}
fn lockfile_path<P: Into<PathBuf>>(base: P) -> PathBuf {
let base: PathBuf = base.into();
let mut lockfile_path: PathBuf = base.into();
let mut lockfile_path = base.clone();
lockfile_path.push(".lock");
lockfile_path
@ -227,7 +226,7 @@ impl ChunkStore {
continue;
}
let bad = bytes.ends_with(".bad".as_bytes());
let bad = bytes.ends_with(b".bad");
return Some((Ok(entry), percentage, bad));
}
Some(Err(err)) => {
@ -402,7 +401,7 @@ impl ChunkStore {
file.write_all(raw_data)?;
if let Err(err) = std::fs::rename(&tmp_path, &chunk_path) {
if let Err(_) = std::fs::remove_file(&tmp_path) { /* ignore */ }
if std::fs::remove_file(&tmp_path).is_err() { /* ignore */ }
bail!(
"Atomic rename on store '{}' failed for chunk {} - {}",
self.name,

View File

@ -59,7 +59,7 @@ where
}
None => {
this.scan_pos = 0;
if this.buffer.len() > 0 {
if !this.buffer.is_empty() {
return Poll::Ready(Some(Ok(this.buffer.split())));
} else {
return Poll::Ready(None);
@ -111,7 +111,7 @@ where
}
None => {
// last chunk can have any size
if this.buffer.len() > 0 {
if !this.buffer.is_empty() {
return Poll::Ready(Some(Ok(this.buffer.split())));
} else {
return Poll::Ready(None);

View File

@ -36,7 +36,7 @@ impl <R: BufRead> CryptReader<R> {
impl <R: BufRead> Read for CryptReader<R> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
if self.small_read_buf.len() > 0 {
if !self.small_read_buf.is_empty() {
let max = if self.small_read_buf.len() > buf.len() { buf.len() } else { self.small_read_buf.len() };
let rest = self.small_read_buf.split_off(max);
buf[..max].copy_from_slice(&self.small_read_buf);
@ -50,7 +50,7 @@ impl <R: BufRead> Read for CryptReader<R> {
if buf.len() <= 2*self.block_size {
let mut outbuf = [0u8; 1024];
let count = if data.len() == 0 { // EOF
let count = if data.is_empty() { // EOF
let written = self.crypter.finalize(&mut outbuf)?;
self.finalized = true;
written
@ -72,7 +72,7 @@ impl <R: BufRead> Read for CryptReader<R> {
buf[..count].copy_from_slice(&outbuf[..count]);
Ok(count)
}
} else if data.len() == 0 { // EOF
} else if data.is_empty() { // EOF
let rest = self.crypter.finalize(buf)?;
self.finalized = true;
Ok(rest)

View File

@ -408,9 +408,7 @@ impl <'a, 'b> DataChunkBuilder<'a, 'b> {
chunk_size: usize,
compress: bool,
) -> Result<(DataBlob, [u8; 32]), Error> {
let mut zero_bytes = Vec::with_capacity(chunk_size);
zero_bytes.resize(chunk_size, 0u8);
let zero_bytes = vec![0; chunk_size];
let mut chunk_builder = DataChunkBuilder::new(&zero_bytes).compress(compress);
if let Some(ref crypt_config) = crypt_config {
chunk_builder = chunk_builder.crypt_config(crypt_config);

View File

@ -334,9 +334,7 @@ impl DataStore {
auth_id: &Authid,
) -> Result<(Authid, DirLockGuard), Error> {
// create intermediate path first:
let base_path = self.base_path();
let mut full_path = base_path.clone();
let mut full_path = self.base_path();
full_path.push(backup_group.backup_type());
std::fs::create_dir_all(&full_path)?;
@ -392,7 +390,7 @@ impl DataStore {
fn is_hidden(entry: &walkdir::DirEntry) -> bool {
entry.file_name()
.to_str()
.map(|s| s.starts_with("."))
.map(|s| s.starts_with('.'))
.unwrap_or(false)
}
let handle_entry_err = |err: walkdir::Error| {
@ -478,12 +476,11 @@ impl DataStore {
let image_list = self.list_images()?;
let image_count = image_list.len();
let mut done = 0;
let mut last_percentage: usize = 0;
let mut strange_paths_count: u64 = 0;
for img in image_list {
for (i, img) in image_list.into_iter().enumerate() {
worker.check_abort()?;
tools::fail_on_shutdown()?;
@ -516,15 +513,14 @@ impl DataStore {
Err(err) if err.kind() == io::ErrorKind::NotFound => (), // ignore vanished files
Err(err) => bail!("can't open index {} - {}", img.to_string_lossy(), err),
}
done += 1;
let percentage = done*100/image_count;
let percentage = (i + 1) * 100 / image_count;
if percentage > last_percentage {
crate::task_log!(
worker,
"marked {}% ({} of {} index files)",
percentage,
done,
i + 1,
image_count,
);
last_percentage = percentage;
@ -548,7 +544,7 @@ impl DataStore {
}
pub fn garbage_collection_running(&self) -> bool {
if let Ok(_) = self.gc_mutex.try_lock() { false } else { true }
!matches!(self.gc_mutex.try_lock(), Ok(_))
}
pub fn garbage_collection(&self, worker: &dyn TaskState, upid: &UPID) -> Result<(), Error> {

View File

@ -194,7 +194,7 @@ impl IndexFile for DynamicIndexReader {
if pos >= self.index.len() {
None
} else {
Some(unsafe { std::mem::transmute(self.chunk_digest(pos).as_ptr()) })
Some(unsafe { &*(self.chunk_digest(pos).as_ptr() as *const [u8; 32]) })
}
}
@ -229,7 +229,7 @@ impl IndexFile for DynamicIndexReader {
Some(ChunkReadInfo {
range: start..end,
digest: self.index[pos].digest.clone(),
digest: self.index[pos].digest,
})
}

View File

@ -63,11 +63,11 @@ pub struct EncryptedDataBlobHeader {
///
/// Panics on unknown magic numbers.
pub fn header_size(magic: &[u8; 8]) -> usize {
match magic {
&UNCOMPRESSED_BLOB_MAGIC_1_0 => std::mem::size_of::<DataBlobHeader>(),
&COMPRESSED_BLOB_MAGIC_1_0 => std::mem::size_of::<DataBlobHeader>(),
&ENCRYPTED_BLOB_MAGIC_1_0 => std::mem::size_of::<EncryptedDataBlobHeader>(),
&ENCR_COMPR_BLOB_MAGIC_1_0 => std::mem::size_of::<EncryptedDataBlobHeader>(),
match *magic {
UNCOMPRESSED_BLOB_MAGIC_1_0 => std::mem::size_of::<DataBlobHeader>(),
COMPRESSED_BLOB_MAGIC_1_0 => std::mem::size_of::<DataBlobHeader>(),
ENCRYPTED_BLOB_MAGIC_1_0 => std::mem::size_of::<EncryptedDataBlobHeader>(),
ENCR_COMPR_BLOB_MAGIC_1_0 => std::mem::size_of::<EncryptedDataBlobHeader>(),
_ => panic!("unknown blob magic"),
}
}

View File

@ -60,7 +60,7 @@ impl FixedIndexReader {
pub fn open(path: &Path) -> Result<Self, Error> {
File::open(path)
.map_err(Error::from)
.and_then(|file| Self::new(file))
.and_then(Self::new)
.map_err(|err| format_err!("Unable to open fixed index {:?} - {}", path, err))
}
@ -126,7 +126,7 @@ impl FixedIndexReader {
}
fn unmap(&mut self) -> Result<(), Error> {
if self.index == std::ptr::null_mut() {
if self.index.is_null() {
return Ok(());
}
@ -166,7 +166,7 @@ impl IndexFile for FixedIndexReader {
if pos >= self.index_length {
None
} else {
Some(unsafe { std::mem::transmute(self.index.add(pos * 32)) })
Some(unsafe { &*(self.index.add(pos * 32) as *const [u8; 32]) })
}
}
@ -324,7 +324,7 @@ impl FixedIndexWriter {
}
fn unmap(&mut self) -> Result<(), Error> {
if self.index == std::ptr::null_mut() {
if self.index.is_null() {
return Ok(());
}
@ -342,7 +342,7 @@ impl FixedIndexWriter {
}
pub fn close(&mut self) -> Result<[u8; 32], Error> {
if self.index == std::ptr::null_mut() {
if self.index.is_null() {
bail!("cannot close already closed index file.");
}
@ -437,7 +437,7 @@ impl FixedIndexWriter {
);
}
if self.index == std::ptr::null_mut() {
if self.index.is_null() {
bail!("cannot write to closed index file.");
}

View File

@ -336,7 +336,7 @@ pub fn rsa_decrypt_key_config(
let decrypted = rsa
.private_decrypt(key, &mut buffer, openssl::rsa::Padding::PKCS1)
.map_err(|err| format_err!("failed to decrypt KeyConfig using RSA - {}", err))?;
decrypt_key(&mut buffer[..decrypted], passphrase)
decrypt_key(&buffer[..decrypted], passphrase)
}
#[test]
@ -372,9 +372,9 @@ fn encrypt_decrypt_test() -> Result<(), Error> {
hint: None,
};
let encrypted = rsa_encrypt_key_config(public.clone(), &key).expect("encryption failed");
let encrypted = rsa_encrypt_key_config(public, &key).expect("encryption failed");
let (decrypted, created, fingerprint) =
rsa_decrypt_key_config(private.clone(), &encrypted, &passphrase)
rsa_decrypt_key_config(private, &encrypted, &passphrase)
.expect("decryption failed");
assert_eq!(key.created, created);

View File

@ -186,7 +186,7 @@ impl BackupManifest {
manifest["unprotected"]["key-fingerprint"] = serde_json::to_value(fingerprint)?;
}
let manifest = serde_json::to_string_pretty(&manifest).unwrap().into();
let manifest = serde_json::to_string_pretty(&manifest).unwrap();
Ok(manifest)
}

View File

@ -8,7 +8,7 @@ enum PruneMark { Keep, KeepPartial, Remove }
fn mark_selections<F: Fn(&BackupInfo) -> Result<String, Error>> (
mark: &mut HashMap<PathBuf, PruneMark>,
list: &Vec<BackupInfo>,
list: &[BackupInfo],
keep: usize,
select_id: F,
) -> Result<(), Error> {
@ -26,7 +26,7 @@ fn mark_selections<F: Fn(&BackupInfo) -> Result<String, Error>> (
for info in list {
let backup_id = info.backup_dir.relative_path();
if let Some(_) = mark.get(&backup_id) { continue; }
if mark.get(&backup_id).is_some() { continue; }
let sel_id: String = select_id(&info)?;
if already_included.contains(&sel_id) { continue; }
@ -45,7 +45,7 @@ fn mark_selections<F: Fn(&BackupInfo) -> Result<String, Error>> (
fn remove_incomplete_snapshots(
mark: &mut HashMap<PathBuf, PruneMark>,
list: &Vec<BackupInfo>,
list: &[BackupInfo],
) {
let mut keep_unfinished = true;

View File

@ -342,7 +342,7 @@ pub fn verify_backup_dir_with_lock(
};
if let Some(filter) = filter {
if filter(&manifest) == false {
if !filter(&manifest) {
task_log!(
worker,
"SKIPPED: verify {}:{} (recently verified)",

View File

@ -898,7 +898,7 @@ async fn create_backup(
}
}
let backup_time = backup_time_opt.unwrap_or_else(|| epoch_i64());
let backup_time = backup_time_opt.unwrap_or_else(epoch_i64);
let client = connect(&repo)?;
record_repository(&repo);
@ -917,7 +917,7 @@ async fn create_backup(
let (key, created, fingerprint) = decrypt_key(&key, &key::get_encryption_key_password)?;
println!("Encryption key fingerprint: {}", fingerprint);
let crypt_config = CryptConfig::new(key.clone())?;
let crypt_config = CryptConfig::new(key)?;
match key::find_master_pubkey()? {
Some(ref path) if path.exists() => {
@ -1464,7 +1464,7 @@ async fn prune_async(mut param: Value) -> Result<Value, Error> {
if quiet {
let list: Vec<Value> = data.as_array().unwrap().iter().filter(|item| {
item["keep"].as_bool() == Some(false)
}).map(|v| v.clone()).collect();
}).cloned().collect();
data = list.into();
}

View File

@ -4,7 +4,7 @@ use std::os::unix::io::AsRawFd;
use anyhow::{bail, format_err, Error};
use futures::*;
use hyper;
use openssl::ssl::{SslMethod, SslAcceptor, SslFiletype};
use tokio_stream::wrappers::ReceiverStream;
@ -218,10 +218,8 @@ fn accept_connections(
match result {
Ok(Ok(())) => {
if let Err(_) = sender.send(Ok(stream)).await {
if debug {
eprintln!("detect closed connection channel");
}
if sender.send(Ok(stream)).await.is_err() && debug {
eprintln!("detect closed connection channel");
}
}
Ok(Err(err)) => {
@ -583,16 +581,16 @@ async fn schedule_task_log_rotate() {
false,
move |worker| {
job.start(&worker.upid().to_string())?;
worker.log(format!("starting task log rotation"));
worker.log("starting task log rotation".to_string());
let result = try_block!({
let max_size = 512 * 1024 - 1; // an entry has ~ 100b, so > 5000 entries/file
let max_files = 20; // times twenty files gives > 100000 task entries
let has_rotated = rotate_task_log_archive(max_size, true, Some(max_files))?;
if has_rotated {
worker.log(format!("task log archive was rotated"));
worker.log("task log archive was rotated".to_string());
} else {
worker.log(format!("task log archive was not rotated"));
worker.log("task log archive was not rotated".to_string());
}
let max_size = 32 * 1024 * 1024 - 1;
@ -603,18 +601,18 @@ async fn schedule_task_log_rotate() {
if logrotate.rotate(max_size, None, Some(max_files))? {
println!("rotated access log, telling daemons to re-open log file");
proxmox_backup::tools::runtime::block_on(command_reopen_logfiles())?;
worker.log(format!("API access log was rotated"));
worker.log("API access log was rotated".to_string());
} else {
worker.log(format!("API access log was not rotated"));
worker.log("API access log was not rotated".to_string());
}
let mut logrotate = LogRotate::new(buildcfg::API_AUTH_LOG_FN, true)
.ok_or_else(|| format_err!("could not get API auth log file names"))?;
if logrotate.rotate(max_size, None, Some(max_files))? {
worker.log(format!("API authentication log was rotated"));
worker.log("API authentication log was rotated".to_string());
} else {
worker.log(format!("API authentication log was not rotated"));
worker.log("API authentication log was not rotated".to_string());
}
Ok(())
@ -751,7 +749,7 @@ async fn generate_host_stats(save: bool) {
match datastore::config() {
Ok((config, _)) => {
let datastore_list: Vec<datastore::DataStoreConfig> =
config.convert_to_typed_array("datastore").unwrap_or(Vec::new());
config.convert_to_typed_array("datastore").unwrap_or_default();
for config in datastore_list {

View File

@ -601,16 +601,14 @@ fn debug_scan(param: Value) -> Result<(), Error> {
Ok(header) => {
if header.magic != PROXMOX_BACKUP_CONTENT_HEADER_MAGIC_1_0 {
println!("got MediaContentHeader with wrong magic: {:?}", header.magic);
} else if let Some(name) = PROXMOX_BACKUP_CONTENT_NAME.get(&header.content_magic) {
println!("got content header: {}", name);
println!(" uuid: {}", header.content_uuid());
println!(" ctime: {}", strftime_local("%c", header.ctime)?);
println!(" hsize: {}", HumanByte::from(header.size as usize));
println!(" part: {}", header.part_number);
} else {
if let Some(name) = PROXMOX_BACKUP_CONTENT_NAME.get(&header.content_magic) {
println!("got content header: {}", name);
println!(" uuid: {}", header.content_uuid());
println!(" ctime: {}", strftime_local("%c", header.ctime)?);
println!(" hsize: {}", HumanByte::from(header.size as usize));
println!(" part: {}", header.part_number);
} else {
println!("got unknown content header: {:?}", header.content_magic);
}
println!("got unknown content header: {:?}", header.content_magic);
}
}
Err(err) => {

View File

@ -293,7 +293,7 @@ fn test_crypt_speed(
let speed = (bytes as f64)/start_time.elapsed().as_secs_f64();
benchmark_result.sha256.speed = Some(speed);
eprintln!("SHA256 speed: {:.2} MB/s", speed/1_000_000_.0);
eprintln!("SHA256 speed: {:.2} MB/s", speed/1_000_000.0);
let start_time = std::time::Instant::now();
@ -308,7 +308,7 @@ fn test_crypt_speed(
let speed = (bytes as f64)/start_time.elapsed().as_secs_f64();
benchmark_result.compress.speed = Some(speed);
eprintln!("Compression speed: {:.2} MB/s", speed/1_000_000_.0);
eprintln!("Compression speed: {:.2} MB/s", speed/1_000_000.0);
let start_time = std::time::Instant::now();
@ -328,7 +328,7 @@ fn test_crypt_speed(
let speed = (bytes as f64)/start_time.elapsed().as_secs_f64();
benchmark_result.decompress.speed = Some(speed);
eprintln!("Decompress speed: {:.2} MB/s", speed/1_000_000_.0);
eprintln!("Decompress speed: {:.2} MB/s", speed/1_000_000.0);
let start_time = std::time::Instant::now();
@ -343,7 +343,7 @@ fn test_crypt_speed(
let speed = (bytes as f64)/start_time.elapsed().as_secs_f64();
benchmark_result.aes256_gcm.speed = Some(speed);
eprintln!("AES256/GCM speed: {:.2} MB/s", speed/1_000_000_.0);
eprintln!("AES256/GCM speed: {:.2} MB/s", speed/1_000_000.0);
let start_time = std::time::Instant::now();
@ -361,7 +361,7 @@ fn test_crypt_speed(
let speed = (bytes as f64)/start_time.elapsed().as_secs_f64();
benchmark_result.verify.speed = Some(speed);
eprintln!("Verify speed: {:.2} MB/s", speed/1_000_000_.0);
eprintln!("Verify speed: {:.2} MB/s", speed/1_000_000.0);
Ok(())
}

View File

@ -189,12 +189,12 @@ async fn mount_do(param: Value, pipe: Option<Fd>) -> Result<Value, Error> {
};
let server_archive_name = if archive_name.ends_with(".pxar") {
if let None = target {
if target.is_none() {
bail!("use the 'mount' command to mount pxar archives");
}
format!("{}.didx", archive_name)
} else if archive_name.ends_with(".img") {
if let Some(_) = target {
if target.is_some() {
bail!("use the 'map' command to map drive images");
}
format!("{}.fidx", archive_name)

View File

@ -239,7 +239,7 @@ async fn get_status(
}
let text = value.as_str().unwrap().to_string();
if text.is_empty() {
return Ok(String::from("--FULL--"));
Ok(String::from("--FULL--"))
} else {
Ok(text)
}

View File

@ -56,7 +56,7 @@ fn get_tape_handle(param: &Value) -> Result<LinuxTapeHandle, Error> {
let file = unsafe { File::from_raw_fd(fd) };
check_tape_is_linux_tape_device(&file)?;
LinuxTapeHandle::new(file)
} else if let Some(name) = std::env::var("PROXMOX_TAPE_DRIVE").ok() {
} else if let Ok(name) = std::env::var("PROXMOX_TAPE_DRIVE") {
let (config, _digest) = config::drive::config()?;
let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
eprintln!("using device {}", drive.path);
@ -292,13 +292,11 @@ fn main() -> Result<(), Error> {
bail!("this program needs to be run with setuid root");
}
if !running_uid.is_root() {
if running_uid != backup_uid || running_gid != backup_gid {
bail!(
"Not running as backup user or group (got uid {} gid {})",
running_uid, running_gid,
);
}
if !running_uid.is_root() && (running_uid != backup_uid || running_gid != backup_gid) {
bail!(
"Not running as backup user or group (got uid {} gid {})",
running_uid, running_gid,
);
}
let cmd_def = CliCommandMap::new()

View File

@ -74,12 +74,14 @@ pub const ROLE_ADMIN: u64 = std::u64::MAX;
pub const ROLE_NO_ACCESS: u64 = 0;
#[rustfmt::skip]
#[allow(clippy::identity_op)]
/// Audit can view configuration and status information, but not modify it.
pub const ROLE_AUDIT: u64 = 0
| PRIV_SYS_AUDIT
| PRIV_DATASTORE_AUDIT;
#[rustfmt::skip]
#[allow(clippy::identity_op)]
/// Datastore.Admin can do anything on the datastore.
pub const ROLE_DATASTORE_ADMIN: u64 = 0
| PRIV_DATASTORE_AUDIT
@ -90,6 +92,7 @@ pub const ROLE_DATASTORE_ADMIN: u64 = 0
| PRIV_DATASTORE_PRUNE;
#[rustfmt::skip]
#[allow(clippy::identity_op)]
/// Datastore.Reader can read/verify datastore content and do restore
pub const ROLE_DATASTORE_READER: u64 = 0
| PRIV_DATASTORE_AUDIT
@ -97,27 +100,32 @@ pub const ROLE_DATASTORE_READER: u64 = 0
| PRIV_DATASTORE_READ;
#[rustfmt::skip]
#[allow(clippy::identity_op)]
/// Datastore.Backup can do backup and restore, but no prune.
pub const ROLE_DATASTORE_BACKUP: u64 = 0
| PRIV_DATASTORE_BACKUP;
#[rustfmt::skip]
#[allow(clippy::identity_op)]
/// Datastore.PowerUser can do backup, restore, and prune.
pub const ROLE_DATASTORE_POWERUSER: u64 = 0
| PRIV_DATASTORE_PRUNE
| PRIV_DATASTORE_BACKUP;
#[rustfmt::skip]
#[allow(clippy::identity_op)]
/// Datastore.Audit can audit the datastore.
pub const ROLE_DATASTORE_AUDIT: u64 = 0
| PRIV_DATASTORE_AUDIT;
#[rustfmt::skip]
#[allow(clippy::identity_op)]
/// Remote.Audit can audit the remote
pub const ROLE_REMOTE_AUDIT: u64 = 0
| PRIV_REMOTE_AUDIT;
#[rustfmt::skip]
#[allow(clippy::identity_op)]
/// Remote.Admin can do anything on the remote.
pub const ROLE_REMOTE_ADMIN: u64 = 0
| PRIV_REMOTE_AUDIT
@ -125,6 +133,7 @@ pub const ROLE_REMOTE_ADMIN: u64 = 0
| PRIV_REMOTE_READ;
#[rustfmt::skip]
#[allow(clippy::identity_op)]
/// Remote.SyncOperator can do read and prune on the remote.
pub const ROLE_REMOTE_SYNC_OPERATOR: u64 = 0
| PRIV_REMOTE_AUDIT
@ -363,6 +372,7 @@ impl AclTreeNode {
fn extract_group_roles(&self, _user: &Userid, leaf: bool) -> HashMap<String, bool> {
let mut map = HashMap::new();
#[allow(clippy::for_kv_map)]
for (_group, roles) in &self.groups {
let is_member = false; // fixme: check if user is member of the group
if !is_member {
@ -402,7 +412,7 @@ impl AclTreeNode {
}
fn insert_group_role(&mut self, group: String, role: String, propagate: bool) {
let map = self.groups.entry(group).or_insert_with(|| HashMap::new());
let map = self.groups.entry(group).or_insert_with(HashMap::new);
if role == ROLE_NAME_NO_ACCESS {
map.clear();
map.insert(role, propagate);
@ -413,7 +423,7 @@ impl AclTreeNode {
}
fn insert_user_role(&mut self, auth_id: Authid, role: String, propagate: bool) {
let map = self.users.entry(auth_id).or_insert_with(|| HashMap::new());
let map = self.users.entry(auth_id).or_insert_with(HashMap::new);
if role == ROLE_NAME_NO_ACCESS {
map.clear();
map.insert(role, propagate);
@ -435,7 +445,7 @@ impl AclTree {
/// Iterates over the tree looking for a node matching `path`.
pub fn find_node(&mut self, path: &str) -> Option<&mut AclTreeNode> {
let path = split_acl_path(path);
return self.get_node(&path);
self.get_node(&path)
}
fn get_node(&mut self, path: &[&str]) -> Option<&mut AclTreeNode> {
@ -455,7 +465,7 @@ impl AclTree {
node = node
.children
.entry(String::from(*comp))
.or_insert_with(|| AclTreeNode::new());
.or_insert_with(AclTreeNode::new);
}
node
}
@ -521,12 +531,12 @@ impl AclTree {
if *propagate {
role_ug_map1
.entry(role)
.or_insert_with(|| BTreeSet::new())
.or_insert_with(BTreeSet::new)
.insert(auth_id);
} else {
role_ug_map0
.entry(role)
.or_insert_with(|| BTreeSet::new())
.or_insert_with(BTreeSet::new)
.insert(auth_id);
}
}
@ -538,12 +548,12 @@ impl AclTree {
if *propagate {
role_ug_map1
.entry(role)
.or_insert_with(|| BTreeSet::new())
.or_insert_with(BTreeSet::new)
.insert(group);
} else {
role_ug_map0
.entry(role)
.or_insert_with(|| BTreeSet::new())
.or_insert_with(BTreeSet::new)
.insert(group);
}
}
@ -563,7 +573,7 @@ impl AclTree {
});
result_map
.entry(item_list)
.or_insert_with(|| BTreeSet::new())
.or_insert_with(BTreeSet::new)
.insert(item.to_string());
}
result_map
@ -651,8 +661,7 @@ impl AclTree {
if !ROLE_NAMES.contains_key(role) {
bail!("unknown role '{}'", role);
}
if user_or_group.starts_with('@') {
let group = &user_or_group[1..];
if let Some(group) = user_or_group.strip_prefix('@') {
node.insert_group_role(group.to_string(), role.to_string(), propagate);
} else {
node.insert_user_role(user_or_group.parse()?, role.to_string(), propagate);

View File

@ -98,7 +98,7 @@ impl CachedUserInfo {
}
}
return true;
true
}
pub fn check_privs(

View File

@ -135,8 +135,8 @@ pub const DATASTORE_CFG_LOCKFILE: &str = "/etc/proxmox-backup/.datastore.lck";
pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
let content = proxmox::tools::fs::file_read_optional_string(DATASTORE_CFG_FILENAME)?;
let content = content.unwrap_or(String::from(""));
let content = proxmox::tools::fs::file_read_optional_string(DATASTORE_CFG_FILENAME)?
.unwrap_or_else(|| "".to_string());
let digest = openssl::sha::sha256(content.as_bytes());
let data = CONFIG.parse(DATASTORE_CFG_FILENAME, &content)?;

View File

@ -68,8 +68,8 @@ pub fn lock() -> Result<std::fs::File, Error> {
pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
let content = proxmox::tools::fs::file_read_optional_string(DRIVE_CFG_FILENAME)?;
let content = content.unwrap_or(String::from(""));
let content = proxmox::tools::fs::file_read_optional_string(DRIVE_CFG_FILENAME)?
.unwrap_or_else(|| "".to_string());
let digest = openssl::sha::sha256(content.as_bytes());
let data = CONFIG.parse(DRIVE_CFG_FILENAME, &content)?;

View File

@ -43,8 +43,8 @@ fn init() -> SectionConfig {
config
}
pub const MEDIA_POOL_CFG_FILENAME: &'static str = "/etc/proxmox-backup/media-pool.cfg";
pub const MEDIA_POOL_CFG_LOCKFILE: &'static str = "/etc/proxmox-backup/.media-pool.lck";
pub const MEDIA_POOL_CFG_FILENAME: &str = "/etc/proxmox-backup/media-pool.cfg";
pub const MEDIA_POOL_CFG_LOCKFILE: &str = "/etc/proxmox-backup/.media-pool.lck";
pub fn lock() -> Result<std::fs::File, Error> {
open_file_locked(MEDIA_POOL_CFG_LOCKFILE, std::time::Duration::new(10, 0), true)
@ -52,8 +52,8 @@ pub fn lock() -> Result<std::fs::File, Error> {
pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
let content = proxmox::tools::fs::file_read_optional_string(MEDIA_POOL_CFG_FILENAME)?;
let content = content.unwrap_or(String::from(""));
let content = proxmox::tools::fs::file_read_optional_string(MEDIA_POOL_CFG_FILENAME)?
.unwrap_or_else(|| "".to_string());
let digest = openssl::sha::sha256(content.as_bytes());
let data = CONFIG.parse(MEDIA_POOL_CFG_FILENAME, &content)?;

View File

@ -386,9 +386,9 @@ impl NetworkConfig {
pub fn check_mtu(&self, parent_name: &str, child_name: &str) -> Result<(), Error> {
let parent = self.interfaces.get(parent_name)
.ok_or(format_err!("check_mtu - missing parent interface '{}'", parent_name))?;
.ok_or_else(|| format_err!("check_mtu - missing parent interface '{}'", parent_name))?;
let child = self.interfaces.get(child_name)
.ok_or(format_err!("check_mtu - missing child interface '{}'", child_name))?;
.ok_or_else(|| format_err!("check_mtu - missing child interface '{}'", child_name))?;
let child_mtu = match child.mtu {
Some(mtu) => mtu,
@ -515,7 +515,7 @@ pub fn config() -> Result<(NetworkConfig, [u8;32]), Error> {
Some(content) => content,
None => {
let content = proxmox::tools::fs::file_get_optional_contents(NETWORK_INTERFACES_FILENAME)?;
content.unwrap_or(Vec::new())
content.unwrap_or_default()
}
};
@ -577,8 +577,8 @@ pub fn complete_port_list(arg: &str, _param: &HashMap<String, String>) -> Vec<St
Err(_) => return vec![],
};
let arg = arg.clone().trim();
let prefix = if let Some(idx) = arg.rfind(",") { &arg[..idx+1] } else { "" };
let arg = arg.trim();
let prefix = if let Some(idx) = arg.rfind(',') { &arg[..idx+1] } else { "" };
ports.iter().map(|port| format!("{}{}", prefix, port)).collect()
}

View File

@ -51,6 +51,7 @@ pub static IPV4_REVERSE_MASK: &[&str] = &[
lazy_static! {
pub static ref IPV4_MASK_HASH_LOCALNET: HashMap<&'static str, u8> = {
let mut map = HashMap::new();
#[allow(clippy::needless_range_loop)]
for i in 8..32 {
map.insert(IPV4_REVERSE_MASK[i], i as u8);
}
@ -61,22 +62,23 @@ lazy_static! {
pub fn parse_cidr(cidr: &str) -> Result<(String, u8, bool), Error> {
let (address, mask, is_v6) = parse_address_or_cidr(cidr)?;
if let Some(mask) = mask {
return Ok((address, mask, is_v6));
Ok((address, mask, is_v6))
} else {
bail!("missing netmask in '{}'", cidr);
}
}
pub fn check_netmask(mask: u8, is_v6: bool) -> Result<(), Error> {
if is_v6 {
if !(mask >= 1 && mask <= 128) {
bail!("IPv6 mask '{}' is out of range (1..128).", mask);
}
let (ver, min, max) = if is_v6 {
("IPv6", 1, 128)
} else {
if !(mask > 0 && mask <= 32) {
bail!("IPv4 mask '{}' is out of range (1..32).", mask);
}
("IPv4", 1, 32)
};
if !(mask >= min && mask <= max) {
bail!("{} mask '{}' is out of range ({}..{}).", ver, mask, min, max);
}
Ok(())
}
@ -97,18 +99,18 @@ pub fn parse_address_or_cidr(cidr: &str) -> Result<(String, Option<u8>, bool), E
if let Some(mask) = caps.get(2) {
let mask = u8::from_str_radix(mask.as_str(), 10)?;
check_netmask(mask, false)?;
return Ok((address.to_string(), Some(mask), false));
Ok((address.to_string(), Some(mask), false))
} else {
return Ok((address.to_string(), None, false));
Ok((address.to_string(), None, false))
}
} else if let Some(caps) = CIDR_V6_REGEX.captures(&cidr) {
let address = &caps[1];
if let Some(mask) = caps.get(2) {
let mask = u8::from_str_radix(mask.as_str(), 10)?;
check_netmask(mask, true)?;
return Ok((address.to_string(), Some(mask), true));
Ok((address.to_string(), Some(mask), true))
} else {
return Ok((address.to_string(), None, true));
Ok((address.to_string(), None, true))
}
} else {
bail!("invalid address/mask '{}'", cidr);

View File

@ -74,9 +74,9 @@ impl <R: BufRead> Lexer<R> {
}
fn split_line(line: &str) -> VecDeque<(Token, String)> {
if line.starts_with("#") {
if let Some(comment) = line.strip_prefix('#') {
let mut res = VecDeque::new();
res.push_back((Token::Comment, line[1..].trim().to_string()));
res.push_back((Token::Comment, comment.trim().to_string()));
return res;
}
let mut list: VecDeque<(Token, String)> = line.split_ascii_whitespace().map(|text| {
@ -114,14 +114,14 @@ impl <R: BufRead> Iterator for Lexer<R> {
Some(ref mut cur_line) => {
if cur_line.is_empty() {
self.cur_line = None;
return Some(Ok((Token::Newline, String::from("\n"))));
Some(Ok((Token::Newline, String::from("\n"))))
} else {
let (token, text) = cur_line.pop_front().unwrap();
return Some(Ok((token, text)));
Some(Ok((token, text)))
}
}
None => {
return None;
None
}
}
}

View File

@ -29,7 +29,7 @@ impl <R: BufRead> NetworkParser<R> {
bail!("input error - {}", err);
}
Some(Ok((token, _))) => {
return Ok(*token);
Ok(*token)
}
None => {
bail!("got unexpected end of stream (inside peek)");
@ -44,7 +44,7 @@ impl <R: BufRead> NetworkParser<R> {
}
Some(Ok((token, text))) => {
if token == Token::Newline { self.line_nr += 1; }
return Ok((token, text));
Ok((token, text))
}
None => {
bail!("got unexpected end of stream (inside peek)");
@ -215,12 +215,12 @@ impl <R: BufRead> NetworkParser<R> {
Token::Comment => {
let comment = self.eat(Token::Comment)?;
if !address_family_v4 && address_family_v6 {
let mut comments = interface.comments6.take().unwrap_or(String::new());
let mut comments = interface.comments6.take().unwrap_or_default();
if !comments.is_empty() { comments.push('\n'); }
comments.push_str(&comment);
interface.comments6 = Some(comments);
} else {
let mut comments = interface.comments.take().unwrap_or(String::new());
let mut comments = interface.comments.take().unwrap_or_default();
if !comments.is_empty() { comments.push('\n'); }
comments.push_str(&comment);
interface.comments = Some(comments);

View File

@ -92,8 +92,8 @@ pub const REMOTE_CFG_LOCKFILE: &str = "/etc/proxmox-backup/.remote.lck";
pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
let content = proxmox::tools::fs::file_read_optional_string(REMOTE_CFG_FILENAME)?;
let content = content.unwrap_or(String::from(""));
let content = proxmox::tools::fs::file_read_optional_string(REMOTE_CFG_FILENAME)?
.unwrap_or_else(|| "".to_string());
let digest = openssl::sha::sha256(content.as_bytes());
let data = CONFIG.parse(REMOTE_CFG_FILENAME, &content)?;

View File

@ -79,7 +79,7 @@ impl From<&SyncJobStatus> for SyncJobConfig {
owner: job_status.owner.clone(),
remote: job_status.remote.clone(),
remote_store: job_status.remote_store.clone(),
remove_vanished: job_status.remove_vanished.clone(),
remove_vanished: job_status.remove_vanished,
comment: job_status.comment.clone(),
schedule: job_status.schedule.clone(),
}
@ -183,8 +183,8 @@ pub const SYNC_CFG_LOCKFILE: &str = "/etc/proxmox-backup/.sync.lck";
pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
let content = proxmox::tools::fs::file_read_optional_string(SYNC_CFG_FILENAME)?;
let content = content.unwrap_or(String::from(""));
let content = proxmox::tools::fs::file_read_optional_string(SYNC_CFG_FILENAME)?
.unwrap_or_else(|| "".to_string());
let digest = openssl::sha::sha256(content.as_bytes());
let data = CONFIG.parse(SYNC_CFG_FILENAME, &content)?;

View File

@ -53,7 +53,7 @@ pub struct EncryptionKeyInfo {
}
pub fn compute_tape_key_fingerprint(key: &[u8; 32]) -> Result<Fingerprint, Error> {
let crypt_config = CryptConfig::new(key.clone())?;
let crypt_config = CryptConfig::new(*key)?;
Ok(crypt_config.fingerprint())
}
@ -193,7 +193,7 @@ pub fn insert_key(key: [u8;32], key_config: KeyConfig, force: bool) -> Result<()
};
if !force {
if let Some(_) = config_map.get(&fingerprint) {
if config_map.get(&fingerprint).is_some() {
bail!("encryption key '{}' already exists.", fingerprint);
}
}

View File

@ -1380,14 +1380,14 @@ impl std::str::FromStr for TfaResponse {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
Ok(if s.starts_with("totp:") {
TfaResponse::Totp(s[5..].to_string())
} else if s.starts_with("u2f:") {
TfaResponse::U2f(serde_json::from_str(&s[4..])?)
} else if s.starts_with("webauthn:") {
TfaResponse::Webauthn(serde_json::from_str(&s[9..])?)
} else if s.starts_with("recovery:") {
TfaResponse::Recovery(s[9..].to_string())
Ok(if let Some(totp) = s.strip_prefix("totp:") {
TfaResponse::Totp(totp.to_string())
} else if let Some(u2f) = s.strip_prefix("u2f:") {
TfaResponse::U2f(serde_json::from_str(u2f)?)
} else if let Some(webauthn) = s.strip_prefix("webauthn:") {
TfaResponse::Webauthn(serde_json::from_str(webauthn)?)
} else if let Some(recovery) = s.strip_prefix("recovery:") {
TfaResponse::Recovery(recovery.to_string())
} else {
bail!("invalid tfa response");
})

View File

@ -157,8 +157,8 @@ pub const USER_CFG_LOCKFILE: &str = "/etc/proxmox-backup/.user.lck";
pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
let content = proxmox::tools::fs::file_read_optional_string(USER_CFG_FILENAME)?;
let content = content.unwrap_or(String::from(""));
let content = proxmox::tools::fs::file_read_optional_string(USER_CFG_FILENAME)?
.unwrap_or_else(|| "".to_string());
let digest = openssl::sha::sha256(content.as_bytes());
let mut data = CONFIG.parse(USER_CFG_FILENAME, &content)?;

View File

@ -40,8 +40,7 @@ fn detect_fs_type(fd: RawFd) -> Result<i64, Error> {
pub fn is_virtual_file_system(magic: i64) -> bool {
use proxmox::sys::linux::magic::*;
match magic {
BINFMTFS_MAGIC |
matches!(magic, BINFMTFS_MAGIC |
CGROUP2_SUPER_MAGIC |
CGROUP_SUPER_MAGIC |
CONFIGFS_MAGIC |
@ -58,9 +57,7 @@ pub fn is_virtual_file_system(magic: i64) -> bool {
SECURITYFS_MAGIC |
SELINUX_MAGIC |
SMACK_MAGIC |
SYSFS_MAGIC => true,
_ => false
}
SYSFS_MAGIC)
}
#[derive(Debug)]

View File

@ -228,7 +228,7 @@ impl Extractor {
allow_existing_dirs,
feature_flags,
current_path: Arc::new(Mutex::new(OsString::new())),
on_error: Box::new(|err| Err(err)),
on_error: Box::new(Err),
}
}

View File

@ -480,11 +480,11 @@ impl SessionImpl {
Ok(())
}
async fn lookup<'a>(
&'a self,
async fn lookup(
&'_ self,
parent: u64,
file_name: &OsStr,
) -> Result<(EntryParam, LookupRef<'a>), Error> {
) -> Result<(EntryParam, LookupRef<'_>), Error> {
let dir = self.open_dir(parent).await?;
let entry = match { dir }.lookup(file_name).await? {
@ -519,10 +519,10 @@ impl SessionImpl {
to_stat(inode, &entry)
}
async fn readdirplus<'a>(
&'a self,
async fn readdirplus(
&'_ self,
request: &mut requests::ReaddirPlus,
) -> Result<Vec<LookupRef<'a>>, Error> {
) -> Result<Vec<LookupRef<'_>>, Error> {
let mut lookups = Vec::new();
let offset = usize::try_from(request.offset)
.map_err(|_| io_format_err!("directory offset out of range"))?;

View File

@ -345,10 +345,7 @@ fn apply_quota_project_id(flags: Flags, fd: RawFd, metadata: &Metadata) -> Resul
}
pub(crate) fn errno_is_unsupported(errno: Errno) -> bool {
match errno {
Errno::ENOTTY | Errno::ENOSYS | Errno::EBADF | Errno::EOPNOTSUPP | Errno::EINVAL => true,
_ => false,
}
matches!(errno, Errno::ENOTTY | Errno::ENOSYS | Errno::EBADF | Errno::EOPNOTSUPP | Errno::EINVAL)
}
fn apply_chattr(fd: RawFd, chattr: libc::c_long, mask: libc::c_long) -> Result<(), Error> {

View File

@ -128,25 +128,20 @@ impl RRA {
// derive counter value
if self.flags.intersects(RRAFlags::DST_DERIVE | RRAFlags::DST_COUNTER) {
let time_diff = time - self.last_update;
let is_counter = self.flags.contains(RRAFlags::DST_COUNTER);
let diff = if self.counter_value.is_nan() {
0.0
} else if is_counter && value < 0.0 {
eprintln!("rrdb update failed - got negative value for counter");
return;
} else if is_counter && value < self.counter_value {
// Note: We do not try automatic overflow corrections
self.counter_value = value;
eprintln!("rrdb update failed - conter overflow/reset detected");
return;
} else {
if self.flags.contains(RRAFlags::DST_COUNTER) { // check for overflow
if value < 0.0 {
eprintln!("rrdb update failed - got negative value for counter");
return;
}
// Note: We do not try automatic overflow corrections
if value < self.counter_value { // overflow or counter reset
self.counter_value = value;
eprintln!("rrdb update failed - conter overflow/reset detected");
return;
} else {
value - self.counter_value
}
} else {
value - self.counter_value
}
value - self.counter_value
};
self.counter_value = value;
value = diff/time_diff;

View File

@ -127,13 +127,13 @@ pub async fn send_command<P>(
if rx.read_line(&mut data).await? == 0 {
bail!("no response");
}
if data.starts_with("OK: ") {
match data[4..].parse::<Value>() {
if let Some(res) = data.strip_prefix("OK: ") {
match res.parse::<Value>() {
Ok(v) => Ok(v),
Err(err) => bail!("unable to parse json response - {}", err),
}
} else if data.starts_with("ERROR: ") {
bail!("{}", &data[7..]);
} else if let Some(err) = data.strip_prefix("ERROR: ") {
bail!("{}", err);
} else {
bail!("unable to parse response: {}", data);
}

View File

@ -57,9 +57,9 @@ impl ApiConfig {
prefix.push_str(components[0]);
if let Some(subdir) = self.aliases.get(&prefix) {
filename.push(subdir);
for i in 1..comp_len { filename.push(components[i]) }
components.iter().skip(1).for_each(|comp| filename.push(comp));
} else {
for i in 0..comp_len { filename.push(components[i]) }
components.iter().for_each(|comp| filename.push(comp));
}
}
filename

View File

@ -376,7 +376,7 @@ fn get_server_url() -> (String, usize) {
}
pub fn send_updates_available(
updates: &Vec<&APTUpdateInfo>,
updates: &[&APTUpdateInfo],
) -> Result<(), Error> {
// update mails always go to the root@pam configured email..
if let Some(email) = lookup_user_email(Userid::root_userid()) {
@ -403,7 +403,7 @@ fn lookup_user_email(userid: &Userid) -> Option<String> {
if let Ok(user_config) = user::cached_config() {
if let Ok(user) = user_config.lookup::<User>("user", userid.as_str()) {
return user.email.clone();
return user.email;
}
}
@ -434,7 +434,7 @@ pub fn lookup_datastore_notify_settings(
None => lookup_user_email(Userid::root_userid()),
};
let notify_str = config.notify.unwrap_or(String::new());
let notify_str = config.notify.unwrap_or_default();
if let Ok(value) = parse_property_string(&notify_str, &DatastoreNotify::API_SCHEMA) {
if let Ok(notify) = serde_json::from_value(value) {
@ -456,7 +456,7 @@ fn handlebars_humam_bytes_helper(
) -> HelperResult {
let param = h.param(0).map(|v| v.value().as_u64())
.flatten()
.ok_or(RenderError::new("human-bytes: param not found"))?;
.ok_or_else(|| RenderError::new("human-bytes: param not found"))?;
out.write(&HumanByte::from(param).to_string())?;
@ -472,10 +472,10 @@ fn handlebars_relative_percentage_helper(
) -> HelperResult {
let param0 = h.param(0).map(|v| v.value().as_f64())
.flatten()
.ok_or(RenderError::new("relative-percentage: param0 not found"))?;
.ok_or_else(|| RenderError::new("relative-percentage: param0 not found"))?;
let param1 = h.param(1).map(|v| v.value().as_f64())
.flatten()
.ok_or(RenderError::new("relative-percentage: param1 not found"))?;
.ok_or_else(|| RenderError::new("relative-percentage: param1 not found"))?;
if param1 == 0.0 {
out.write("-")?;

View File

@ -48,6 +48,6 @@ impl RpcEnvironment for RestEnvironment {
}
fn get_client_ip(&self) -> Option<std::net::SocketAddr> {
self.client_ip.clone()
self.client_ip
}
}

View File

@ -39,13 +39,12 @@ pub fn do_garbage_collection_job(
let status = worker.create_state(&result);
match job.finish(status) {
Err(err) => eprintln!(
if let Err(err) = job.finish(status) {
eprintln!(
"could not finish job state for {}: {}",
job.jobtype().to_string(),
err
),
Ok(_) => (),
);
}
if let Some(email) = email {

View File

@ -97,7 +97,7 @@ impl <E: RpcEnvironment + Clone> tower_service::Service<Request<Body>> for H2Ser
let method = req.method().clone();
let worker = self.worker.clone();
std::pin::Pin::from(self.handle_request(req))
self.handle_request(req)
.map(move |result| match result {
Ok(res) => {
Self::log_response(worker, method, &path, &res);

View File

@ -207,11 +207,8 @@ impl Job {
/// Start the job and update the statefile accordingly
/// Fails if the job was already started
pub fn start(&mut self, upid: &str) -> Result<(), Error> {
match self.state {
JobState::Started { .. } => {
bail!("cannot start job that is started!");
}
_ => {}
if let JobState::Started { .. } = self.state {
bail!("cannot start job that is started!");
}
self.state = JobState::Started {

View File

@ -39,7 +39,7 @@ fn function_calls() -> Vec<(&'static str, fn() -> String)> {
};
let mut list = Vec::new();
for (store, _) in &config.sections {
for store in config.sections.keys() {
list.push(store.as_str());
}
list.join(", ")

View File

@ -147,7 +147,7 @@ fn log_response(
let now = proxmox::tools::time::epoch_i64();
// time format which apache/nginx use (by default), copied from pve-http-server
let datetime = proxmox::tools::time::strftime_local("%d/%m/%Y:%H:%M:%S %z", now)
.unwrap_or("-".into());
.unwrap_or_else(|_| "-".to_string());
logfile
.lock()
@ -161,7 +161,7 @@ fn log_response(
path,
status.as_str(),
resp.body().size_hint().lower(),
user_agent.unwrap_or("-".into()),
user_agent.unwrap_or_else(|| "-".to_string()),
));
}
}
@ -517,7 +517,7 @@ async fn chuncked_static_file_download(filename: PathBuf) -> Result<Response<Bod
.map_err(|err| http_err!(BAD_REQUEST, "File open failed: {}", err))?;
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
.map_ok(|bytes| hyper::body::Bytes::from(bytes.freeze()));
.map_ok(|bytes| bytes.freeze());
let body = Body::wrap_stream(payload);
// fixme: set other headers ?

View File

@ -68,8 +68,8 @@ impl std::str::FromStr for ApiTicket {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
if s.starts_with("!tfa!") {
Ok(ApiTicket::Partial(serde_json::from_str(&s[5..])?))
if let Some(tfa_ticket) = s.strip_prefix("!tfa!") {
Ok(ApiTicket::Partial(serde_json::from_str(tfa_ticket)?))
} else {
Ok(ApiTicket::Full(s.parse()?))
}

View File

@ -23,7 +23,7 @@ pub fn do_verification_job(
let datastore = DataStore::lookup_datastore(&verification_job.store)?;
let outdated_after = verification_job.outdated_after.clone();
let outdated_after = verification_job.outdated_after;
let ignore_verified_snapshots = verification_job.ignore_verified.unwrap_or(true);
let filter = move |manifest: &BackupManifest| {
@ -33,7 +33,7 @@ pub fn do_verification_job(
let raw_verify_state = manifest.unprotected["verify_state"].clone();
match serde_json::from_value::<SnapshotVerifyState>(raw_verify_state) {
Err(_) => return true, // no last verification, always include
Err(_) => true, // no last verification, always include
Ok(last_verify) => {
match outdated_after {
None => false, // never re-verify if ignored and no max age
@ -83,13 +83,12 @@ pub fn do_verification_job(
let status = worker.create_state(&job_result);
match job.finish(status) {
Err(err) => eprintln!(
if let Err(err) = job.finish(status) {
eprintln!(
"could not finish job state for {}: {}",
job.jobtype().to_string(),
err
),
Ok(_) => (),
);
}
if let Some(email) = email {

View File

@ -48,7 +48,7 @@ pub async fn worker_is_active(upid: &UPID) -> Result<bool, Error> {
return Ok(WORKER_TASK_LIST.lock().unwrap().contains_key(&upid.task_id));
}
if !procfs::check_process_running_pstart(upid.pid, upid.pstart).is_some() {
if procfs::check_process_running_pstart(upid.pid, upid.pstart).is_none() {
return Ok(false);
}
@ -191,7 +191,7 @@ pub fn upid_read_status(upid: &UPID) -> Result<TaskState, Error> {
file.read_to_end(&mut data)?;
// task logs should end with newline, we do not want it here
if data.len() > 0 && data[data.len()-1] == b'\n' {
if !data.is_empty() && data[data.len()-1] == b'\n' {
data.pop();
}
@ -267,11 +267,11 @@ impl TaskState {
Ok(TaskState::Unknown { endtime })
} else if s == "OK" {
Ok(TaskState::OK { endtime })
} else if s.starts_with("WARNINGS: ") {
let count: u64 = s[10..].parse()?;
} else if let Some(warnings) = s.strip_prefix("WARNINGS: ") {
let count: u64 = warnings.parse()?;
Ok(TaskState::Warning{ count, endtime })
} else if s.len() > 0 {
let message = if s.starts_with("ERROR: ") { &s[7..] } else { s }.to_string();
} else if !s.is_empty() {
let message = if let Some(err) = s.strip_prefix("ERROR: ") { err } else { s }.to_string();
Ok(TaskState::Error{ message, endtime })
} else {
bail!("unable to parse Task Status '{}'", s);
@ -330,7 +330,7 @@ pub fn rotate_task_log_archive(size_threshold: u64, compress: bool, max_files: O
let _lock = lock_task_list_files(true)?;
let mut logrotate = LogRotate::new(PROXMOX_BACKUP_ARCHIVE_TASK_FN, compress)
.ok_or(format_err!("could not get archive file names"))?;
.ok_or_else(|| format_err!("could not get archive file names"))?;
logrotate.rotate(size_threshold, None, max_files)
}
@ -362,8 +362,7 @@ fn update_active_workers(new_upid: Option<&UPID>) -> Result<(), Error> {
if !worker_is_active_local(&info.upid) {
// println!("Detected stopped task '{}'", &info.upid_str);
let now = proxmox::tools::time::epoch_i64();
let status = upid_read_status(&info.upid)
.unwrap_or_else(|_| TaskState::Unknown { endtime: now });
let status = upid_read_status(&info.upid).unwrap_or(TaskState::Unknown { endtime: now });
finish_list.push(TaskListInfo {
upid: info.upid,
upid_str: info.upid_str,

View File

@ -187,11 +187,9 @@ pub trait MediaChange {
if let ElementStatus::Empty = element_status {
to = Some(i as u64 + 1);
}
} else {
if let ElementStatus::VolumeTag(ref tag) = element_status {
if tag == label_text {
from = Some(i as u64 + 1);
}
} else if let ElementStatus::VolumeTag(ref tag) = element_status {
if tag == label_text {
from = Some(i as u64 + 1);
}
}
}

View File

@ -58,13 +58,12 @@ fn parse_drive_status(i: &str) -> IResult<&str, DriveStatus> {
let mut loaded_slot = None;
if i.starts_with("Empty") {
return Ok((&i[5..], DriveStatus { loaded_slot, status: ElementStatus::Empty }));
if let Some(empty) = i.strip_suffix("Empty") {
return Ok((empty, DriveStatus { loaded_slot, status: ElementStatus::Empty }));
}
let (mut i, _) = tag("Full (")(i)?;
if i.starts_with("Storage Element ") {
let n = &i[16..];
if let Some(n) = i.strip_prefix("Storage Element ") {
let (n, id) = parse_u64(n)?;
loaded_slot = Some(id);
let (n, _) = tag(" Loaded")(n)?;
@ -76,8 +75,7 @@ fn parse_drive_status(i: &str) -> IResult<&str, DriveStatus> {
let (i, _) = tag(")")(i)?;
if i.starts_with(":VolumeTag = ") {
let i = &i[13..];
if let Some(i) = i.strip_prefix(":VolumeTag = ") {
let (i, tag) = take_while(|c| !(c == ' ' || c == ':' || c == '\n'))(i)?;
let (i, _) = take_while(|c| c != '\n')(i)?; // skip to eol
return Ok((i, DriveStatus { loaded_slot, status: ElementStatus::VolumeTag(tag.to_string()) }));
@ -89,14 +87,11 @@ fn parse_drive_status(i: &str) -> IResult<&str, DriveStatus> {
}
fn parse_slot_status(i: &str) -> IResult<&str, ElementStatus> {
if i.starts_with("Empty") {
return Ok((&i[5..], ElementStatus::Empty));
if let Some(empty) = i.strip_prefix("Empty") {
return Ok((empty, ElementStatus::Empty));
}
if i.starts_with("Full ") {
let mut n = &i[5..];
if n.starts_with(":VolumeTag=") {
n = &n[11..];
if let Some(n) = i.strip_prefix("Full ") {
if let Some(n) = n.strip_prefix(":VolumeTag=") {
let (n, tag) = take_while(|c| !(c == ' ' || c == ':' || c == '\n'))(n)?;
let (n, _) = take_while(|c| c != '\n')(n)?; // skip to eol
return Ok((n, ElementStatus::VolumeTag(tag.to_string())));

View File

@ -62,15 +62,11 @@ impl <'a> ChunkArchiveWriter<'a> {
}
fn write_all(&mut self, data: &[u8]) -> Result<bool, std::io::Error> {
let result = match self.writer {
Some(ref mut writer) => {
let leom = writer.write_all(data)?;
Ok(leom)
}
match self.writer {
Some(ref mut writer) => writer.write_all(data),
None => proxmox::io_bail!(
"detected write after archive finished - internal error"),
};
result
}
}
/// Write chunk into archive.

View File

@ -24,10 +24,7 @@ pub fn has_encryption<F: AsRawFd>(
Ok(data) => data,
Err(_) => return false,
};
match decode_spin_data_encryption_caps(&data) {
Ok(_) => true,
Err(_) => false,
}
decode_spin_data_encryption_caps(&data).is_ok()
}
/// Set or clear encryption key

View File

@ -85,12 +85,12 @@ pub fn linux_tape_changer_list() -> Vec<TapeDeviceInfo> {
let vendor = device.property_value("ID_VENDOR")
.map(std::ffi::OsString::from)
.and_then(|s| if let Ok(s) = s.into_string() { Some(s) } else { None })
.unwrap_or(String::from("unknown"));
.unwrap_or_else(|| String::from("unknown"));
let model = device.property_value("ID_MODEL")
.map(std::ffi::OsString::from)
.and_then(|s| if let Ok(s) = s.into_string() { Some(s) } else { None })
.unwrap_or(String::from("unknown"));
.unwrap_or_else(|| String::from("unknown"));
let dev_path = format!("/dev/tape/by-id/scsi-{}", serial);
@ -166,12 +166,12 @@ pub fn linux_tape_device_list() -> Vec<TapeDeviceInfo> {
let vendor = device.property_value("ID_VENDOR")
.map(std::ffi::OsString::from)
.and_then(|s| if let Ok(s) = s.into_string() { Some(s) } else { None })
.unwrap_or(String::from("unknown"));
.unwrap_or_else(|| String::from("unknown"));
let model = device.property_value("ID_MODEL")
.map(std::ffi::OsString::from)
.and_then(|s| if let Ok(s) = s.into_string() { Some(s) } else { None })
.unwrap_or(String::from("unknown"));
.unwrap_or_else(|| String::from("unknown"));
let dev_path = format!("/dev/tape/by-id/scsi-{}-nst", serial);

View File

@ -98,16 +98,14 @@ impl LinuxTapeDrive {
if drive_status.blocksize == 0 {
// device is variable block size - OK
} else {
if drive_status.blocksize != PROXMOX_TAPE_BLOCK_SIZE as u32 {
eprintln!("device is in fixed block size mode with wrong size ({} bytes)", drive_status.blocksize);
eprintln!("trying to set variable block size mode...");
if handle.set_block_size(0).is_err() {
bail!("set variable block size mod failed - device uses wrong blocksize.");
}
} else {
// device is in fixed block size mode with correct block size
} else if drive_status.blocksize != PROXMOX_TAPE_BLOCK_SIZE as u32 {
eprintln!("device is in fixed block size mode with wrong size ({} bytes)", drive_status.blocksize);
eprintln!("trying to set variable block size mode...");
if handle.set_block_size(0).is_err() {
bail!("set variable block size mod failed - device uses wrong blocksize.");
}
} else {
// device is in fixed block size mode with correct block size
}
// Only root can set driver options, so we cannot
@ -528,7 +526,7 @@ impl TapeDriver for LinuxTapeHandle {
let result: Result<u64, String> = serde_json::from_str(&output)?;
result
.map_err(|err| format_err!("{}", err))
.map(|bits| TapeAlertFlags::from_bits_truncate(bits))
.map(TapeAlertFlags::from_bits_truncate)
}
/// Set or clear encryption key

View File

@ -32,7 +32,7 @@ enum MamFormat {
DEC,
}
static MAM_ATTRIBUTES: &'static [ (u16, u16, MamFormat, &'static str) ] = &[
static MAM_ATTRIBUTES: &[ (u16, u16, MamFormat, &str) ] = &[
(0x00_00, 8, MamFormat::DEC, "Remaining Capacity In Partition"),
(0x00_01, 8, MamFormat::DEC, "Maximum Capacity In Partition"),
(0x00_02, 8, MamFormat::DEC, "Tapealert Flags"),

View File

@ -258,13 +258,13 @@ pub fn required_media_changer(
) -> Result<(Box<dyn MediaChange>, String), Error> {
match media_changer(config, drive) {
Ok(Some(result)) => {
return Ok(result);
Ok(result)
}
Ok(None) => {
bail!("drive '{}' has no associated changer device", drive);
},
Err(err) => {
return Err(err);
Err(err)
}
}
}
@ -339,7 +339,7 @@ pub fn request_and_load_media(
let media_id = check_label(handle.as_mut(), &label.uuid)?;
return Ok((handle, media_id));
Ok((handle, media_id))
}
"linux" => {
let drive_config = LinuxTapeDrive::deserialize(config)?;
@ -390,20 +390,18 @@ pub fn request_and_load_media(
media_id.label.uuid.to_string(),
));
return Ok((Box::new(handle), media_id));
} else {
if Some(media_id.label.uuid.clone()) != last_media_uuid {
worker.log(format!(
"wrong media label {} ({})",
media_id.label.label_text,
media_id.label.uuid.to_string(),
));
last_media_uuid = Some(media_id.label.uuid);
}
} else if Some(media_id.label.uuid.clone()) != last_media_uuid {
worker.log(format!(
"wrong media label {} ({})",
media_id.label.label_text,
media_id.label.uuid.to_string(),
));
last_media_uuid = Some(media_id.label.uuid);
}
}
Ok((None, _)) => {
if last_media_uuid.is_some() {
worker.log(format!("found empty media without label (please label all tapes first)"));
worker.log("found empty media without label (please label all tapes first)".to_string());
last_media_uuid = None;
}
}

View File

@ -17,6 +17,7 @@ bitflags::bitflags!{
///
/// See LTO SCSI Reference LOG_SENSE - LP 2Eh: TapeAlerts
pub struct TapeAlertFlags: u64 {
#[allow(clippy::eq_op)]
const READ_WARNING = 1 << (0x0001 -1);
const WRITE_WARNING = 1 << (0x0002 -1);
const HARD_ERROR = 1 << (0x0003 -1);

View File

@ -168,8 +168,8 @@ impl VirtualTapeHandle {
if path.is_file() && path.extension() == Some(std::ffi::OsStr::new("json")) {
if let Some(name) = path.file_stem() {
if let Some(name) = name.to_str() {
if name.starts_with("tape-") {
list.push(name[5..].to_string());
if let Some(label) = name.strip_prefix("tape-") {
list.push(label.to_string());
}
}
}

View File

@ -95,19 +95,16 @@ fn decode_volume_statistics(data: &[u8]) -> Result<Lp17VolumeStatistics, Error>
let read_be_counter = |reader: &mut &[u8], len: u8| {
let len = len as usize;
if len == 0 || len > 8 {
bail!("invalid conter size '{}'", len);
}
let mut buffer = [0u8; 8];
reader.read_exact(&mut buffer[..len])?;
let mut value: u64 = 0;
for i in 0..len {
value = value << 8;
value = value | buffer[i] as u64;
}
let value = buffer
.iter()
.take(len)
.fold(0, |value, curr| (value << 8) | *curr as u64);
Ok(value)
};

View File

@ -81,10 +81,8 @@ impl <R: Read> BlockedReader<R> {
if size > buffer.payload.len() {
proxmox::io_bail!("detected tape block with wrong payload size ({} > {}", size, buffer.payload.len());
} else if size == 0 {
if !found_end_marker{
proxmox::io_bail!("detected tape block with zero payload size");
}
} else if size == 0 && !found_end_marker {
proxmox::io_bail!("detected tape block with zero payload size");
}
@ -179,7 +177,7 @@ impl <R: Read> Read for BlockedReader<R> {
}
if rest <= 0 {
return Ok(0);
Ok(0)
} else {
let copy_len = if (buffer.len() as isize) < rest {
buffer.len()
@ -189,7 +187,7 @@ impl <R: Read> Read for BlockedReader<R> {
buffer[..copy_len].copy_from_slice(
&self.buffer.payload[self.read_pos..(self.read_pos + copy_len)]);
self.read_pos += copy_len;
return Ok(copy_len);
Ok(copy_len)
}
}
}

View File

@ -77,7 +77,7 @@ impl <W: Write> BlockedWriter<W> {
self.bytes_written += BlockHeader::SIZE;
} else {
self.buffer_pos = self.buffer_pos + bytes;
self.buffer_pos += bytes;
}
Ok(bytes)

View File

@ -50,7 +50,7 @@ impl SnapshotReader {
}
};
let mut client_log_path = snapshot_path.clone();
let mut client_log_path = snapshot_path;
client_log_path.push(CLIENT_LOG_BLOB_NAME);
let mut file_list = Vec::new();

View File

@ -215,12 +215,13 @@ impl Inventory {
/// find media by label_text
pub fn find_media_by_label_text(&self, label_text: &str) -> Option<&MediaId> {
for (_uuid, entry) in &self.map {
self.map.values().find_map(|entry| {
if entry.id.label.label_text == label_text {
return Some(&entry.id);
Some(&entry.id)
} else {
None
}
}
None
})
}
/// Lookup media pool
@ -245,7 +246,7 @@ impl Inventory {
pub fn list_pool_media(&self, pool: &str) -> Vec<MediaId> {
let mut list = Vec::new();
for (_uuid, entry) in &self.map {
for entry in self.map.values() {
match entry.id.media_set_label {
None => continue, // not assigned to any pool
Some(ref set) => {
@ -272,7 +273,7 @@ impl Inventory {
pub fn list_used_media(&self) -> Vec<MediaId> {
let mut list = Vec::new();
for (_uuid, entry) in &self.map {
for entry in self.map.values() {
match entry.id.media_set_label {
None => continue, // not assigned to any pool
Some(ref set) => {
@ -288,19 +289,17 @@ impl Inventory {
/// List media not assigned to any pool
pub fn list_unassigned_media(&self) -> Vec<MediaId> {
let mut list = Vec::new();
for (_uuid, entry) in &self.map {
self.map.values().filter_map(|entry|
if entry.id.media_set_label.is_none() {
list.push(entry.id.clone());
Some(entry.id.clone())
} else {
None
}
}
list
).collect()
}
pub fn media_set_start_time(&self, media_set_uuid: &Uuid) -> Option<i64> {
self.media_set_start_times.get(media_set_uuid).map(|t| *t)
self.media_set_start_times.get(media_set_uuid).copied()
}
/// Lookup media set pool
@ -383,7 +382,7 @@ impl Inventory {
let set_list = self.map.values()
.filter_map(|entry| entry.id.media_set_label.as_ref())
.filter(|set| &set.pool == &pool && set.uuid.as_ref() != [0u8;16]);
.filter(|set| set.pool == pool && set.uuid.as_ref() != [0u8;16]);
for set in set_list {
match last_set {
@ -406,7 +405,7 @@ impl Inventory {
// consistency check - must be the only set with that ctime
let set_list = self.map.values()
.filter_map(|entry| entry.id.media_set_label.as_ref())
.filter(|set| &set.pool == &pool && set.uuid.as_ref() != [0u8;16]);
.filter(|set| set.pool == pool && set.uuid.as_ref() != [0u8;16]);
for set in set_list {
if set.uuid != uuid && set.ctime >= ctime { // should not happen
@ -437,7 +436,7 @@ impl Inventory {
let set_list = self.map.values()
.filter_map(|entry| entry.id.media_set_label.as_ref())
.filter(|set| (&set.uuid != media_set_uuid) && (&set.pool == &pool));
.filter(|set| (&set.uuid != media_set_uuid) && (set.pool == pool));
let mut next_ctime = None;
@ -522,7 +521,7 @@ impl Inventory {
) -> Result<String, Error> {
if let Some(ctime) = self.media_set_start_time(media_set_uuid) {
let mut template = template.unwrap_or(String::from("%c"));
let mut template = template.unwrap_or_else(|| String::from("%c"));
template = template.replace("%id%", &media_set_uuid.to_string());
proxmox::tools::time::strftime_local(&template, ctime)
} else {
@ -675,20 +674,18 @@ impl Inventory {
for (uuid, entry) in self.map.iter_mut() {
if let Some(changer_name) = online_map.lookup_changer(uuid) {
entry.location = Some(MediaLocation::Online(changer_name.to_string()));
} else {
if let Some(MediaLocation::Online(ref changer_name)) = entry.location {
match online_map.online_map(changer_name) {
None => {
// no such changer device
entry.location = Some(MediaLocation::Offline);
}
Some(None) => {
// got no info - do nothing
}
Some(Some(_)) => {
// media changer changed
entry.location = Some(MediaLocation::Offline);
}
} else if let Some(MediaLocation::Online(ref changer_name)) = entry.location {
match online_map.online_map(changer_name) {
None => {
// no such changer device
entry.location = Some(MediaLocation::Offline);
}
Some(None) => {
// got no info - do nothing
}
Some(Some(_)) => {
// media changer changed
entry.location = Some(MediaLocation::Offline);
}
}
}

View File

@ -323,7 +323,7 @@ impl MediaCatalog {
/// Returns the chunk archive file number
pub fn lookup_snapshot(&self, snapshot: &str) -> Option<u64> {
self.snapshot_index.get(snapshot).map(|n| *n)
self.snapshot_index.get(snapshot).copied()
}
/// Test if the catalog already contain a chunk
@ -333,7 +333,7 @@ impl MediaCatalog {
/// Returns the chunk archive file number
pub fn lookup_chunk(&self, digest: &[u8;32]) -> Option<u64> {
self.chunk_index.get(digest).map(|n| *n)
self.chunk_index.get(digest).copied()
}
fn check_register_label(&self, file_number: u64) -> Result<(), Error> {

Some files were not shown because too many files have changed in this diff Show More