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

View file

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

View file

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

View file

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

View file

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

View file

@ -197,6 +197,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore, virtual S3BinaryCache
S3Helper s3Helper; S3Helper s3Helper;
S3BinaryCacheStoreImpl( S3BinaryCacheStoreImpl(
[[maybe_unused]] const std::string & scheme,
const std::string & bucketName, const std::string & bucketName,
const Params & params) const Params & params)
: StoreConfig(params) : StoreConfig(params)
@ -434,7 +435,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore, virtual S3BinaryCache
return paths; 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: 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) : StoreConfig(params)
, Store(params) , Store(params)
, RemoteStoreConfig(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 std::string getUri() override
{ {
return uriPrefixes()[0] + "://" + host; return *uriSchemes().begin() + "://" + host;
} }
bool sameMachine() override 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_, ref<Store> openStore(const std::string & uri_,
const Store::Params & extraParams) const Store::Params & extraParams)
{ {
auto [uri, uriParams] = splitUriAndParams(uri_);
auto params = extraParams; 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)) { auto baseURI = parsedUri.authority.value_or("") + parsedUri.path;
store->warnUnknownSettings();
return ref<Store>(store); 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) { if (auto store = openFromNonUri(uri, params)) {
auto store = implem.create(uri, params);
if (store) {
store->init();
store->warnUnknownSettings(); store->warnUnknownSettings();
return ref<Store>(store); 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() std::list<ref<Store>> getDefaultSubstituters()

View file

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