From f26c8bcf3167069ccd8ac3beb9185d1bf480a83f Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Tue, 22 Oct 2024 01:41:08 -0700 Subject: refactor(runtime/ops): use concrete error types (#26409) --- runtime/ops/os/mod.rs | 115 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 37 deletions(-) (limited to 'runtime/ops/os/mod.rs') diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs index bd9260e97..24b0389e1 100644 --- a/runtime/ops/os/mod.rs +++ b/runtime/ops/os/mod.rs @@ -1,9 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use super::utils::into_string; use crate::worker::ExitCode; -use deno_core::error::type_error; -use deno_core::error::AnyError; use deno_core::op2; use deno_core::v8; use deno_core::OpState; @@ -73,17 +70,39 @@ deno_core::extension!( }, ); +#[derive(Debug, thiserror::Error)] +pub enum OsError { + #[error(transparent)] + Permission(deno_core::error::AnyError), + #[error("File name or path {0:?} is not valid UTF-8")] + InvalidUtf8(std::ffi::OsString), + #[error("Key is an empty string.")] + EnvEmptyKey, + #[error("Key contains invalid characters: {0:?}")] + EnvInvalidKey(String), + #[error("Value contains invalid characters: {0:?}")] + EnvInvalidValue(String), + #[error(transparent)] + Var(#[from] env::VarError), + #[error("{0}")] + Io(#[from] std::io::Error), +} + #[op2] #[string] -fn op_exec_path(state: &mut OpState) -> Result { +fn op_exec_path(state: &mut OpState) -> Result { let current_exe = env::current_exe().unwrap(); state .borrow_mut::() - .check_read_blind(¤t_exe, "exec_path", "Deno.execPath()")?; + .check_read_blind(¤t_exe, "exec_path", "Deno.execPath()") + .map_err(OsError::Permission)?; // normalize path so it doesn't include '.' or '..' components let path = normalize_path(current_exe); - into_string(path.into_os_string()) + path + .into_os_string() + .into_string() + .map_err(OsError::InvalidUtf8) } #[op2(fast)] @@ -91,20 +110,19 @@ fn op_set_env( state: &mut OpState, #[string] key: &str, #[string] value: &str, -) -> Result<(), AnyError> { - state.borrow_mut::().check_env(key)?; +) -> Result<(), OsError> { + state + .borrow_mut::() + .check_env(key) + .map_err(OsError::Permission)?; if key.is_empty() { - return Err(type_error("Key is an empty string.")); + return Err(OsError::EnvEmptyKey); } if key.contains(&['=', '\0'] as &[char]) { - return Err(type_error(format!( - "Key contains invalid characters: {key:?}" - ))); + return Err(OsError::EnvInvalidKey(key.to_string())); } if value.contains('\0') { - return Err(type_error(format!( - "Value contains invalid characters: {value:?}" - ))); + return Err(OsError::EnvInvalidValue(value.to_string())); } env::set_var(key, value); Ok(()) @@ -112,7 +130,9 @@ fn op_set_env( #[op2] #[serde] -fn op_env(state: &mut OpState) -> Result, AnyError> { +fn op_env( + state: &mut OpState, +) -> Result, deno_core::error::AnyError> { state.borrow_mut::().check_env_all()?; Ok(env::vars().collect()) } @@ -122,21 +142,22 @@ fn op_env(state: &mut OpState) -> Result, AnyError> { fn op_get_env( state: &mut OpState, #[string] key: String, -) -> Result, AnyError> { +) -> Result, OsError> { let skip_permission_check = NODE_ENV_VAR_ALLOWLIST.contains(&key); if !skip_permission_check { - state.borrow_mut::().check_env(&key)?; + state + .borrow_mut::() + .check_env(&key) + .map_err(OsError::Permission)?; } if key.is_empty() { - return Err(type_error("Key is an empty string.")); + return Err(OsError::EnvEmptyKey); } if key.contains(&['=', '\0'] as &[char]) { - return Err(type_error(format!( - "Key contains invalid characters: {key:?}" - ))); + return Err(OsError::EnvInvalidKey(key.to_string())); } let r = match env::var(key) { @@ -150,10 +171,13 @@ fn op_get_env( fn op_delete_env( state: &mut OpState, #[string] key: String, -) -> Result<(), AnyError> { - state.borrow_mut::().check_env(&key)?; +) -> Result<(), OsError> { + state + .borrow_mut::() + .check_env(&key) + .map_err(OsError::Permission)?; if key.is_empty() || key.contains(&['=', '\0'] as &[char]) { - return Err(type_error("Key contains invalid characters.")); + return Err(OsError::EnvInvalidKey(key.to_string())); } env::remove_var(key); Ok(()) @@ -178,7 +202,9 @@ fn op_exit(state: &mut OpState) { #[op2] #[serde] -fn op_loadavg(state: &mut OpState) -> Result<(f64, f64, f64), AnyError> { +fn op_loadavg( + state: &mut OpState, +) -> Result<(f64, f64, f64), deno_core::error::AnyError> { state .borrow_mut::() .check_sys("loadavg", "Deno.loadavg()")?; @@ -187,7 +213,9 @@ fn op_loadavg(state: &mut OpState) -> Result<(f64, f64, f64), AnyError> { #[op2] #[string] -fn op_hostname(state: &mut OpState) -> Result { +fn op_hostname( + state: &mut OpState, +) -> Result { state .borrow_mut::() .check_sys("hostname", "Deno.hostname()")?; @@ -196,7 +224,9 @@ fn op_hostname(state: &mut OpState) -> Result { #[op2] #[string] -fn op_os_release(state: &mut OpState) -> Result { +fn op_os_release( + state: &mut OpState, +) -> Result { state .borrow_mut::() .check_sys("osRelease", "Deno.osRelease()")?; @@ -207,10 +237,11 @@ fn op_os_release(state: &mut OpState) -> Result { #[serde] fn op_network_interfaces( state: &mut OpState, -) -> Result, AnyError> { +) -> Result, OsError> { state .borrow_mut::() - .check_sys("networkInterfaces", "Deno.networkInterfaces()")?; + .check_sys("networkInterfaces", "Deno.networkInterfaces()") + .map_err(OsError::Permission)?; Ok(netif::up()?.map(NetworkInterface::from).collect()) } @@ -259,7 +290,7 @@ impl From for NetworkInterface { #[serde] fn op_system_memory_info( state: &mut OpState, -) -> Result, AnyError> { +) -> Result, deno_core::error::AnyError> { state .borrow_mut::() .check_sys("systemMemoryInfo", "Deno.systemMemoryInfo()")?; @@ -269,7 +300,9 @@ fn op_system_memory_info( #[cfg(not(windows))] #[op2] #[smi] -fn op_gid(state: &mut OpState) -> Result, AnyError> { +fn op_gid( + state: &mut OpState, +) -> Result, deno_core::error::AnyError> { state .borrow_mut::() .check_sys("gid", "Deno.gid()")?; @@ -283,7 +316,9 @@ fn op_gid(state: &mut OpState) -> Result, AnyError> { #[cfg(windows)] #[op2] #[smi] -fn op_gid(state: &mut OpState) -> Result, AnyError> { +fn op_gid( + state: &mut OpState, +) -> Result, deno_core::error::AnyError> { state .borrow_mut::() .check_sys("gid", "Deno.gid()")?; @@ -293,7 +328,9 @@ fn op_gid(state: &mut OpState) -> Result, AnyError> { #[cfg(not(windows))] #[op2] #[smi] -fn op_uid(state: &mut OpState) -> Result, AnyError> { +fn op_uid( + state: &mut OpState, +) -> Result, deno_core::error::AnyError> { state .borrow_mut::() .check_sys("uid", "Deno.uid()")?; @@ -307,7 +344,9 @@ fn op_uid(state: &mut OpState) -> Result, AnyError> { #[cfg(windows)] #[op2] #[smi] -fn op_uid(state: &mut OpState) -> Result, AnyError> { +fn op_uid( + state: &mut OpState, +) -> Result, deno_core::error::AnyError> { state .borrow_mut::() .check_sys("uid", "Deno.uid()")?; @@ -485,7 +524,7 @@ fn rss() -> usize { } } -fn os_uptime(state: &mut OpState) -> Result { +fn os_uptime(state: &mut OpState) -> Result { state .borrow_mut::() .check_sys("osUptime", "Deno.osUptime()")?; @@ -494,6 +533,8 @@ fn os_uptime(state: &mut OpState) -> Result { #[op2(fast)] #[number] -fn op_os_uptime(state: &mut OpState) -> Result { +fn op_os_uptime( + state: &mut OpState, +) -> Result { os_uptime(state) } -- cgit v1.2.3 From fe9f0ee5934871175758857899fe64e56c397fd5 Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Mon, 4 Nov 2024 09:17:21 -0800 Subject: refactor(runtime/permissions): use concrete error types (#26464) --- runtime/ops/os/mod.rs | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) (limited to 'runtime/ops/os/mod.rs') diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs index 24b0389e1..9bee9d823 100644 --- a/runtime/ops/os/mod.rs +++ b/runtime/ops/os/mod.rs @@ -73,7 +73,7 @@ deno_core::extension!( #[derive(Debug, thiserror::Error)] pub enum OsError { #[error(transparent)] - Permission(deno_core::error::AnyError), + Permission(#[from] deno_permissions::PermissionCheckError), #[error("File name or path {0:?} is not valid UTF-8")] InvalidUtf8(std::ffi::OsString), #[error("Key is an empty string.")] @@ -94,8 +94,7 @@ fn op_exec_path(state: &mut OpState) -> Result { let current_exe = env::current_exe().unwrap(); state .borrow_mut::() - .check_read_blind(¤t_exe, "exec_path", "Deno.execPath()") - .map_err(OsError::Permission)?; + .check_read_blind(¤t_exe, "exec_path", "Deno.execPath()")?; // normalize path so it doesn't include '.' or '..' components let path = normalize_path(current_exe); @@ -111,10 +110,7 @@ fn op_set_env( #[string] key: &str, #[string] value: &str, ) -> Result<(), OsError> { - state - .borrow_mut::() - .check_env(key) - .map_err(OsError::Permission)?; + state.borrow_mut::().check_env(key)?; if key.is_empty() { return Err(OsError::EnvEmptyKey); } @@ -146,10 +142,7 @@ fn op_get_env( let skip_permission_check = NODE_ENV_VAR_ALLOWLIST.contains(&key); if !skip_permission_check { - state - .borrow_mut::() - .check_env(&key) - .map_err(OsError::Permission)?; + state.borrow_mut::().check_env(&key)?; } if key.is_empty() { @@ -172,10 +165,7 @@ fn op_delete_env( state: &mut OpState, #[string] key: String, ) -> Result<(), OsError> { - state - .borrow_mut::() - .check_env(&key) - .map_err(OsError::Permission)?; + state.borrow_mut::().check_env(&key)?; if key.is_empty() || key.contains(&['=', '\0'] as &[char]) { return Err(OsError::EnvInvalidKey(key.to_string())); } @@ -240,8 +230,7 @@ fn op_network_interfaces( ) -> Result, OsError> { state .borrow_mut::() - .check_sys("networkInterfaces", "Deno.networkInterfaces()") - .map_err(OsError::Permission)?; + .check_sys("networkInterfaces", "Deno.networkInterfaces()")?; Ok(netif::up()?.map(NetworkInterface::from).collect()) } -- cgit v1.2.3 From aa546189be730163ee5370029e4dfdb3b454ab96 Mon Sep 17 00:00:00 2001 From: snek Date: Wed, 13 Nov 2024 11:38:46 +0100 Subject: feat: OpenTelemetry Tracing API and Exporting (#26710) Initial import of OTEL code supporting tracing. Metrics soon to come. Implements APIs for https://jsr.io/@deno/otel so that code using OpenTelemetry.js just works tm. There is still a lot of work to do with configuration and adding built-in tracing to core APIs, which will come in followup PRs. --------- Co-authored-by: Luca Casonato --- runtime/ops/os/mod.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'runtime/ops/os/mod.rs') diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs index 9bee9d823..790962f38 100644 --- a/runtime/ops/os/mod.rs +++ b/runtime/ops/os/mod.rs @@ -186,6 +186,8 @@ fn op_get_exit_code(state: &mut OpState) -> i32 { #[op2(fast)] fn op_exit(state: &mut OpState) { + crate::ops::otel::otel_drop_state(state); + let code = state.borrow::().get(); std::process::exit(code) } -- cgit v1.2.3 From 4e899d48cffa95617266dd8f9aef54603a87ad82 Mon Sep 17 00:00:00 2001 From: snek Date: Thu, 14 Nov 2024 13:16:28 +0100 Subject: fix: otel resiliency (#26857) Improving the breadth of collected data, and ensuring that the collected data is more likely to be successfully reported. - Use `log` crate in more places - Hook up `log` crate to otel - Switch to process-wide otel processors - Handle places that use `process::exit` Also adds a more robust testing framework, with a deterministic tracing setting. Refs: https://github.com/denoland/deno/issues/26852 --- runtime/ops/os/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'runtime/ops/os/mod.rs') diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs index 790962f38..b10a2939e 100644 --- a/runtime/ops/os/mod.rs +++ b/runtime/ops/os/mod.rs @@ -186,10 +186,8 @@ fn op_get_exit_code(state: &mut OpState) -> i32 { #[op2(fast)] fn op_exit(state: &mut OpState) { - crate::ops::otel::otel_drop_state(state); - let code = state.borrow::().get(); - std::process::exit(code) + crate::exit(code) } #[op2] -- cgit v1.2.3 From c9baf3849fdbe161a9251a712a71e2b91eeabf3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 15 Nov 2024 09:33:03 +0000 Subject: perf: use available system memory for v8 isolate memory limit (#26868) Instead of using the default 1.4Gb limit (which was meant for browser tabs) configure V8 to set the heap limit to the amount of memory available in the system. Closes https://github.com/denoland/deno/issues/23424 Closes https://github.com/denoland/deno/issues/26435 Closes https://github.com/denoland/deno/issues/21226 --- runtime/ops/os/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'runtime/ops/os/mod.rs') diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs index b10a2939e..74c708c53 100644 --- a/runtime/ops/os/mod.rs +++ b/runtime/ops/os/mod.rs @@ -1,5 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use crate::sys_info; use crate::worker::ExitCode; use deno_core::op2; use deno_core::v8; @@ -11,8 +12,6 @@ use serde::Serialize; use std::collections::HashMap; use std::env; -mod sys_info; - deno_core::extension!( deno_os, ops = [ -- cgit v1.2.3