pactest: create packages in memory

This is similar to what was just done for the sync databases. Move a few
pieces around so we never need to actually write out the filesystem to
create a package, and simply stream the tarfile out from the data we've
collected.

Once again, a few newline addition hacks and other things have to be
left in place in order not to break everything; this time however most
of the assumptions are in pactest and not libalpm.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2011-06-23 21:35:32 -05:00
parent 13235ba65a
commit 0ed848a9ea
4 changed files with 89 additions and 60 deletions

View File

@ -229,8 +229,7 @@ def generate(self):
path = os.path.join(self.dbdir, pkg.fullname()) path = os.path.join(self.dbdir, pkg.fullname())
util.mkdir(path) util.mkdir(path)
for name, data in entry.iteritems(): for name, data in entry.iteritems():
filename = os.path.join(path, name) util.mkfile(path, name, data)
util.mkfile(filename, data)
if self.dbfile: if self.dbfile:
tar = tarfile.open(self.dbfile, "w:gz") tar = tarfile.open(self.dbfile, "w:gz")

View File

@ -20,6 +20,7 @@
import tempfile import tempfile
import stat import stat
import shutil import shutil
from StringIO import StringIO
import tarfile import tarfile
import util import util
@ -66,6 +67,7 @@ def __init__(self, name, version = "1.0-1"):
"pre_upgrade": "", "pre_upgrade": "",
"post_upgrade": "", "post_upgrade": "",
} }
self.path = None
def __str__(self): def __str__(self):
s = ["%s" % self.fullname()] s = ["%s" % self.fullname()]
@ -106,16 +108,7 @@ def makepkg(self, path):
A package archive is generated in the location 'path', based on the data A package archive is generated in the location 'path', based on the data
from the object. from the object.
""" """
self.path = os.path.join(path, self.filename()) archive_files = []
curdir = os.getcwd()
tmpdir = tempfile.mkdtemp()
os.chdir(tmpdir)
# Generate package file system
for f in self.files:
util.mkfile(f, f)
self.size += os.lstat(self.parse_filename(f))[stat.ST_SIZE]
# .PKGINFO # .PKGINFO
data = ["pkgname = %s" % self.name] data = ["pkgname = %s" % self.name]
@ -143,23 +136,51 @@ def makepkg(self, path):
data.append("provides = %s" % i) data.append("provides = %s" % i)
for i in self.backup: for i in self.backup:
data.append("backup = %s" % i) data.append("backup = %s" % i)
util.mkfile(".PKGINFO", "\n".join(data)) data.append("\n")
archive_files.append((".PKGINFO", "\n".join(data)))
# .INSTALL # .INSTALL
if any(self.install.values()): if any(self.install.values()):
util.mkfile(".INSTALL", self.installfile()) archive_files.append((".INSTALL", self.installfile()))
# safely create the dir self.path = os.path.join(path, self.filename())
util.mkdir(os.path.dirname(self.path)) util.mkdir(os.path.dirname(self.path))
# Generate package archive # Generate package metadata
tar = tarfile.open(self.path, "w:gz") tar = tarfile.open(self.path, "w:gz")
for i in os.listdir("."): for name, data in archive_files:
tar.add(i) info = tarfile.TarInfo(name)
info.size = len(data)
tar.addfile(info, StringIO(data))
# Generate package file system
for name in self.files:
fileinfo = util.getfileinfo(name)
info = tarfile.TarInfo(fileinfo["filename"])
if fileinfo["hasperms"]:
info.mode = fileinfo["perms"]
if fileinfo["isdir"]:
info.type = tarfile.DIRTYPE
tar.addfile(info)
elif fileinfo["islink"]:
info.type = tarfile.SYMTYPE
info.linkname = fileinfo["link"]
tar.addfile(info)
else:
# TODO wow what a hack, adding a newline to match mkfile?
filedata = name + "\n"
info.size = len(filedata)
tar.addfile(info, StringIO(filedata))
tar.close() tar.close()
os.chdir(curdir) def install_package(self, root):
shutil.rmtree(tmpdir) """Install the package in the given root."""
for f in self.files:
util.mkfile(root, f, f)
path = os.path.join(root, f)
if os.path.isfile(path):
os.utime(path, (355, 355))
def full_filelist(self): def full_filelist(self):
"""Generate a list of package files. """Generate a list of package files.

