Skip to content

Commit 98da1ea

Browse files
Fix remote extension syncing (#42918)
Closes #40906 Closes #39729 SFTP uploads weren't quoting the install directory which was causing extension syncing to fail. We were also only running `install_extension` once per remote-connection instead of once per project (thx @feeiyu for pointing this out) so extension weren't being loaded in subsequently opened remote projects. Release Notes: - N/A --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
1 parent 98a83b4 commit 98da1ea

3 files changed

Lines changed: 35 additions & 26 deletions

File tree

crates/extension_host/src/extension_host.rs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use async_compression::futures::bufread::GzipDecoder;
1111
use async_tar::Archive;
1212
use client::ExtensionProvides;
1313
use client::{Client, ExtensionMetadata, GetExtensionsResponse, proto, telemetry::Telemetry};
14-
use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
14+
use collections::{BTreeMap, BTreeSet, HashSet, btree_map};
1515
pub use extension::ExtensionManifest;
1616
use extension::extension_builder::{CompileExtensionOptions, ExtensionBuilder};
1717
use extension::{
@@ -43,7 +43,7 @@ use language::{
4343
use node_runtime::NodeRuntime;
4444
use project::ContextProviderWithTasks;
4545
use release_channel::ReleaseChannel;
46-
use remote::{RemoteClient, RemoteConnectionOptions};
46+
use remote::RemoteClient;
4747
use semantic_version::SemanticVersion;
4848
use serde::{Deserialize, Serialize};
4949
use settings::Settings;
@@ -123,7 +123,7 @@ pub struct ExtensionStore {
123123
pub wasm_host: Arc<WasmHost>,
124124
pub wasm_extensions: Vec<(Arc<ExtensionManifest>, WasmExtension)>,
125125
pub tasks: Vec<Task<()>>,
126-
pub remote_clients: HashMap<RemoteConnectionOptions, WeakEntity<RemoteClient>>,
126+
pub remote_clients: Vec<WeakEntity<RemoteClient>>,
127127
pub ssh_registered_tx: UnboundedSender<()>,
128128
}
129129

@@ -274,7 +274,7 @@ impl ExtensionStore {
274274
reload_tx,
275275
tasks: Vec::new(),
276276

277-
remote_clients: HashMap::default(),
277+
remote_clients: Default::default(),
278278
ssh_registered_tx: connection_registered_tx,
279279
};
280280

@@ -348,7 +348,7 @@ impl ExtensionStore {
348348
index_changed = false;
349349
}
350350

351-
Self::update_ssh_clients(&this, cx).await?;
351+
Self::update_remote_clients(&this, cx).await?;
352352
}
353353
_ = connection_registered_rx.next() => {
354354
debounce_timer = cx
@@ -1725,7 +1725,7 @@ impl ExtensionStore {
17251725
})
17261726
}
17271727

1728-
async fn sync_extensions_over_ssh(
1728+
async fn sync_extensions_to_remotes(
17291729
this: &WeakEntity<Self>,
17301730
client: WeakEntity<RemoteClient>,
17311731
cx: &mut AsyncApp,
@@ -1778,7 +1778,11 @@ impl ExtensionStore {
17781778
})?,
17791779
path_style,
17801780
);
1781-
log::info!("Uploading extension {}", missing_extension.clone().id);
1781+
log::info!(
1782+
"Uploading extension {} to {:?}",
1783+
missing_extension.clone().id,
1784+
dest_dir
1785+
);
17821786

17831787
client
17841788
.update(cx, |client, cx| {
@@ -1791,44 +1795,48 @@ impl ExtensionStore {
17911795
missing_extension.clone().id
17921796
);
17931797

1794-
client
1798+
let result = client
17951799
.update(cx, |client, _cx| {
17961800
client.proto_client().request(proto::InstallExtension {
17971801
tmp_dir: dest_dir.to_proto(),
1798-
extension: Some(missing_extension),
1802+
extension: Some(missing_extension.clone()),
17991803
})
18001804
})?
1801-
.await?;
1805+
.await;
1806+
1807+
if let Err(e) = result {
1808+
log::error!(
1809+
"Failed to install extension {}: {}",
1810+
missing_extension.id,
1811+
e
1812+
);
1813+
}
18021814
}
18031815

18041816
anyhow::Ok(())
18051817
}
18061818

1807-
pub async fn update_ssh_clients(this: &WeakEntity<Self>, cx: &mut AsyncApp) -> Result<()> {
1819+
pub async fn update_remote_clients(this: &WeakEntity<Self>, cx: &mut AsyncApp) -> Result<()> {
18081820
let clients = this.update(cx, |this, _cx| {
1809-
this.remote_clients.retain(|_k, v| v.upgrade().is_some());
1810-
this.remote_clients.values().cloned().collect::<Vec<_>>()
1821+
this.remote_clients.retain(|v| v.upgrade().is_some());
1822+
this.remote_clients.clone()
18111823
})?;
18121824

18131825
for client in clients {
1814-
Self::sync_extensions_over_ssh(this, client, cx)
1826+
Self::sync_extensions_to_remotes(this, client, cx)
18151827
.await
18161828
.log_err();
18171829
}
18181830

18191831
anyhow::Ok(())
18201832
}
18211833

1822-
pub fn register_remote_client(&mut self, client: Entity<RemoteClient>, cx: &mut Context<Self>) {
1823-
let options = client.read(cx).connection_options();
1824-
1825-
if let Some(existing_client) = self.remote_clients.get(&options)
1826-
&& existing_client.upgrade().is_some()
1827-
{
1828-
return;
1829-
}
1830-
1831-
self.remote_clients.insert(options, client.downgrade());
1834+
pub fn register_remote_client(
1835+
&mut self,
1836+
client: Entity<RemoteClient>,
1837+
_cx: &mut Context<Self>,
1838+
) {
1839+
self.remote_clients.push(client.downgrade());
18321840
self.ssh_registered_tx.unbounded_send(()).ok();
18331841
}
18341842
}

crates/extension_host/src/headless_host.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,8 @@ impl HeadlessExtensionStore {
279279
}
280280

281281
fs.rename(&tmp_path, &path, RenameOptions::default())
282-
.await?;
282+
.await
283+
.context("Failed to rename {tmp_path:?} to {path:?}")?;
283284

284285
Self::load_extension(this, extension, cx).await
285286
})

crates/remote/src/transport/ssh.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ impl RemoteConnection for SshRemoteConnection {
304304
let mut child = sftp_command.spawn()?;
305305
if let Some(mut stdin) = child.stdin.take() {
306306
use futures::AsyncWriteExt;
307-
let sftp_batch = format!("put -r {src_path_display} {dest_path_str}\n");
307+
let sftp_batch = format!("put -r \"{src_path_display}\" \"{dest_path_str}\"\n");
308308
stdin.write_all(sftp_batch.as_bytes()).await?;
309309
stdin.flush().await?;
310310
}

0 commit comments

Comments
 (0)