Skip to content

Commit 6ce47b2

Browse files
authored
[rust] Use file lock to protect concurrent accesses to cache (fix #13511 and #13686)
* [rust] Use file lock to protect concurrent accesses to cache * [rust] Fix several problems related to file manipulation * [rust] Improve logic for handling unstable edge bad links * [rust] Ensure lock file exists and content of target folder after acquiring lock * [rust] Refactor lock logic in a separate module * [rust] Acquire file lock before downloading driver and browser
1 parent e6d6e0b commit 6ce47b2

File tree

6 files changed

+250
-41
lines changed

6 files changed

+250
-41
lines changed

rust/Cargo.Bazel.lock

+111-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"checksum": "778a62d50d430548a64ececb679a81afba2ffa2ac1553d2e95807253aa723ac7",
2+
"checksum": "ba73e39704c230ab36d29779338a27060fadfde0a7e9b957428668f5fdb9c271",
33
"crates": {
44
"addr2line 0.21.0": {
55
"name": "addr2line",
@@ -4539,6 +4539,100 @@
45394539
],
45404540
"license_file": "LICENSE-APACHE"
45414541
},
4542+
"fs2 0.4.3": {
4543+
"name": "fs2",
4544+
"version": "0.4.3",
4545+
"package_url": "https://github.com/danburkert/fs2-rs",
4546+
"repository": {
4547+
"Http": {
4548+
"url": "https://static.crates.io/crates/fs2/0.4.3/download",
4549+
"sha256": "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
4550+
}
4551+
},
4552+
"targets": [
4553+
{
4554+
"Library": {
4555+
"crate_name": "fs2",
4556+
"crate_root": "src/lib.rs",
4557+
"srcs": {
4558+
"allow_empty": true,
4559+
"include": [
4560+
"**/*.rs"
4561+
]
4562+
}
4563+
}
4564+
}
4565+
],
4566+
"library_target_name": "fs2",
4567+
"common_attrs": {
4568+
"compile_data_glob": [
4569+
"**"
4570+
],
4571+
"deps": {
4572+
"common": [],
4573+
"selects": {
4574+
"cfg(unix)": [
4575+
{
4576+
"id": "libc 0.2.168",
4577+
"target": "libc"
4578+
}
4579+
],
4580+
"cfg(windows)": [
4581+
{
4582+
"id": "winapi 0.3.9",
4583+
"target": "winapi"
4584+
}
4585+
]
4586+
}
4587+
},
4588+
"edition": "2015",
4589+
"version": "0.4.3"
4590+
},
4591+
"license": "MIT/Apache-2.0",
4592+
"license_ids": [
4593+
"Apache-2.0",
4594+
"MIT"
4595+
],
4596+
"license_file": "LICENSE-APACHE"
4597+
},
4598+
"fs_extra 1.3.0": {
4599+
"name": "fs_extra",
4600+
"version": "1.3.0",
4601+
"package_url": "https://github.com/webdesus/fs_extra",
4602+
"repository": {
4603+
"Http": {
4604+
"url": "https://static.crates.io/crates/fs_extra/1.3.0/download",
4605+
"sha256": "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
4606+
}
4607+
},
4608+
"targets": [
4609+
{
4610+
"Library": {
4611+
"crate_name": "fs_extra",
4612+
"crate_root": "src/lib.rs",
4613+
"srcs": {
4614+
"allow_empty": true,
4615+
"include": [
4616+
"**/*.rs"
4617+
]
4618+
}
4619+
}
4620+
}
4621+
],
4622+
"library_target_name": "fs_extra",
4623+
"common_attrs": {
4624+
"compile_data_glob": [
4625+
"**"
4626+
],
4627+
"edition": "2018",
4628+
"version": "1.3.0"
4629+
},
4630+
"license": "MIT",
4631+
"license_ids": [
4632+
"MIT"
4633+
],
4634+
"license_file": "LICENSE"
4635+
},
45424636
"futures 0.3.30": {
45434637
"name": "futures",
45444638
"version": "0.3.30",
@@ -13320,6 +13414,14 @@
1332013414
"id": "flate2 1.0.35",
1332113415
"target": "flate2"
1332213416
},
13417+
{
13418+
"id": "fs2 0.4.3",
13419+
"target": "fs2"
13420+
},
13421+
{
13422+
"id": "fs_extra 1.3.0",
13423+
"target": "fs_extra"
13424+
},
1332313425
{
1332413426
"id": "infer 0.16.0",
1332513427
"target": "infer"
@@ -18553,7 +18655,12 @@
1855318655
],
1855418656
"crate_features": {
1855518657
"common": [
18556-
"winbase"
18658+
"fileapi",
18659+
"handleapi",
18660+
"processthreadsapi",
18661+
"std",
18662+
"winbase",
18663+
"winerror"
1855718664
],
1855818665
"selects": {}
1855918666
},
@@ -22185,6 +22292,8 @@
2218522292
"env_logger 0.11.5",
2218622293
"exitcode 1.1.2",
2218722294
"flate2 1.0.35",
22295+
"fs2 0.4.3",
22296+
"fs_extra 1.3.0",
2218822297
"infer 0.16.0",
2218922298
"log 0.4.22",
2219022299
"regex 1.11.1",

rust/Cargo.lock

+19-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ debpkg = "0.6.0"
3636
anyhow = { version = "1.0.94", default-features = false, features = ["backtrace", "std"] }
3737
apple-flat-package = "0.20.0"
3838
which = "7.0.0"
39+
fs2 = "0.4.3"
40+
fs_extra = "1.3.0"
3941

4042
[dev-dependencies]
4143
assert_cmd = "2.0.16"

rust/src/files.rs

+30-27
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use apple_flat_package::PkgReader;
2727
use bzip2::read::BzDecoder;
2828
use directories::BaseDirs;
2929
use flate2::read::GzDecoder;
30+
use fs_extra::dir::{move_dir, CopyOptions};
3031
use regex::Regex;
3132
use std::fs;
3233
use std::fs::File;
@@ -143,7 +144,7 @@ pub fn uncompress(
143144
} else if extension.eq_ignore_ascii_case(EXE) {
144145
uncompress_sfx(compressed_file, target, log)?
145146
} else if extension.eq_ignore_ascii_case(DEB) {
146-
uncompress_deb(compressed_file, target, log, os, volume.unwrap_or_default())?
147+
uncompress_deb(compressed_file, target, log, volume.unwrap_or_default())?
147148
} else if extension.eq_ignore_ascii_case(MSI) {
148149
install_msi(compressed_file, log, os)?
149150
} else if extension.eq_ignore_ascii_case(XML) || extension.eq_ignore_ascii_case(HTML) {
@@ -158,6 +159,7 @@ pub fn uncompress(
158159
extension
159160
)));
160161
}
162+
161163
Ok(())
162164
}
163165