View File

@ -156,16 +156,11 @@ def generate(self):
vprint(" Populating file system") vprint(" Populating file system")
for pkg in self.db["local"].pkgs: for pkg in self.db["local"].pkgs:
vprint("\tinstalling %s" % pkg.fullname()) vprint("\tinstalling %s" % pkg.fullname())
for f in pkg.files: pkg.install_package(self.root)
vprint("\t%s" % f)
path = os.path.join(self.root, f)
util.mkfile(path, f)
if os.path.isfile(path):
os.utime(path, (355, 355))
for f in self.filesystem: for f in self.filesystem:
vprint("\t%s" % f) vprint("\t%s" % f)
util.mkfile(self.root, f, f)
path = os.path.join(self.root, f) path = os.path.join(self.root, f)
util.mkfile(path, f)
if os.path.isfile(path): if os.path.isfile(path):
os.utime(path, (355, 355)) os.utime(path, (355, 355))

View File

@ -47,49 +47,63 @@ def vprint(msg):
# Methods to generate files # Methods to generate files
# #
def mkfile(name, data = ""): def getfileinfo(filename):
isdir = 0 data = {
islink = 0 'changed': False,
setperms = 0 'isdir': False,
filename = name 'islink': False,
link = "" 'link': None,
perms = "" 'hasperms': False,
'perms': None,
}
if filename[-1] == "*": if filename[-1] == "*":
data["changed"] = True
filename = filename.rstrip("*") filename = filename.rstrip("*")
if filename.find(" -> ") != -1: if filename.find(" -> ") != -1:
islink = 1
filename, link = filename.split(" -> ") filename, link = filename.split(" -> ")
data["islink"] = True
data["link"] = link
elif filename.find("|") != -1: elif filename.find("|") != -1:
setperms = 1
filename, perms = filename.split("|") filename, perms = filename.split("|")
data["hasperms"] = True
data["perms"] = int(perms, 8)
if filename[-1] == "/": if filename[-1] == "/":
isdir = 1 data["isdir"] = True
if isdir: data["filename"] = filename
path = filename return data
else:
path = os.path.dirname(filename)
if path and not os.path.isdir(path):
os.makedirs(path, 0755)
if isdir: def mkfile(base, name, data=""):
info = getfileinfo(name)
filename = info["filename"]
path = os.path.join(base, filename)
if info["isdir"]:
if not os.path.isdir(path):
os.makedirs(path, 0755)
return return
if islink:
curdir = os.getcwd() dir_path = os.path.dirname(path)
if path: if dir_path and not os.path.isdir(dir_path):
os.chdir(path) os.makedirs(dir_path, 0755)
os.symlink(link, os.path.basename(filename))
os.chdir(curdir) if info["islink"]:
os.symlink(info["link"], path)
else: else:
fd = file(filename, "w") writedata(path, data)
if data:
fd.write(data) if info["perms"]:
if data[-1] != "\n": os.chmod(path, info["perms"])
fd.write("\n")
fd.close() def writedata(filename, data):
if setperms: if isinstance(data, list):
os.chmod(filename, int(perms, 8)) data = "\n".join(data)
fd = file(filename, "w")
if data:
fd.write(data)
if data[-1] != "\n":
fd.write("\n")
fd.close()
def mkcfgfile(filename, root, option, db): def mkcfgfile(filename, root, option, db):
# Options # Options
@ -111,7 +125,7 @@ def mkcfgfile(filename, root, option, db):
for optkey, optval in value.option.iteritems(): for optkey, optval in value.option.iteritems():
data.extend(["%s = %s" % (optkey, j) for j in optval]) data.extend(["%s = %s" % (optkey, j) for j in optval])
mkfile(os.path.join(root, filename), "\n".join(data)) mkfile(root, filename, "\n".join(data))
# #