Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add git file ingestion method #1

Merged
merged 29 commits into from
May 28, 2020
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f3dbfaa
Merge remote-tracking branch 'Ericson2314/enum-FileIngestionMethod' i…
matthewbauer May 27, 2020
d4aff3f
Add initial IpfsStore
matthewbauer May 27, 2020
e5281ce
Add ingestionMethodPrefix to get prefix
matthewbauer May 27, 2020
cbad8b4
Rename some variables named “recursive” to “method”
matthewbauer May 27, 2020
0b98d55
Handle g: prefix in nix store paths
matthewbauer May 27, 2020
859fbce
Don’t use FileIngestionMethod for StorePathsCommand
matthewbauer May 27, 2020
b0b6d4b
Merge remote-tracking branch 'obsidiansystems/ipfs-develop' into ipfs…
matthewbauer May 27, 2020
09a9bf0
Use git: instead of g: for ca prefix
matthewbauer May 27, 2020
44bc71b
Rename recursive to method in more places
matthewbauer May 27, 2020
fb83c10
Throw error when using unsupported git file ingestion
matthewbauer May 27, 2020
168c7d8
First draft of git parsing
meditans May 27, 2020
147764c
Use switch ingestion method in BinaryCacheStore::addToStore
matthewbauer May 28, 2020
63df19e
Merge remote-tracking branch 'obsidian/ipfs-develop' into ipfs-git-me…
Ericson2314 May 28, 2020
6c29671
Merge branch 'ipfs-develop' into ipfs-git-method
Ericson2314 May 28, 2020
17dc40c
Merge branch 'ipfs-develop' into ipfs-git-method
Ericson2314 May 28, 2020
dbca599
Add ingestionMethodPrefix to get prefix
matthewbauer May 27, 2020
9b452c9
Handle g: prefix in nix store paths
matthewbauer May 27, 2020
16c4945
Use git: instead of g: for ca prefix
matthewbauer May 27, 2020
6ba8360
Rename recursive to method in more places
matthewbauer May 27, 2020
2e16c28
Throw error when using unsupported git file ingestion
matthewbauer May 27, 2020
256bbb6
First draft of git parsing
meditans May 27, 2020
85eeb2a
Use switch ingestion method in BinaryCacheStore::addToStore
matthewbauer May 28, 2020
39df335
More work on git objects
matthewbauer May 27, 2020
77a9510
Merge branch 'git-objects' into ipfs-git-method
Ericson2314 May 28, 2020
ffc1024
Add fcntl.h to fs-sink.hh
matthewbauer May 28, 2020
35001b6
Remove `aarch64-linux` from supportedSystems until we have a builder
Ericson2314 May 27, 2020
9d82006
Remove x86-linux from supportedSystems for now, too
Ericson2314 May 27, 2020
77153be
Merge remote-tracking branch 'obsidiansystems/ipfs-develop' into git-…
matthewbauer May 28, 2020
9e820c1
Merge branch 'git-objects-develop' into ipfs-git-method
matthewbauer May 28, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath);
drv.outputs.insert_or_assign("out", DerivationOutput {
std::move(outPath),
(ingestionMethod == FileIngestionMethod::Recursive ? "r:" : "")
+ printHashType(h.type),
ingestionMethodPrefix(ingestionMethod) + printHashType(h.type),
h.to_string(Base16, false),
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/libstore/binary-cache-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ StorePath BinaryCacheStore::addToStore(const string & name, const Path & srcPath
if (method == FileIngestionMethod::Recursive) {
dumpPath(srcPath, sink, filter);
h = hashString(hashAlgo, *sink.s);
} else if (method == FileIngestionMethod::Git) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With cases like these its is good to use switch case instead, so the compiler can help us make sure we caught all the cases.

throw Error("cannot add to binary cache store using the git file ingestion method");
} else {
auto s = readFile(srcPath);
dumpString(s, sink);
Expand Down
9 changes: 6 additions & 3 deletions src/libstore/derivations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@
namespace nix {


void DerivationOutput::parseHashInfo(FileIngestionMethod & recursive, Hash & hash) const
void DerivationOutput::parseHashInfo(FileIngestionMethod & method, Hash & hash) const
{
recursive = FileIngestionMethod::Flat;
method = FileIngestionMethod::Flat;
string algo = hashAlgo;

if (string(algo, 0, 2) == "r:") {
recursive = FileIngestionMethod::Recursive;
method = FileIngestionMethod::Recursive;
algo = string(algo, 2);
} else if (string(algo, 0, 4) == "git:") {
method = FileIngestionMethod::Git;
algo = string(algo, 2);
}

Expand Down
2 changes: 1 addition & 1 deletion src/libstore/derivations.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct DerivationOutput
, hashAlgo(std::move(hashAlgo))
, hash(std::move(hash))
{ }
void parseHashInfo(FileIngestionMethod & recursive, Hash & hash) const;
void parseHashInfo(FileIngestionMethod & method, Hash & hash) const;
};

typedef std::map<string, DerivationOutput> DerivationOutputs;
Expand Down
61 changes: 61 additions & 0 deletions src/libstore/ipfs.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "binary-cache-store.hh"

namespace nix {

class IpfsStore : public BinaryCacheStore
{
Path daemonUri;

public:

IpfsStore(
const Params & params, const Path & _daemonUri)
: BinaryCacheStore(params)
, daemonUri(_daemonUri)
{
if (daemonUri.back() == '/')
daemonUri.pop_back();
}

std::string getUri() override
{
return daemonUri;
}

void init() override
{
}

bool fileExists(const std::string & path) override
{
return false;
}

void upsertFile(const std::string & path,
const std::string & data,
const std::string & mimeType) override
{
}

void getFile(const std::string & path, Sink & sink) override
{
}

void getFile(const std::string & path, Callback<std::shared_ptr<std::string>> callback) noexcept override
{
}

};

static RegisterStoreImplementation regStore([](
const std::string & uri, const Store::Params & params)
-> std::shared_ptr<Store>
{
if (std::string(uri, 0, 12) != "ipfs+http://")
return 0;
auto store = std::make_shared<IpfsStore>(params, std::string(uri, 5));
store->init();
return store;
});

}
17 changes: 15 additions & 2 deletions src/libstore/path.hh
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,23 @@ const size_t storePathHashLen = 32; // i.e. 160 bits
const std::string drvExtension = ".drv";

enum struct FileIngestionMethod : uint8_t {
Flat = false,
Recursive = true
Flat,
Recursive,
Git
};

inline std::string ingestionMethodPrefix(FileIngestionMethod method) {
switch (method) {
case FileIngestionMethod::Flat:
return "";
case FileIngestionMethod::Recursive:
return "r:";
case FileIngestionMethod::Git:
return "git:";
}
throw;
}

struct StorePathWithOutputs
{
StorePath path;
Expand Down
2 changes: 2 additions & 0 deletions src/libstore/remote-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,8 @@ StorePath RemoteStore::addToStore(const string & name, const Path & _srcPath,
{
if (repair) throw Error("repairing is not supported when building through the Nix daemon");

if (method == FileIngestionMethod::Git) throw Error("cannot remotely add to store using the git file ingestion method");

auto conn(getConnection());

Path srcPath(absPath(_srcPath));
Expand Down
26 changes: 14 additions & 12 deletions src/libstore/store-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ string storePathToHash(const Path & path)
for paths copied by addToStore() or produced by fixed-output
derivations:
the string "fixed:out:<rec><algo>:<hash>:", where
<rec> = "r:" for recursive (path) hashes, or "" for flat
(file) hashes
<rec> = "r:" for recursive (path) hashes, "git:" for git
paths, or "" for flat (file) hashes
<algo> = "md5", "sha1" or "sha256"
<hash> = base-16 representation of the path or flat hash of
the contents of the path (or expected contents of the
Expand Down Expand Up @@ -172,20 +172,20 @@ static std::string makeType(


StorePath Store::makeFixedOutputPath(
FileIngestionMethod recursive,
FileIngestionMethod method,
const Hash & hash,
std::string_view name,
const StorePathSet & references,
bool hasSelfReference) const
{
if (hash.type == htSHA256 && recursive == FileIngestionMethod::Recursive) {
if (hash.type == htSHA256 && method == FileIngestionMethod::Recursive) {
return makeStorePath(makeType(*this, "source", references, hasSelfReference), hash, name);
} else {
assert(references.empty());
return makeStorePath("output:out",
hashString(htSHA256,
"fixed:out:"
+ (recursive == FileIngestionMethod::Recursive ? (string) "r:" : "")
+ ingestionMethodPrefix(method)
+ hash.to_string(Base16) + ":"),
name);
}
Expand Down Expand Up @@ -787,15 +787,19 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const
}

else if (hasPrefix(ca, "fixed:")) {
FileIngestionMethod recursive { ca.compare(6, 2, "r:") == 0 };
Hash hash(std::string(ca, recursive == FileIngestionMethod::Recursive ? 8 : 6));
FileIngestionMethod method = FileIngestionMethod::Flat;
if (ca.compare(6, 2, "r:") == 0)
method = FileIngestionMethod::Recursive;
else if (ca.compare(6, 4, "git:") == 0)
method = FileIngestionMethod::Git;
Hash hash(std::string(ca, 6 + ingestionMethodPrefix(method).length()));
auto refs = cloneStorePathSet(references);
bool hasSelfReference = false;
if (refs.count(path)) {
hasSelfReference = true;
refs.erase(path);
}
if (store.makeFixedOutputPath(recursive, hash, path.name(), refs, hasSelfReference) == path)
if (store.makeFixedOutputPath(method, hash, path.name(), refs, hasSelfReference) == path)
return true;
else
warn();
Expand Down Expand Up @@ -832,11 +836,9 @@ Strings ValidPathInfo::shortRefs() const
}


std::string makeFixedOutputCA(FileIngestionMethod recursive, const Hash & hash)
std::string makeFixedOutputCA(FileIngestionMethod method, const Hash & hash)
{
return "fixed:"
+ (recursive == FileIngestionMethod::Recursive ? (std::string) "r:" : "")
+ hash.to_string();
return "fixed:" + ingestionMethodPrefix(method) + hash.to_string();
}


Expand Down
12 changes: 6 additions & 6 deletions src/nix-store/nix-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ static void opAdd(Strings opFlags, Strings opArgs)
store. */
static void opAddFixed(Strings opFlags, Strings opArgs)
{
auto recursive = FileIngestionMethod::Flat;
auto method = FileIngestionMethod::Flat;

for (auto & i : opFlags)
if (i == "--recursive") recursive = FileIngestionMethod::Recursive;
if (i == "--recursive") method = FileIngestionMethod::Recursive;
else throw UsageError(format("unknown flag '%1%'") % i);

if (opArgs.empty())
Expand All @@ -187,17 +187,17 @@ static void opAddFixed(Strings opFlags, Strings opArgs)
opArgs.pop_front();

for (auto & i : opArgs)
cout << fmt("%s\n", store->printStorePath(store->addToStore(std::string(baseNameOf(i)), i, recursive, hashAlgo)));
cout << fmt("%s\n", store->printStorePath(store->addToStore(std::string(baseNameOf(i)), i, method, hashAlgo)));
}


/* Hack to support caching in `nix-prefetch-url'. */
static void opPrintFixedPath(Strings opFlags, Strings opArgs)
{
auto recursive = FileIngestionMethod::Flat;
auto method = FileIngestionMethod::Flat;

for (auto i : opFlags)
if (i == "--recursive") recursive = FileIngestionMethod::Recursive;
if (i == "--recursive") method = FileIngestionMethod::Recursive;
else throw UsageError(format("unknown flag '%1%'") % i);

if (opArgs.size() != 3)
Expand All @@ -208,7 +208,7 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
string hash = *i++;
string name = *i++;

cout << fmt("%s\n", store->printStorePath(store->makeFixedOutputPath(recursive, Hash(hash, hashAlgo), name)));
cout << fmt("%s\n", store->printStorePath(store->makeFixedOutputPath(method, Hash(hash, hashAlgo), name)));
}


Expand Down