forked from lix-project/lix
* Importing and exporting of pre-built packages.
This commit is contained in:
parent
383f9bb0f1
commit
5bc26fb73f
116
src/nix.cc
116
src/nix.cc
|
@ -35,6 +35,7 @@ using namespace std;
|
||||||
|
|
||||||
static string dbRefs = "refs";
|
static string dbRefs = "refs";
|
||||||
static string dbInstPkgs = "pkginst";
|
static string dbInstPkgs = "pkginst";
|
||||||
|
static string dbPrebuilts = "prebuilts";
|
||||||
|
|
||||||
|
|
||||||
static string prog;
|
static string prog;
|
||||||
|
@ -307,6 +308,14 @@ string getFromEnv(const Environment & env, const string & key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string queryPkgId(const string & hash)
|
||||||
|
{
|
||||||
|
Params pkgImports, fileImports, arguments;
|
||||||
|
readPkgDescr(hash, pkgImports, fileImports, arguments);
|
||||||
|
return getFromEnv(arguments, "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void installPkg(string hash)
|
void installPkg(string hash)
|
||||||
{
|
{
|
||||||
string pkgfile;
|
string pkgfile;
|
||||||
|
@ -321,8 +330,10 @@ void installPkg(string hash)
|
||||||
|
|
||||||
builder = getFromEnv(env, "build");
|
builder = getFromEnv(env, "build");
|
||||||
|
|
||||||
|
string id = getFromEnv(env, "id");
|
||||||
|
|
||||||
/* Construct a path for the installed package. */
|
/* Construct a path for the installed package. */
|
||||||
path = pkgHome + "/" + hash;
|
path = pkgHome + "/" + id + "-" + hash;
|
||||||
|
|
||||||
/* Create the path. */
|
/* Create the path. */
|
||||||
if (mkdir(path.c_str(), 0777))
|
if (mkdir(path.c_str(), 0777))
|
||||||
|
@ -341,10 +352,33 @@ void installPkg(string hash)
|
||||||
|
|
||||||
/* Go to the build directory. */
|
/* Go to the build directory. */
|
||||||
if (chdir(path.c_str())) {
|
if (chdir(path.c_str())) {
|
||||||
cout << "unable to chdir to package directory\n";
|
cerr << "unable to chdir to package directory\n";
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Try to use a prebuilt. */
|
||||||
|
string prebuiltHash, prebuiltFile;
|
||||||
|
if (queryDB(dbPrebuilts, hash, prebuiltHash) &&
|
||||||
|
queryDB(dbRefs, prebuiltHash, prebuiltFile))
|
||||||
|
{
|
||||||
|
cerr << "substituting prebuilt " << prebuiltFile << endl;
|
||||||
|
|
||||||
|
if (hashFile(prebuiltFile) != prebuiltHash) {
|
||||||
|
cerr << "prebuilt " + prebuiltFile + " is stale\n";
|
||||||
|
goto build;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = system(("tar xvfj " + prebuiltFile).c_str()); // !!! escaping
|
||||||
|
if (WEXITSTATUS(res) != 0)
|
||||||
|
/* This is a fatal error, because path may now
|
||||||
|
have clobbered. */
|
||||||
|
throw Error("cannot unpack " + prebuiltFile);
|
||||||
|
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
build:
|
||||||
|
|
||||||
/* Fill in the environment. We don't bother freeing the
|
/* Fill in the environment. We don't bother freeing the
|
||||||
strings, since we'll exec or die soon anyway. */
|
strings, since we'll exec or die soon anyway. */
|
||||||
const char * env2[env.size() + 1];
|
const char * env2[env.size() + 1];
|
||||||
|
@ -357,9 +391,9 @@ void installPkg(string hash)
|
||||||
/* Execute the builder. This should not return. */
|
/* Execute the builder. This should not return. */
|
||||||
execle(builder.c_str(), builder.c_str(), 0, env2);
|
execle(builder.c_str(), builder.c_str(), 0, env2);
|
||||||
|
|
||||||
cout << strerror(errno) << endl;
|
cerr << strerror(errno) << endl;
|
||||||
|
|
||||||
cout << "unable to execute builder\n";
|
cerr << "unable to execute builder\n";
|
||||||
_exit(1); }
|
_exit(1); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -427,7 +461,7 @@ void runPkg(string hash, const vector<string> & args)
|
||||||
/* Execute the runner. This should not return. */
|
/* Execute the runner. This should not return. */
|
||||||
execv(runner.c_str(), (char * *) args2);
|
execv(runner.c_str(), (char * *) args2);
|
||||||
|
|
||||||
cout << strerror(errno) << endl;
|
cerr << strerror(errno) << endl;
|
||||||
throw Error("unable to execute runner");
|
throw Error("unable to execute runner");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,6 +480,50 @@ void ensurePkg(string hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void delPkg(string hash)
|
||||||
|
{
|
||||||
|
string path;
|
||||||
|
checkHash(hash);
|
||||||
|
if (queryDB(dbInstPkgs, hash, path)) {
|
||||||
|
int res = system(("rm -rf " + path).c_str()); // !!! escaping
|
||||||
|
delDB(dbInstPkgs, hash); // not a bug
|
||||||
|
if (WEXITSTATUS(res) != 0)
|
||||||
|
throw Error("cannot delete " + path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void exportPkgs(string outDir, vector<string> hashes)
|
||||||
|
{
|
||||||
|
for (vector<string>::iterator it = hashes.begin();
|
||||||
|
it != hashes.end(); it++)
|
||||||
|
{
|
||||||
|
string hash = *it;
|
||||||
|
string pkgDir = getPkg(hash);
|
||||||
|
string tmpFile = outDir + "/export_tmp";
|
||||||
|
|
||||||
|
int res = system(("cd " + pkgDir + " && tar cvfj " + tmpFile + " .").c_str()); // !!! escaping
|
||||||
|
if (WEXITSTATUS(res) != 0)
|
||||||
|
throw Error("cannot tar " + pkgDir);
|
||||||
|
|
||||||
|
string prebuiltHash = hashFile(tmpFile);
|
||||||
|
string pkgId = queryPkgId(hash);
|
||||||
|
string prebuiltFile = outDir + "/" +
|
||||||
|
pkgId + "-" + hash + "-" + prebuiltHash + ".tar.bz2";
|
||||||
|
|
||||||
|
rename(tmpFile.c_str(), prebuiltFile.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void regPrebuilt(string pkgHash, string prebuiltHash)
|
||||||
|
{
|
||||||
|
checkHash(pkgHash);
|
||||||
|
checkHash(prebuiltHash);
|
||||||
|
setDB(dbPrebuilts, pkgHash, prebuiltHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string absPath(string filename)
|
string absPath(string filename)
|
||||||
{
|
{
|
||||||
if (filename[0] != '/') {
|
if (filename[0] != '/') {
|
||||||
|
@ -481,6 +559,7 @@ void initDB()
|
||||||
{
|
{
|
||||||
openDB(dbRefs, false);
|
openDB(dbRefs, false);
|
||||||
openDB(dbInstPkgs, false);
|
openDB(dbInstPkgs, false);
|
||||||
|
openDB(dbPrebuilts, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -543,10 +622,8 @@ void printInfo(vector<string> hashes)
|
||||||
it != hashes.end(); it++)
|
it != hashes.end(); it++)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Params pkgImports, fileImports, arguments;
|
cout << *it << " " << queryPkgId(*it) << endl;
|
||||||
readPkgDescr(*it, pkgImports, fileImports, arguments);
|
} catch (Error & e) { // !!! more specific
|
||||||
cout << *it << " " << getFromEnv(arguments, "id") << endl;
|
|
||||||
} catch (Error & e) {
|
|
||||||
cout << *it << " (descriptor missing)\n";
|
cout << *it << " (descriptor missing)\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -642,12 +719,21 @@ void run(vector<string> args)
|
||||||
if (args.size() != 1) throw argcError;
|
if (args.size() != 1) throw argcError;
|
||||||
string path = getPkg(args[0]);
|
string path = getPkg(args[0]);
|
||||||
cout << path << endl;
|
cout << path << endl;
|
||||||
|
} else if (cmd == "delpkg") {
|
||||||
|
if (args.size() != 1) throw argcError;
|
||||||
|
delPkg(args[0]);
|
||||||
} else if (cmd == "run") {
|
} else if (cmd == "run") {
|
||||||
if (args.size() < 1) throw argcError;
|
if (args.size() < 1) throw argcError;
|
||||||
runPkg(args[0], vector<string>(args.begin() + 1, args.end()));
|
runPkg(args[0], vector<string>(args.begin() + 1, args.end()));
|
||||||
} else if (cmd == "ensure") {
|
} else if (cmd == "ensure") {
|
||||||
if (args.size() != 1) throw argcError;
|
if (args.size() != 1) throw argcError;
|
||||||
ensurePkg(args[0]);
|
ensurePkg(args[0]);
|
||||||
|
} else if (cmd == "export") {
|
||||||
|
if (args.size() < 1) throw argcError;
|
||||||
|
exportPkgs(args[0], vector<string>(args.begin() + 1, args.end()));
|
||||||
|
} else if (cmd == "regprebuilt") {
|
||||||
|
if (args.size() != 2) throw argcError;
|
||||||
|
regPrebuilt(args[0], args[1]);
|
||||||
} else if (cmd == "regfile") {
|
} else if (cmd == "regfile") {
|
||||||
if (args.size() != 1) throw argcError;
|
if (args.size() != 1) throw argcError;
|
||||||
registerFile(args[0]);
|
registerFile(args[0]);
|
||||||
|
@ -688,9 +774,13 @@ Subcommands:
|
||||||
Register an installed package.
|
Register an installed package.
|
||||||
|
|
||||||
getpkg HASH
|
getpkg HASH
|
||||||
Ensure that the package referenced by HASH is installed. Prints
|
Ensure that the package referenced by HASH is installed. Print
|
||||||
out the path of the package on stdout.
|
out the path of the package on stdout.
|
||||||
|
|
||||||
|
delpkg HASH
|
||||||
|
Uninstall the package referenced by HASH, disregarding any
|
||||||
|
dependencies that other packages may have on HASH.
|
||||||
|
|
||||||
listinst
|
listinst
|
||||||
Prints a list of installed packages.
|
Prints a list of installed packages.
|
||||||
|
|
||||||
|
@ -701,6 +791,12 @@ Subcommands:
|
||||||
Like getpkg, but if HASH refers to a run descriptor, fetch only
|
Like getpkg, but if HASH refers to a run descriptor, fetch only
|
||||||
the dependencies.
|
the dependencies.
|
||||||
|
|
||||||
|
export DIR HASH...
|
||||||
|
Export installed packages to DIR.
|
||||||
|
|
||||||
|
regprebuilt HASH1 HASH2
|
||||||
|
Inform Nix that an export HASH2 can be used to fast-build HASH1.
|
||||||
|
|
||||||
info HASH...
|
info HASH...
|
||||||
Print information about the specified descriptors.
|
Print information about the specified descriptors.
|
||||||
|
|
||||||
|
|
|
@ -8,3 +8,5 @@ cd aterm-*
|
||||||
./configure --prefix=$top
|
./configure --prefix=$top
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
|
cd ..
|
||||||
|
rm -rf aterm-*
|
||||||
|
|
|
@ -1,23 +1,19 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
root=/home/eelco/Dev/nix/test
|
mkdir -p $NIX/db
|
||||||
cd $root
|
mkdir -p $NIX/pkg
|
||||||
|
mkdir -p $NIX/descr
|
||||||
mkdir -p db
|
mkdir -p $NIX/netcache
|
||||||
mkdir -p pkg
|
|
||||||
mkdir -p descr
|
|
||||||
mkdir -p netcache
|
|
||||||
|
|
||||||
nix init
|
nix init
|
||||||
|
|
||||||
if ! nix-instantiate descr netcache tmpl/*.nix; then
|
if ! nix-instantiate $NIX/descr $NIX/netcache tmpl/*.nix; then
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for i in netcache/*; do nix regfile $i; done
|
for i in $NIX/netcache/*; do nix regfile $i; done
|
||||||
for i in build/*; do nix regfile $i; done
|
for i in build/*; do nix regfile $i; done
|
||||||
for i in descr/*; do
|
for i in $NIX/descr/*; do
|
||||||
md5sum $i
|
md5sum $i
|
||||||
nix regfile $i
|
nix regfile $i
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue