mononoke: reject pure pushes if the appropriate config is not set

Summary:
This is the final step in making sure we have control over whether
non-pushrebase pushes are supported by a given repo.

Reviewed By: krallin

Differential Revision: D15522276

fbshipit-source-id: 7e3228f7f0836f3dcd0b1a3b2500545342af1c5e
This commit is contained in:
Kostia Balytskyi 2019-05-31 10:46:10 -07:00 committed by Facebook Github Bot
parent e2e5250e36
commit 2d9a45ca45
4 changed files with 98 additions and 3 deletions

View File

@ -73,7 +73,7 @@ pub fn resolve(
phases_hint: Arc<dyn Phases>,
readonly: RepoReadOnly,
maybe_full_content: Option<Arc<Mutex<Bytes>>>,
_pure_push_allowed: bool,
pure_push_allowed: bool,
) -> BoxFuture<Bytes, Error> {
let resolver = Bundle2Resolver::new(
ctx.clone(),
@ -144,6 +144,9 @@ pub fn resolve(
lca_hint,
)
} else {
fn changegroup_always_unacceptable() -> bool {
false
};
resolve_pushrebase(
ctx,
commonheads,
@ -153,6 +156,7 @@ pub fn resolve(
lca_hint,
phases_hint,
maybe_full_content,
changegroup_always_unacceptable,
)
}
} else {
@ -163,6 +167,7 @@ pub fn resolve(
allow_non_fast_forward,
maybe_full_content,
lca_hint,
move || pure_push_allowed,
)
}
},
@ -177,9 +182,10 @@ fn resolve_push(
allow_non_fast_forward: bool,
maybe_full_content: Option<Arc<Mutex<Bytes>>>,
lca_hint: Arc<dyn LeastCommonAncestorsHint>,
changegroup_acceptable: impl FnOnce() -> bool + Send + Sync + 'static,
) -> BoxFuture<Bytes, Error> {
resolver
.maybe_resolve_changegroup(ctx.clone(), bundle2)
.maybe_resolve_changegroup(ctx.clone(), bundle2, changegroup_acceptable)
.and_then({
cloned!(resolver);
move |(cg_push, bundle2)| {
@ -289,6 +295,7 @@ fn resolve_pushrebase(
lca_hint: Arc<dyn LeastCommonAncestorsHint>,
phases_hint: Arc<dyn Phases>,
maybe_full_content: Option<Arc<Mutex<Bytes>>>,
changegroup_acceptable: impl FnOnce() -> bool + Send + Sync + 'static,
) -> BoxFuture<Bytes, Error> {
resolver
.resolve_b2xtreegroup2(ctx.clone(), bundle2)
@ -296,7 +303,7 @@ fn resolve_pushrebase(
cloned!(ctx, resolver);
move |(manifests, bundle2)| {
resolver
.maybe_resolve_changegroup(ctx, bundle2)
.maybe_resolve_changegroup(ctx, bundle2, changegroup_acceptable)
.map(move |(cg_push, bundle2)| (cg_push, manifests, bundle2))
}
})
@ -859,10 +866,13 @@ impl Bundle2Resolver {
/// The Changesets should be parsed as RevlogChangesets and used for uploading changesets
/// The Filelogs should be scheduled for uploading to BlobRepo and the Future resolving in
/// their upload should be used for uploading changesets
/// `pure_push_allowed` argument is responsible for allowing
/// pure (non-pushrebase and non-infinitepush) pushes
fn maybe_resolve_changegroup(
&self,
ctx: CoreContext,
bundle2: BoxStream<Bundle2Item, Error>,
changegroup_acceptable: impl FnOnce() -> bool + Send + Sync + 'static,
) -> BoxFuture<(Option<ChangegroupPush>, BoxStream<Bundle2Item, Error>), Error> {
let repo = self.repo.clone();
@ -873,6 +883,11 @@ impl Bundle2Resolver {
Some(Bundle2Item::Changegroup(header, parts))
| Some(Bundle2Item::B2xInfinitepush(header, parts))
| Some(Bundle2Item::B2xRebase(header, parts)) => {
if header.part_type() == &PartHeaderType::Changegroup && !changegroup_acceptable() {
// Changegroup part type signals that we are in a pure push scenario
return err(format_err!("Pure pushes are disallowed in this repo"))
.boxify();
}
let (c, f) = split_changegroup(parts);
convert_to_revlog_changesets(c)
.collect()

View File

@ -27,6 +27,7 @@ use metaconfig_types::{
HookType, InfinitepushNamespace, InfinitepushParams, LfsParams, MetadataDBConfig,
PushParams, PushrebaseParams, RepoConfig, RepoReadOnly,
ShardedFilenodesParams, StorageConfig, WhitelistEntry,
};
use regex::Regex;
use toml;

View File

@ -398,6 +398,13 @@ preserve_raw_bundle2 = true
CONFIG
fi
if [[ -v DISALLOW_NON_PUSHREBASE ]]; then
cat >> "repos/$reponame/server.toml" <<CONFIG
[push]
pure_push_allowed = false
CONFIG
fi
if [[ -v CACHE_WARMUP_BOOKMARK ]]; then
cat >> "repos/$reponame/server.toml" <<CONFIG
[cache_warmup]

View File

@ -0,0 +1,72 @@
$ . $TESTDIR/library.sh
setup configuration
$ DISALLOW_NON_PUSHREBASE=1 setup_common_config
$ cd $TESTTMP
setup repo
$ hginit_treemanifest repo-hg-server
$ cd repo-hg-server
$ echo "a file content" > a
$ hg add a
$ hg ci -ma
$ hg bookmark master_bookmark -r 'tip'
verify content
$ hg log
changeset: 0:0e7ec5675652
bookmark: master_bookmark
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: a
blobimport the repo
$ cd $TESTTMP
$ blobimport repo-hg-server/.hg repo
start mononoke
$ mononoke
$ wait_for_mononoke $TESTTMP/repo
setup the client repo
$ cd $TESTTMP
$ hgclone_treemanifest ssh://user@dummy/repo-hg-server client --noupdate --config extensions.remotenames= -q
create new hg commits
$ cd $TESTTMP/client
$ hg up -q 0
$ echo b > b && hg ci -Am b
adding b
try doing a non-pushrebase push with the new commits
$ hgmn push --force ssh://user@dummy/repo
pushing to ssh://user@dummy/repo
searching for changes
remote: Command failed
remote: Error:
remote: bundle2_resolver error
remote: Root cause:
remote: ErrorMessage {
remote: msg: "Pure pushes are disallowed in this repo",
remote: }
remote: Caused by:
remote: While resolving Changegroup
remote: Caused by:
remote: Pure pushes are disallowed in this repo
abort: stream ended unexpectedly (got 0 bytes, expected 4)
[255]
try doing a pushrebase push with the new commits
$ hgmn push ssh://user@dummy/repo --config extensions.pushrebase= --config extensions.remotenames= --to master_bookmark
pushing rev * to destination ssh://user@dummy/repo bookmark master_bookmark (glob)
searching for changes
adding changesets
adding manifests
adding file changes
added 0 changesets with 0 changes to 0 files
updating bookmark master_bookmark