@opencode-cloud/core 13.0.0 → 13.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +8 -8
- package/package.json +1 -1
- package/src/platform/mod.rs +19 -4
- package/src/platform/systemd.rs +29 -3
package/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "opencode-cloud-core"
|
|
3
|
-
version = "13.0.
|
|
3
|
+
version = "13.0.1"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
rust-version = "1.89"
|
|
6
6
|
license = "MIT"
|
|
@@ -23,11 +23,11 @@ napi = ["dep:napi", "dep:napi-derive"]
|
|
|
23
23
|
|
|
24
24
|
[dependencies]
|
|
25
25
|
clap = { version = "4.5", features = ["derive"] }
|
|
26
|
-
tokio = { version = "1.
|
|
26
|
+
tokio = { version = "1.49", features = ["rt-multi-thread", "macros"] }
|
|
27
27
|
serde = { version = "1.0", features = ["derive"] }
|
|
28
28
|
serde_json = "1.0"
|
|
29
29
|
jsonc-parser = { version = "0.29", features = ["serde"] }
|
|
30
|
-
directories = "
|
|
30
|
+
directories = "6"
|
|
31
31
|
thiserror = "2"
|
|
32
32
|
anyhow = "1"
|
|
33
33
|
tracing = "0.1"
|
|
@@ -35,18 +35,18 @@ console = "0.16"
|
|
|
35
35
|
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
|
|
36
36
|
|
|
37
37
|
# NAPI dependencies (optional - only for Node bindings)
|
|
38
|
-
napi = { version = "
|
|
39
|
-
napi-derive = { version = "
|
|
38
|
+
napi = { version = "3", features = ["tokio_rt", "napi9"], optional = true }
|
|
39
|
+
napi-derive = { version = "3", optional = true }
|
|
40
40
|
|
|
41
41
|
# Docker integration
|
|
42
42
|
bollard = { version = "0.20.1", features = ["chrono", "buildkit"] }
|
|
43
43
|
futures-util = "0.3"
|
|
44
44
|
tar = "0.4"
|
|
45
|
-
flate2 = "1.
|
|
45
|
+
flate2 = "1.1"
|
|
46
46
|
tokio-retry = "0.3"
|
|
47
|
-
indicatif = { version = "0.
|
|
47
|
+
indicatif = { version = "0.18", features = ["tokio", "futures"] }
|
|
48
48
|
http-body-util = "0.1"
|
|
49
|
-
bytes = "1.
|
|
49
|
+
bytes = "1.11"
|
|
50
50
|
reqwest = { version = "0.13", default-features = false, features = ["rustls", "webpki-roots", "json"] }
|
|
51
51
|
|
|
52
52
|
# Platform service management (macOS)
|
package/package.json
CHANGED
package/src/platform/mod.rs
CHANGED
|
@@ -85,9 +85,12 @@ pub trait ServiceManager: Send + Sync {
|
|
|
85
85
|
|
|
86
86
|
/// Get the appropriate service manager for the current platform
|
|
87
87
|
///
|
|
88
|
+
/// # Arguments
|
|
89
|
+
/// * `boot_mode` - "user" for user-level service (default), "system" for system-level
|
|
90
|
+
///
|
|
88
91
|
/// Returns an error if the platform is not supported or if the
|
|
89
92
|
/// service manager implementation is not yet available.
|
|
90
|
-
pub fn get_service_manager() -> Result<Box<dyn ServiceManager>> {
|
|
93
|
+
pub fn get_service_manager(boot_mode: &str) -> Result<Box<dyn ServiceManager>> {
|
|
91
94
|
#[cfg(target_os = "linux")]
|
|
92
95
|
{
|
|
93
96
|
if !systemd::systemd_available() {
|
|
@@ -96,11 +99,11 @@ pub fn get_service_manager() -> Result<Box<dyn ServiceManager>> {
|
|
|
96
99
|
Service registration requires systemd as the init system."
|
|
97
100
|
));
|
|
98
101
|
}
|
|
99
|
-
Ok(Box::new(systemd::SystemdManager::new(
|
|
102
|
+
Ok(Box::new(systemd::SystemdManager::new(boot_mode)))
|
|
100
103
|
}
|
|
101
104
|
#[cfg(target_os = "macos")]
|
|
102
105
|
{
|
|
103
|
-
Ok(Box::new(launchd::LaunchdManager::new(
|
|
106
|
+
Ok(Box::new(launchd::LaunchdManager::new(boot_mode)))
|
|
104
107
|
}
|
|
105
108
|
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
|
|
106
109
|
{
|
|
@@ -164,7 +167,7 @@ mod tests {
|
|
|
164
167
|
|
|
165
168
|
#[test]
|
|
166
169
|
fn test_get_service_manager_behavior() {
|
|
167
|
-
let result = get_service_manager();
|
|
170
|
+
let result = get_service_manager("user");
|
|
168
171
|
|
|
169
172
|
// On Linux with systemd: returns Ok(SystemdManager)
|
|
170
173
|
// On Linux without systemd: returns Err (systemd not available)
|
|
@@ -188,4 +191,16 @@ mod tests {
|
|
|
188
191
|
assert!(result.is_err());
|
|
189
192
|
}
|
|
190
193
|
}
|
|
194
|
+
|
|
195
|
+
#[test]
|
|
196
|
+
fn test_get_service_manager_respects_boot_mode() {
|
|
197
|
+
// Test that boot_mode parameter is passed through
|
|
198
|
+
let user_result = get_service_manager("user");
|
|
199
|
+
let system_result = get_service_manager("system");
|
|
200
|
+
|
|
201
|
+
// Both should either succeed or fail based on platform support,
|
|
202
|
+
// but they should not panic
|
|
203
|
+
let _ = user_result;
|
|
204
|
+
let _ = system_result;
|
|
205
|
+
}
|
|
191
206
|
}
|
package/src/platform/systemd.rs
CHANGED
|
@@ -130,11 +130,37 @@ pub fn systemd_available() -> bool {
|
|
|
130
130
|
Path::new("/run/systemd/system").exists()
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
/// Check if systemd user session is available for the current user
|
|
134
|
+
///
|
|
135
|
+
/// Returns true if XDG_RUNTIME_DIR is set and the user's systemd directory exists.
|
|
136
|
+
/// This is needed for `systemctl --user` commands to work.
|
|
137
|
+
pub fn systemd_user_session_available() -> bool {
|
|
138
|
+
if let Ok(runtime_dir) = std::env::var("XDG_RUNTIME_DIR") {
|
|
139
|
+
// Check if the user's systemd directory exists
|
|
140
|
+
Path::new(&runtime_dir).join("systemd").exists()
|
|
141
|
+
} else {
|
|
142
|
+
false
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
133
146
|
impl ServiceManager for SystemdManager {
|
|
134
147
|
fn install(&self, config: &ServiceConfig) -> Result<InstallResult> {
|
|
135
|
-
// Check permissions
|
|
136
|
-
if
|
|
137
|
-
//
|
|
148
|
+
// Check permissions and session availability based on mode
|
|
149
|
+
if self.user_mode {
|
|
150
|
+
// User-level installation requires an active systemd user session
|
|
151
|
+
if !systemd_user_session_available() {
|
|
152
|
+
return Err(anyhow!(
|
|
153
|
+
"User-level systemd session not available.\n\
|
|
154
|
+
This typically happens during cloud-init or when running as a \
|
|
155
|
+
different user without an active login session.\n\n\
|
|
156
|
+
Solutions:\n\
|
|
157
|
+
1. Use system-level installation: occ config set boot_mode system\n\
|
|
158
|
+
2. Run the command from an interactive login session\n\
|
|
159
|
+
3. Ensure XDG_RUNTIME_DIR is set and the user has an active systemd session"
|
|
160
|
+
));
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
// System-level installation requires root privileges
|
|
138
164
|
let test_path = self.service_dir().join(".opencode-cloud-test");
|
|
139
165
|
if fs::write(&test_path, "").is_err() {
|
|
140
166
|
return Err(anyhow!(
|