LEFT | RIGHT |
(no file at all) | |
1 import os | 1 import os |
2 import stat | 2 import stat |
3 import zipfile | 3 import zipfile |
4 import tempfile | 4 import tempfile |
5 | 5 |
6 from juju.charm.base import CharmBase, get_revision, ZIP_SYMLINK_ATTR | 6 from juju.charm.base import CharmBase, get_revision |
7 from juju.charm.bundle import CharmBundle | 7 from juju.charm.bundle import CharmBundle |
8 from juju.charm.config import ConfigOptions | 8 from juju.charm.config import ConfigOptions |
9 from juju.charm.errors import InvalidCharmFile | 9 from juju.charm.errors import InvalidCharmFile |
10 from juju.charm.metadata import MetaData | 10 from juju.charm.metadata import MetaData |
11 | 11 |
12 | 12 |
13 class CharmDirectory(CharmBase): | 13 class CharmDirectory(CharmBase): |
14 """Directory that holds charm content. | 14 """Directory that holds charm content. |
15 | 15 |
16 :param path: Path to charm directory | 16 :param path: Path to charm directory |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 link_path = os.path.join(path_dir, link_path) | 98 link_path = os.path.join(path_dir, link_path) |
99 if not link_path.startswith(os.path.abspath(self.path)): | 99 if not link_path.startswith(os.path.abspath(self.path)): |
100 raise InvalidCharmFile( | 100 raise InvalidCharmFile( |
101 self.metadata.name, path, "Only internal symlinks are allowed") | 101 self.metadata.name, path, "Only internal symlinks are allowed") |
102 | 102 |
103 def _write_symlink(self, zf, link_target, link_path): | 103 def _write_symlink(self, zf, link_target, link_path): |
104 """Package symlinks with appropriate zipfile metadata.""" | 104 """Package symlinks with appropriate zipfile metadata.""" |
105 info = zipfile.ZipInfo() | 105 info = zipfile.ZipInfo() |
106 info.filename = link_path | 106 info.filename = link_path |
107 info.create_system = 3 | 107 info.create_system = 3 |
108 info.external_attr = ZIP_SYMLINK_ATTR | 108 # Preserve the pre-existing voodoo mode in a slightly clearer form. |
| 109 info.external_attr = (stat.S_IFLNK | 0755) << 16 |
109 zf.writestr(info, link_target) | 110 zf.writestr(info, link_target) |
110 | 111 |
111 def _ignore(self, path): | 112 def _ignore(self, path): |
112 if path == "build" or path.startswith("build/"): | 113 if path == "build" or path.startswith("build/"): |
113 return True | 114 return True |
114 if path.startswith('.'): | 115 if path.startswith('.'): |
115 return True | 116 return True |
116 | 117 |
117 def as_bundle(self): | 118 def as_bundle(self): |
118 if self._temp_bundle is None: | 119 if self._temp_bundle is None: |
119 prefix = "%s-%d.charm." % (self.metadata.name, self.get_revision()) | 120 prefix = "%s-%d.charm." % (self.metadata.name, self.get_revision()) |
120 temp_file = tempfile.NamedTemporaryFile(prefix=prefix) | 121 temp_file = tempfile.NamedTemporaryFile(prefix=prefix) |
121 self.make_archive(temp_file.name) | 122 self.make_archive(temp_file.name) |
122 self._temp_bundle = CharmBundle(temp_file.name) | 123 self._temp_bundle = CharmBundle(temp_file.name) |
123 # Attach the life time of temp_file to self: | 124 # Attach the life time of temp_file to self: |
124 self._temp_bundle_file = temp_file | 125 self._temp_bundle_file = temp_file |
125 return self._temp_bundle | 126 return self._temp_bundle |
126 | 127 |
127 def as_directory(self): | 128 def as_directory(self): |
128 return self | 129 return self |
129 | 130 |
130 def compute_sha256(self): | 131 def compute_sha256(self): |
131 """ | 132 """ |
132 Compute sha256, based on the bundle. | 133 Compute sha256, based on the bundle. |
133 """ | 134 """ |
134 return self.as_bundle().compute_sha256() | 135 return self.as_bundle().compute_sha256() |
LEFT | RIGHT |