summaryrefslogtreecommitdiff
path: root/lib/thandy/packagesys/ThpPackages.py
blob: 3ca9d52c2a1afa6028eeb048b53a8e1e176bc1a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# Copyright 2011 The Tor Project, Inc.  See LICENSE for licensing information.

import logging
import os
import zipfile
import tempfile
import time

from lockfile import LockFile

import thandy.util
import thandy.formats
import thandy.packagesys.PackageSystem as PS
import thandy.packagesys.PackageDB as PDB

json = thandy.util.importJSON()

class ThpDB(object):
    def __init__(self):
        self._thp_db_root = os.environ.get("THP_DB_ROOT")
        if self._thp_db_root is None:
          raise Exception("There is no THP_DB_ROOT variable set")

    def insert(self, pkg):
        thandy.util.replaceFile(os.path.join(self._thp_db_root, "pkg-status",
                                             pkg['package_name'])+".json",
                                json.dumps(pkg))

    def delete(self, pkg):
        try:
          os.unlink(os.path.join(self._thp_db_root, "pkg-status",
                                 pkg['package_name'])+".json")
        except Exception as e:
          print e

    def update(self, pkg):
        self.insert(pkg)

    def exists(self, name):
        fname = os.path.join(self._thp_db_root, "pkg-status", name+".json")
        fexists = os.path.exists(fname)

        version = -1
        if fexists:
            contents = open(fname, "r").read()
            metadata = json.loads(contents)
            version = metadata['package_version']
        return fexists, version

    def statusInProgress(self, pkg):
        thandy.util.replaceFile(os.path.join(self._thp_db_root, "pkg-status",
                                             pkg['package_name']+".status"),
                                json.dumps({ "status" : "IN-PROGRESS" }))

    def statusInstalled(self, pkg):
        thandy.util.replaceFile(os.path.join(self._thp_db_root, "pkg-status",
                                             pkg['package_name']+".status"),
                                json.dumps({ "status" : "INSTALLED" }))

class ThpChecker(PS.Checker):
    def __init__(self, name, version):
        PS.Checker.__init__(self)
        self._name = name
        self._version = version
        self._db = ThpDB()

    def __repr__(self):
        return "ThpChecker(%r, %r)"%(self._name, self._version)

    def getInstalledVersions(self):
        versions = []
        (exists, version) = self._db.exists(self._name)

        if exists:
            versions.append(version)

        return versions

    def isInstalled(self):
        return self._version in self.getInstalledVersions()

class ThpInstaller(PS.Installer):
    def __init__(self, relPath):
        PS.Installer.__init__(self, relPath)
        self._db = ThpDB()

    def __repr__(self):
        return "ThpInstaller(%r)" %(self._relPath)

    def install(self):
        print "Running thp installer", self._cacheRoot, self._relPath
        self._thp_root = os.environ.get("THP_INSTALL_ROOT")
        if self._thp_root is None:
          raise Exception("There is no THP_INSTALL_ROOT variable set")

        lockfile = os.path.join(self._thp_db_root, ".lock")
        lock = LockFile(lockfile)
        try:
            lock.acquire()
            pkg = ThpPackage(os.path.join(self._cacheRoot, self._relPath[1:]))
            shutil.copytree()
        except AlreadyLocked:
            print "You can't run more than one instance of Thandy"
        except LockFailed:
            print "Can't acquire lock on %s" % lockfile
#        self._db.insert(pkg.getAll())
#        self._db.statusInstalled(pkg.getAll())
#        self._db.delete(pkg.getAll())
#        print self._db.exists(pkg.get("package_name"))


    def remove(self):
        print "Running thp remover"

class ThpPackage(object):
    def __init__(self, thp_path):
        self._thp_path = thp_path
        self._metadata = None
        self._valid = False

        self._process()

    def __repr__(self):
        print "ThpPackage(%s)" % self._thp_path

    def _process(self):
        tmpPath = tempfile.mkdtemp(suffix=str(time.time()),
                                  prefix="thp")

        thpFile = zipfile.ZipFile(self._thp_path)
        thpFile.extractall(tmpPath)
        contents = open(os.path.join(tmpPath, "meta", "package.json")).read()
        self._metadata = json.loads(contents)
        print self._validateFiles(tmpPath)

        thandy.util.deltree(tmpPath)

    def get(self, key):
        if self._metadata:
          return self._metadata.get(key)

    def getAll(self):
        return self._metadata

    def isValid(self):
        return self._valid

    def _validateFiles(self, tmpPath):
        for manifest in self._metadata['manifest']:
            name = manifest['name']
            digest = manifest['digest']
            is_config = manifest['is_config']
            f = open(os.path.join(tmpPath, "content", name), "rb")
            newdigest = thandy.formats.formatHash(thandy.formats.getFileDigest(f))
            f.close()
            if newdigest != digest:
                return (False, [name, digest, newdigest])