Properly filter the stores according to their declared uriSchemes

When opening a store, only try the stores whose `uriSchemes()` include
the current one
This commit is contained in:
regnat 2020-09-11 11:11:05 +02:00
parent 5895184df4
commit 7f103dcddd
10 changed files with 51 additions and 33 deletions

View file

@ -8,7 +8,7 @@ struct DummyStoreConfig : StoreConfig {
struct DummyStore : public Store, public virtual DummyStoreConfig
{
DummyStore(const std::string uri, const Params & params)
DummyStore(const std::string scheme, const std::string uri, const Params & params)
: DummyStore(params)
{ }
@ -21,7 +21,7 @@ struct DummyStore : public Store, public virtual DummyStoreConfig
string getUri() override
{
return uriPrefixes()[0] + "://";
return *uriSchemes().begin();
}
void queryPathInfoUncached(const StorePath & path,
@ -30,7 +30,7 @@ struct DummyStore : public Store, public virtual DummyStoreConfig
callback(nullptr);
}
static std::vector<std::string> uriPrefixes() {
static std::set<std::string> uriSchemes() {
return {"dummy"};
}

View file

@ -29,13 +29,14 @@ private:
public:
HttpBinaryCacheStore(
const std::string & scheme,
const Path & _cacheUri,
const Params & params)
: StoreConfig(params)
, BinaryCacheStoreConfig(params)
, BinaryCacheStore(params)
, HttpBinaryCacheStoreConfig(params)
, cacheUri(_cacheUri)
, cacheUri(scheme + "://" + _cacheUri)
{
if (cacheUri.back() == '/')
cacheUri.pop_back();
@ -64,11 +65,11 @@ public:
}
}
static std::vector<std::string> uriPrefixes()
static std::set<std::string> uriSchemes()
{
static bool forceHttp = getEnv("_NIX_FORCE_HTTP") == "1";
auto ret = std::vector<std::string>({"http", "https"});
if (forceHttp) ret.push_back("file");
auto ret = std::set<std::string>({"http", "https"});
if (forceHttp) ret.insert("file");
return ret;
}
protected:

View file

@ -41,9 +41,9 @@ struct LegacySSHStore : public Store, public virtual LegacySSHStoreConfig
SSHMaster master;
static std::vector<std::string> uriPrefixes() { return {"ssh"}; }
static std::set<std::string> uriSchemes() { return {"ssh"}; }
LegacySSHStore(const string & host, const Params & params)
LegacySSHStore(const string & scheme, const string & host, const Params & params)
: StoreConfig(params)
, LegacySSHStoreConfig(params)
, Store(params)
@ -92,7 +92,7 @@ struct LegacySSHStore : public Store, public virtual LegacySSHStoreConfig
string getUri() override
{
return uriPrefixes()[0] + "://" + host;
return *uriSchemes().begin() + "://" + host;
}
void queryPathInfoUncached(const StorePath & path,

View file

@ -18,6 +18,7 @@ private:
public:
LocalBinaryCacheStore(
[[maybe_unused]] const std::string scheme,
const Path & binaryCacheDir,
const Params & params)
: StoreConfig(params)
@ -35,7 +36,7 @@ public:
return "file://" + binaryCacheDir;
}
static std::vector<std::string> uriPrefixes();
static std::set<std::string> uriSchemes();
protected:
@ -96,7 +97,7 @@ bool LocalBinaryCacheStore::fileExists(const std::string & path)
return pathExists(binaryCacheDir + "/" + path);
}
std::vector<std::string> LocalBinaryCacheStore::uriPrefixes()
std::set<std::string> LocalBinaryCacheStore::uriSchemes()
{
if (getEnv("_NIX_FORCE_HTTP_BINARY_CACHE_STORE") == "1")
return {};

View file

@ -135,7 +135,10 @@ UDSRemoteStore::UDSRemoteStore(const Params & params)
}
UDSRemoteStore::UDSRemoteStore(std::string socket_path, const Params & params)
UDSRemoteStore::UDSRemoteStore(
[[maybe_unused]] const std::string scheme,
std::string socket_path,
const Params & params)
: UDSRemoteStore(params)
{
path.emplace(socket_path);

View file

@ -165,11 +165,11 @@ class UDSRemoteStore : public LocalFSStore, public RemoteStore, public virtual U
public:
UDSRemoteStore(const Params & params);
UDSRemoteStore(std::string path, const Params & params);
UDSRemoteStore(const std::string scheme, std::string path, const Params & params);
std::string getUri() override;
static std::vector<std::string> uriPrefixes()
static std::set<std::string> uriSchemes()
{ return {"unix"}; }
bool sameMachine() override

View file

@ -197,6 +197,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore, virtual S3BinaryCache
S3Helper s3Helper;
S3BinaryCacheStoreImpl(
[[maybe_unused]] const std::string & scheme,
const std::string & bucketName,
const Params & params)
: StoreConfig(params)
@ -434,7 +435,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore, virtual S3BinaryCache
return paths;
}
static std::vector<std::string> uriPrefixes() { return {"s3"}; }
static std::set<std::string> uriSchemes() { return {"s3"}; }
};

