-
Notifications
You must be signed in to change notification settings - Fork 6
Use ssh2 instead of std::process::Command #172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
ed6d619
c5811d8
61d992c
a566f08
ee2828c
327dc82
7bc38a0
c236986
38a275d
537e846
1cbac37
1d8fd32
ede5781
193268f
6cb7f19
f832a11
5580324
6df6689
67ad2e5
ac11ef6
d1f8363
1f2dd63
5e8ff7a
feecdbb
ecd277e
29aa98b
3020e38
7afa257
1757a27
020cfb9
94ee183
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,9 +7,8 @@ use std::{ | |
path::{Path, PathBuf}, | ||
}; | ||
|
||
use anyhow::bail; | ||
use anyhow::{bail, Context}; | ||
use flate2::read::GzDecoder; | ||
use log::debug; | ||
use tar::Archive; | ||
|
||
use ssh2::{FileStat, Session}; | ||
|
@@ -44,6 +43,7 @@ impl RemoteCommand { | |
|
||
cmd.arg(executable); | ||
if let Some(args) = args { | ||
cmd.arg("--"); // They should be passed to the process, not to 'su' | ||
cmd.args(args); | ||
} | ||
|
||
|
@@ -126,17 +126,23 @@ pub fn run_other<S: AsRef<str>>( | |
{ | ||
let path = Path::new(&path); | ||
|
||
let sftp = session.sftp()?; | ||
sftp.create(path)?.write_all(&std::fs::read(prog)?)?; | ||
let mut stat = sftp.stat(path)?; | ||
let sftp = session.sftp().context("Creating sftp session")?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! I'm usually too lazy to add |
||
sftp.create(path) | ||
.context(format!("Creating {:?}", path))? | ||
|
||
.write_all(&std::fs::read(prog)?) | ||
.context(format!("Writing {:?}", prog))?; | ||
let mut stat = sftp | ||
.stat(path) | ||
.context(format!("Running `stat` on {:?}", path))?; | ||
// `sftp.create` creates a new file with write-only permissions, | ||
// but since we expect to run this program we need to mark it executable | ||
// for the user | ||
stat.perm = Some(0o100744); | ||
sftp.setstat(path, stat)?; | ||
sftp.setstat(path, stat) | ||
.context(format!("Updating stat on {:?}", path))?; | ||
} | ||
|
||
RemoteCommand::new(None::<&str>, Some(env), &path, Some(args)).exec(session) | ||
RemoteCommand::new(None::<&str>, Some(env), path, Some(args)).exec(session) | ||
} | ||
|
||
// TODO: Consider abstracting away the difference between devices that support developer mode, and | ||
|
@@ -201,7 +207,7 @@ pub fn patch_package(package: &Path, session: &Session) -> anyhow::Result<()> { | |
}; | ||
|
||
let package_dir = PathBuf::from("/usr/local/packages").join(app_name); | ||
let sftp = session.sftp()?; | ||
let sftp = session.sftp().context("Creating sftp session")?; | ||
if sftp.stat(&package_dir).is_err() { | ||
bail!("Package doesn't exist!"); | ||
} | ||
|
@@ -223,11 +229,26 @@ pub fn patch_package(package: &Path, session: &Session) -> anyhow::Result<()> { | |
mtime: Some(header.mtime()?), | ||
size: None, | ||
}; | ||
|
||
if header.entry_type().is_dir() { | ||
// If the directory can't be opened, then it doesn't exist so we need to create it. | ||
// TODO: What if permissions has changed? | ||
if sftp.opendir(entry.path()?).is_err() { | ||
sftp.mkdir(&header.path()?, header.mode()? as i32) | ||
.context(format!("Creating directory {:?}", entry.path()?))?; | ||
} | ||
|
||
continue; | ||
} | ||
|
||
entry.read_to_end(&mut buf)?; | ||
debug!("Writing file: {:?}", entry.path()?); | ||
let mut file = sftp.create(&package_dir.join(&entry.path()?))?; | ||
file.write_all(&buf)?; | ||
file.setstat(stat)?; | ||
let mut file = sftp | ||
.create(&package_dir.join(&entry.path()?)) | ||
.context(format!("Creating {:?}", entry.path()?))?; | ||
file.write_all(&buf) | ||
.context(format!("Writing to {:?}", entry.path()?))?; | ||
file.setstat(stat) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this work if the app contains files that are symlinks? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does not. I'll fix that. |
||
.context(format!("Updating stat on {:?}", entry.path()?))?; | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tested this?
I don't have a camera at hand, but
su --help
on Debian does not mention that--
can be used and experimenting seems to confirm this:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. When I was running the tests it was complaining since we pass
--test-threads=1
to the test. Adding the '--' suppressed this but that's not the correct way to do it. We need to pass the executable with its arguments as a whole, i.e. as a string:su root -c "env --help"
I've fixed that now and added a test in
inspect_env
to make sure this stays working.