@@ -176,15 +178,23 @@ pub fn uncompress_sfx(compressed_file: &str, target: &Path, log: &Logger) -> Res
176178
sevenz_rust::decompress(file_reader, zip_parent).unwrap();
177179

178180
let zip_parent_str = path_to_string(zip_parent);
179-
let target_str = path_to_string(target);
180181
let core_str = format!(r"{}\core", zip_parent_str);
182+
move_folder_content(&core_str, &target, &log)?;
183+
184+
Ok(())
185+
}
186+
187+
pub fn move_folder_content(source: &str, target: &Path, log: &Logger) -> Result<(), Error> {
181188
log.trace(format!(
182-
"Moving extracted files and folders from {} to {}",
183-
core_str, target_str
189+
"Moving files and folders from {} to {}",
190+
source,
191+
target.display()
184192
));
185193
create_parent_path_if_not_exists(target)?;
186-
fs::rename(&core_str, &target_str)?;
187-
194+
let mut options = CopyOptions::new();
195+
options.content_only = true;
196+
options.skip_exist = true;
197+
move_dir(source, target, &options)?;
188198
Ok(())
189199
}
190200

@@ -261,7 +271,6 @@ pub fn uncompress_deb(
261271
compressed_file: &str,
262272
target: &Path,
263273
log: &Logger,
264-
os: &str,
265274
label: &str,
266275
) -> Result<(), Error> {
267276
let zip_parent = Path::new(compressed_file).parent().unwrap();
@@ -276,21 +285,17 @@ pub fn uncompress_deb(
276285
deb_pkg.data()?.unpack(zip_parent)?;
277286

278287
let zip_parent_str = path_to_string(zip_parent);
279-
let target_str = path_to_string(target);
280288
let opt_edge_str = format!("{}/opt/microsoft/{}", zip_parent_str, label);
281-
let opt_edge_mv = format!("mv {} {}", opt_edge_str, target_str);
282-
let command = Command::new_single(opt_edge_mv.clone());
283-
log.trace(format!(
284-
"Moving extracted files and folders from {} to {}",
285-
opt_edge_str, target_str
286-
));
287-
create_parent_path_if_not_exists(target)?;
288-
run_shell_command_by_os(os, command)?;
289-
let target_path = Path::new(target);
290-
if target_path.parent().unwrap().read_dir()?.next().is_none() {
291-
fs::rename(&opt_edge_str, &target_str)?;
289+
290+
// Exception due to bad symbolic link in unstable distributions. For example:
291+
// microsoft-edge -> /opt/microsoft/msedge-beta/microsoft-edge-beta
292+
if !label.eq("msedge") {
293+
let link = format!("{}/microsoft-edge", opt_edge_str);
294+
fs::remove_file(Path::new(&link)).unwrap_or_default();
292295
}
293296

297+
move_folder_content(&opt_edge_str, &target, &log)?;
298+
294299
Ok(())
295300
}
296301

@@ -337,14 +342,12 @@ pub fn uncompress_tar(decoder: &mut dyn Read, target: &Path, log: &Logger) -> Re
337342
let mut buffer: Vec<u8> = Vec::new();
338343
decoder.read_to_end(&mut buffer)?;
339344
let mut archive = Archive::new(Cursor::new(buffer));
340-
if !target.exists() {
341-
for entry in archive.entries()? {
342-
let mut entry_decoder = entry?;
343-
let entry_path: PathBuf = entry_decoder.path()?.iter().skip(1).collect();
344-
let entry_target = target.join(entry_path);
345-
fs::create_dir_all(entry_target.parent().unwrap())?;
346-
entry_decoder.unpack(entry_target)?;
347-
}
345+
for entry in archive.entries()? {
346+
let mut entry_decoder = entry?;
347+
let entry_path: PathBuf = entry_decoder.path()?.iter().skip(1).collect();
348+
let entry_target = target.join(entry_path);
349+
fs::create_dir_all(entry_target.parent().unwrap())?;
350+
entry_decoder.unpack(entry_target)?;
348351
}
349352
Ok(())
350353
}

0 commit comments

Comments
 (0)