configs: fetch remote configs during dynamic config generation

Summary:
Fetches configs from a remote endpoint and caches them locally. If the
remote endpoint fails to respond, we use the cached version.

Reviewed By: quark-zju

Differential Revision: D22010684

fbshipit-source-id: bd6d4349d185d7450a3d18f9db2709967edc2971
This commit is contained in:
Durham Goode 2020-06-30 09:48:31 -07:00 committed by Facebook GitHub Bot
parent 4bf346b6ac
commit 977155ef99
6 changed files with 30 additions and 11 deletions

View File

@ -452,7 +452,7 @@ class localrepository(object):
# If the repo does not already exists, load the dynamic configs in
# memory only. They will be written to disk later once the localvfs
# is created.
uiconfig.applydynamicconfig(self.ui, reponame)
uiconfig.applydynamicconfig(self.ui, reponame, self.path)
self._loadextensions()

View File

@ -679,9 +679,9 @@ def validatedynamicconfig(ui):
)
def applydynamicconfig(ui, reponame):
def applydynamicconfig(ui, reponame, sharedpath):
if ui.configbool("configs", "loaddynamicconfig"):
dynamicconfig.applydynamicconfig(ui._uiconfig._rcfg._rcfg, reponame)
dynamicconfig.applydynamicconfig(ui._uiconfig._rcfg._rcfg, reponame, sharedpath)
validatedynamicconfig(ui)

View File

@ -21,7 +21,10 @@ pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
m.add(
py,
"applydynamicconfig",
py_fn!(py, applydynamicconfig(config: config, repo_name: String)),
py_fn!(
py,
applydynamicconfig(config: config, repo_name: String, shared_path: PyPathBuf)
),
)?;
m.add(
py,
@ -34,8 +37,13 @@ pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
Ok(m)
}
fn applydynamicconfig(py: Python, config: config, repo_name: String) -> PyResult<PyNone> {
let dyn_cfg = Generator::new(repo_name)
fn applydynamicconfig(
py: Python,
config: config,
repo_name: String,
shared_path: PyPathBuf,
) -> PyResult<PyNone> {
let dyn_cfg = Generator::new(repo_name, shared_path.to_path_buf())
.map_pyerr(py)?
.execute()
.map_pyerr(py)?;
@ -61,7 +69,7 @@ fn generatedynamicconfig(
repo_name: String,
shared_path: PyPathBuf,
) -> PyResult<PyNone> {
let config = Generator::new(repo_name)
let config = Generator::new(repo_name, shared_path.to_path_buf())
.map_pyerr(py)?
.execute()
.map_pyerr(py)?;

View File

@ -10,6 +10,11 @@ hgtime = { path = "../hgtime" }
hostname = "0.3"
minibytes = { path = "../minibytes" }
os_info = "2.0.1"
reqwest = { version = "0.10", features=["blocking"] }
serde_json = "1.0"
sha2 = "0.8"
thrift-types = { path = "../thrift-types" }
types = { path = "../types" }
[dev-dependencies]
tempdir = "0.3.7"

View File

@ -10,7 +10,7 @@ use std::collections::HashSet;
use std::convert::TryInto;
use std::fs;
use std::hash::{Hash, Hasher};
use std::path::Path;
use std::path::{Path, PathBuf};
use std::str::FromStr;
#[cfg(not(feature = "fb"))]
@ -86,6 +86,7 @@ pub enum Domain {
}
pub struct Generator {
repo_path: PathBuf,
tiers: HashSet<String>,
repo: Repo,
group: HgGroup,
@ -96,7 +97,7 @@ pub struct Generator {
}
impl Generator {
pub fn new(repo_name: String) -> Result<Self> {
pub fn new(repo_name: String, repo_path: PathBuf) -> Result<Self> {
let repo = Repo::from_str(&repo_name)?;
let tiers: HashSet<String> = if Path::new("/etc/smc.tiers").exists() {
@ -131,6 +132,7 @@ impl Generator {
};
Ok(Generator {
repo_path,
tiers,
repo,
group,
@ -141,6 +143,10 @@ impl Generator {
})
}
pub(crate) fn repo_path(&self) -> &Path {
self.repo_path.as_ref()
}
pub(crate) fn group(&self) -> HgGroup {
self.group
}
@ -305,7 +311,7 @@ pub(crate) mod tests {
#[test]
fn test_basic() {
let repo_name = "test_repo";
let mut generator = Generator::new(repo_name.to_string()).unwrap();
let mut generator = Generator::new(repo_name.to_string(), PathBuf::new()).unwrap();
let tiers = HashSet::from_iter(["in_tier1", "in_tier2"].iter().map(|s| s.to_string()));
let group = HgGroup::Alpha;

View File

@ -297,7 +297,7 @@ pub fn debugdynamicconfig(_opts: NoOpts, _io: &mut IO, repo: Repo) -> Result<u8>
let repo_name: String = repo
.repo_name()
.map_or_else(|| "".to_string(), |s| s.to_string());
let config = Generator::new(repo_name)?.execute()?;
let config = Generator::new(repo_name, repo.shared_dot_hg_path().to_path_buf())?.execute()?;
let config_str = config.to_string();
let config_str = format!(
"# version={}\n# Generated by `hg debugdynamicconfig` - DO NOT MODIFY\n{}",