* Importing and exporting of pre-built packages.

This commit is contained in:
Eelco Dolstra 2003-04-02 15:34:05 +00:00
parent 383f9bb0f1
commit 5bc26fb73f
3 changed files with 115 additions and 21 deletions

View file

@ -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.

View file

@ -8,3 +8,5 @@ cd aterm-*
./configure --prefix=$top ./configure --prefix=$top
make make
make install make install
cd ..
rm -rf aterm-*

View file

@ -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