* 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 dbInstPkgs = "pkginst";
static string dbPrebuilts = "prebuilts";
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)
{
string pkgfile;
@ -321,8 +330,10 @@ void installPkg(string hash)
builder = getFromEnv(env, "build");
string id = getFromEnv(env, "id");
/* Construct a path for the installed package. */
path = pkgHome + "/" + hash;
path = pkgHome + "/" + id + "-" + hash;
/* Create the path. */
if (mkdir(path.c_str(), 0777))
@ -341,10 +352,33 @@ void installPkg(string hash)
/* Go to the build directory. */
if (chdir(path.c_str())) {
cout << "unable to chdir to package directory\n";
cerr << "unable to chdir to package directory\n";
_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
strings, since we'll exec or die soon anyway. */
const char * env2[env.size() + 1];
@ -357,9 +391,9 @@ void installPkg(string hash)
/* Execute the builder. This should not return. */
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); }
}
@ -427,7 +461,7 @@ void runPkg(string hash, const vector<string> & args)
/* Execute the runner. This should not return. */
execv(runner.c_str(), (char * *) args2);
cout << strerror(errno) << endl;
cerr << strerror(errno) << endl;
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)
{
if (filename[0] != '/') {
@ -481,6 +559,7 @@ void initDB()
{
openDB(dbRefs, false);
openDB(dbInstPkgs, false);
openDB(dbPrebuilts, false);
}
@ -543,10 +622,8 @@ void printInfo(vector<string> hashes)
it != hashes.end(); it++)
{
try {
Params pkgImports, fileImports, arguments;
readPkgDescr(*it, pkgImports, fileImports, arguments);
cout << *it << " " << getFromEnv(arguments, "id") << endl;
} catch (Error & e) {
cout << *it << " " << queryPkgId(*it) << endl;
} catch (Error & e) { // !!! more specific
cout << *it << " (descriptor missing)\n";
}
}
@ -642,12 +719,21 @@ void run(vector<string> args)
if (args.size() != 1) throw argcError;
string path = getPkg(args[0]);
cout << path << endl;
} else if (cmd == "delpkg") {
if (args.size() != 1) throw argcError;
delPkg(args[0]);
} else if (cmd == "run") {
if (args.size() < 1) throw argcError;
runPkg(args[0], vector<string>(args.begin() + 1, args.end()));
} else if (cmd == "ensure") {
if (args.size() != 1) throw argcError;
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") {
if (args.size() != 1) throw argcError;
registerFile(args[0]);
@ -688,9 +774,13 @@ Subcommands:
Register an installed package.
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.
delpkg HASH
Uninstall the package referenced by HASH, disregarding any
dependencies that other packages may have on HASH.
listinst
Prints a list of installed packages.
@ -701,6 +791,12 @@ Subcommands:
Like getpkg, but if HASH refers to a run descriptor, fetch only
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...
Print information about the specified descriptors.

View File

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

View File

@ -1,23 +1,19 @@
#! /bin/sh
root=/home/eelco/Dev/nix/test
cd $root
mkdir -p db
mkdir -p pkg
mkdir -p descr
mkdir -p netcache
mkdir -p $NIX/db
mkdir -p $NIX/pkg
mkdir -p $NIX/descr
mkdir -p $NIX/netcache
nix init
if ! nix-instantiate descr netcache tmpl/*.nix; then
if ! nix-instantiate $NIX/descr $NIX/netcache tmpl/*.nix; then
exit 1;
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 descr/*; do
for i in $NIX/descr/*; do
md5sum $i
nix regfile $i
done