~gandelman-a/juju-deployer/darwin_redux

« back to all changes in this revision

Viewing changes to juju_deployer/charm.py

  • Committer: Adam Gandelman
  • Date: 2013-07-10 00:05:11 UTC
  • Revision ID: adamg@canonical.com-20130710000511-b86ud2mlgtsscnfy
Create juju_deployer module, stuff all classes and utils there.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import logging
 
2
import os
 
3
 
 
4
from os.path import join as path_join
 
5
from os.path import exists as path_exists
 
6
 
 
7
from juju_deployer import utils
 
8
 
 
9
from juju_deployer.vcs import Bzr, Git
 
10
 
 
11
 
 
12
class Charm(object):
 
13
 
 
14
    log = logging.getLogger('deployer.charm')
 
15
 
 
16
    def __init__(self, name, path, branch, rev, build, charm_url=""):
 
17
        self.name = name
 
18
        self.path = path
 
19
        self.branch = branch
 
20
        self.rev = rev
 
21
        self._charm_url = charm_url
 
22
        self._build = build
 
23
        self.vcs = self.get_vcs()
 
24
 
 
25
    def get_vcs(self):
 
26
        if not self.branch:
 
27
            return None
 
28
        if self.branch.startswith('git') or 'github.com' in self.branch:
 
29
            return Git(self.path, self.branch, self.log)
 
30
        elif self.branch.startswith("bzr") or self.branch.startswith('lp:'):
 
31
            return Bzr(self.path, self.branch, self.log)
 
32
 
 
33
    @classmethod
 
34
    def from_service(cls, name, series_path, d):
 
35
        branch, rev = None, None
 
36
        charm_branch = d.get('branch')
 
37
        if charm_branch is not None:
 
38
            branch, sep, rev = charm_branch.partition('@')
 
39
        name = d.get('charm', name)
 
40
        charm_path = path_join(series_path, name)
 
41
        build = d.get('build', '')
 
42
        store_url = d.get('charm_url', None)
 
43
 
 
44
        if store_url and branch:
 
45
            cls.log.error(
 
46
                "Service: %s has both charm url: %s and branch: %s specified",
 
47
                name, store_url, branch)
 
48
        return cls(name, charm_path, branch, rev, build, store_url)
 
49
 
 
50
    def exists(self):
 
51
        return path_exists(self.path)
 
52
 
 
53
    def is_subordinate(self):
 
54
        return self.metadata.get('subordinate', False)
 
55
 
 
56
    @property
 
57
    def charm_url(self):
 
58
        if self._charm_url:
 
59
            return self._charm_url
 
60
        series = os.path.basename(os.path.dirname(self.path))
 
61
        return "local:%s/%s" % (series, self.name)
 
62
 
 
63
    def build(self):
 
64
        #if self.charm_url.startswith('cs:'):
 
65
        #    shutil.copy(urllib.urlopen(CHARM_DL_URL % self.charm_url))
 
66
        if not self._build:
 
67
            return
 
68
        self.log.debug("Building charm %s with %s", self.path, self._build)
 
69
        _check_call([self._build], self.path, self.log,
 
70
                    "Charm build failed %s @ %s", self._build, self.path)
 
71
 
 
72
    def fetch(self):
 
73
        if not self.branch:
 
74
            return
 
75
        self.log.debug(" Branching charm %s @ %s", self.branch, self.path)
 
76
        self.vcs.branch()
 
77
        self.build()
 
78
 
 
79
    def update(self, build=False):
 
80
        if not self.branch:
 
81
            return
 
82
        assert self.exists()
 
83
        self.log.debug(" Updating charm %s from %s", self.path, self.branch)
 
84
        self.vcs.update(self.rev)
 
85
        if build:
 
86
            self.build()
 
87
 
 
88
    def is_modified(self):
 
89
        if not self.branch:
 
90
            return False
 
91
        return self.vcs.is_modified()
 
92
 
 
93
    @property
 
94
    def config(self):
 
95
        config_path = path_join(self.path, "config.yaml")
 
96
        if not path_exists(config_path):
 
97
            return {}
 
98
 
 
99
        with open(config_path) as fh:
 
100
            return utils.yaml_load(fh.read()).get('options', {})
 
101
 
 
102
    @property
 
103
    def metadata(self):
 
104
        md_path = path_join(self.path, "metadata.yaml")
 
105
        if not path_exists(md_path):
 
106
            if not path_exists(self.path):
 
107
                raise RuntimeError("No charm metadata @ %s", md_path)
 
108
        with open(md_path) as fh:
 
109
            return utils.yaml_load(fh.read())
 
110
 
 
111
    def get_provides(self):
 
112
        p = {'juju-info': [{'name': 'juju-info'}]}
 
113
        for key, value in self.metadata['provides'].items():
 
114
            value['name'] = key
 
115
            p.setdefault(value['interface'], []).append(value)
 
116
        return p
 
117
 
 
118
    def get_requires(self):
 
119
        r = {}
 
120
        for key, value in self.metadata['requires'].items():
 
121
            value['name'] = key
 
122
            r.setdefault(value['interface'], []).append(value)
 
123
        return r