View file

@ -22,7 +22,7 @@ class SSHStore : public virtual RemoteStore, public virtual SSHStoreConfig
{
public:
SSHStore(const std::string & host, const Params & params)
SSHStore([[maybe_unused]] const std::string & scheme, const std::string & host, const Params & params)
: StoreConfig(params)
, Store(params)
, RemoteStoreConfig(params)
@ -38,11 +38,11 @@ public:
{
}
static std::vector<std::string> uriPrefixes() { return {"ssh-ng"}; }
static std::set<std::string> uriSchemes() { return {"ssh-ng"}; }
std::string getUri() override
{
return uriPrefixes()[0] + "://" + host;
return *uriSchemes().begin() + "://" + host;
}
bool sameMachine() override

View file

@ -1078,25 +1078,35 @@ std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Para
ref<Store> openStore(const std::string & uri_,
const Store::Params & extraParams)
{
auto [uri, uriParams] = splitUriAndParams(uri_);
auto params = extraParams;
params.insert(uriParams.begin(), uriParams.end());
try {
auto parsedUri = parseURL(uri_);
params.insert(parsedUri.query.begin(), parsedUri.query.end());
if (auto store = openFromNonUri(uri, params)) {
store->warnUnknownSettings();
return ref<Store>(store);
auto baseURI = parsedUri.authority.value_or("") + parsedUri.path;
for (auto implem : *Implementations::registered) {
if (implem.uriSchemes.count(parsedUri.scheme)) {
auto store = implem.create(parsedUri.scheme, baseURI, params);
if (store) {
store->init();
store->warnUnknownSettings();
return ref<Store>(store);
}
}
}
}
catch (BadURL) {
auto [uri, uriParams] = splitUriAndParams(uri_);
params.insert(uriParams.begin(), uriParams.end());
for (auto implem : *Implementations::registered) {
auto store = implem.create(uri, params);
if (store) {
store->init();
if (auto store = openFromNonUri(uri, params)) {
store->warnUnknownSettings();
return ref<Store>(store);
}
}
throw Error("don't know how to open Nix store '%s'", uri);
throw Error("don't know how to open Nix store '%s'", uri_);
}
std::list<ref<Store>> getDefaultSubstituters()

View file

@ -760,7 +760,8 @@ std::list<ref<Store>> getDefaultSubstituters();
struct StoreFactory
{
std::function<std::shared_ptr<Store> (const std::string & uri, const Store::Params & params)> create;
std::set<std::string> uriSchemes;
std::function<std::shared_ptr<Store> (const std::string & scheme, const std::string & uri, const Store::Params & params)> create;
std::function<std::shared_ptr<StoreConfig> ()> getConfig;
};
struct Implementations
@ -773,13 +774,14 @@ struct Implementations
if (!registered) registered = new std::vector<StoreFactory>();
StoreFactory factory{
.create =
([](const std::string & uri, const Store::Params & params)
([](const std::string & scheme, const std::string & uri, const Store::Params & params)
-> std::shared_ptr<Store>
{ return std::make_shared<T>(uri, params); }),
{ return std::make_shared<T>(scheme, uri, params); }),
.getConfig =
([]()
-> std::shared_ptr<StoreConfig>
{ return std::make_shared<TConfig>(); })
{ return std::make_shared<TConfig>(StringMap({})); }),
.uriSchemes = T::uriSchemes()
};
registered->push_back(factory);
}