use crate::cmds::*;
use crate::run::run_async;
use holochain_client::AdminWebsocket;
use holochain_conductor_api::conductor::paths::ConfigRootPath;
use holochain_conductor_api::AppInfo;
use holochain_trace::Output;
use holochain_types::app::{AppManifest, RoleSettingsMap, RoleSettingsMapYaml};
use holochain_types::prelude::{
AgentPubKey, AppBundleSource, InstallAppPayload, InstalledAppId, NetworkSeed,
};
use std::collections::HashMap;
use std::path::Path;
use std::path::PathBuf;
#[derive(Debug, Clone)]
pub struct InstallApp {
pub app_id: Option<String>,
pub agent_key: Option<AgentPubKey>,
pub path: PathBuf,
pub network_seed: Option<NetworkSeed>,
pub roles_settings: Option<PathBuf>,
}
async fn install_app_bundle(
client: &mut AdminWebsocket,
args: InstallApp,
) -> anyhow::Result<AppInfo> {
let InstallApp {
app_id,
agent_key,
path,
network_seed,
roles_settings,
} = args;
let roles_settings = match roles_settings {
Some(path) => {
let yaml_string = std::fs::read_to_string(path)?;
let roles_settings_yaml = serde_yaml::from_str::<RoleSettingsMapYaml>(&yaml_string)?;
let mut roles_settings: RoleSettingsMap = HashMap::new();
for (k, v) in roles_settings_yaml.into_iter() {
roles_settings.insert(k, v.into());
}
Some(roles_settings)
}
None => None,
};
let payload = InstallAppPayload {
installed_app_id: app_id.clone(),
agent_key,
source: AppBundleSource::Path(path),
roles_settings,
network_seed,
ignore_genesis_failure: false,
};
let installed_app = client.install_app(payload).await?;
match &installed_app.manifest {
AppManifest::V0(manifest) => {
if !manifest.allow_deferred_memproofs {
client
.enable_app(installed_app.installed_app_id.clone())
.await?;
}
}
}
Ok(installed_app)
}
#[allow(clippy::too_many_arguments)]
pub async fn default_with_network(
holochain_path: &Path,
create: Create,
directory: Option<PathBuf>,
happ: PathBuf,
app_id: InstalledAppId,
network_seed: Option<String>,
roles_settings: Option<PathBuf>,
structured: Output,
) -> anyhow::Result<ConfigRootPath> {
let Create {
network,
root,
in_process_lair,
#[cfg(feature = "chc")]
chc_url,
..
} = create;
let network = Network::to_kitsune(&NetworkCmd::as_inner(&network)).await;
let config_path = holochain_conductor_config::generate::generate(
network,
root,
directory,
in_process_lair,
0,
#[cfg(feature = "chc")]
chc_url,
)?;
let conductor = run_async(holochain_path, config_path.clone(), None, structured).await?;
let mut client = AdminWebsocket::connect(format!("localhost:{}", conductor.0), None).await?;
let install_bundle = InstallApp {
app_id: Some(app_id),
agent_key: None,
path: happ,
network_seed,
roles_settings,
};
install_app_bundle(&mut client, install_bundle).await?;
Ok(config_path)
}
pub async fn default_n(
holochain_path: &Path,
create: Create,
happ: PathBuf,
app_id: InstalledAppId,
network_seed: Option<String>,
roles_settings: Option<PathBuf>,
structured: Output,
) -> anyhow::Result<Vec<ConfigRootPath>> {
let num_sandboxes = create.num_sandboxes.into();
let mut paths = Vec::with_capacity(num_sandboxes);
for i in 0..num_sandboxes {
let p = default_with_network(
holochain_path,
create.clone(),
create.directories.get(i).cloned(),
happ.clone(),
app_id.clone(),
network_seed.clone(),
roles_settings.clone(),
structured.clone(),
)
.await?;
paths.push(p);
}
Ok(paths)
}