Codebase list bundlewrap / 052a7a1
New upstream version Jonathan Carter 5 years ago
9 changed file(s) with 61 addition(s) and 57 deletion(s). Raw diff Collapse all Expand all
0 # 3.5.3
1
2 2018-12-27
3
4 * added error message when trying to access node bundles from `members_add/remove`
5 * improved performance for file verification
6 * fixed symlinks being mistaken for directories in some circumstances
7
8
09 # 3.5.2
110
211 2018-12-11
00 # -*- coding: utf-8 -*-
11 from __future__ import unicode_literals
22
3 VERSION = (3, 5, 2)
3 VERSION = (3, 5, 3)
44 VERSION_STRING = ".".join([str(v) for v in VERSION])
240240 if self.attributes['purge']:
241241 paths_to_purge = list(self._get_paths_to_purge())
242242 return {
243 'type': path_info.path_type,
243 'type': 'directory' if path_info.is_directory else path_info.stat['type'],
244244 'mode': path_info.mode,
245245 'owner': path_info.owner,
246246 'group': path_info.group,
334334 return None
335335 else:
336336 return {
337 'type': path_info.path_type,
338 'content_hash': path_info.sha1 if path_info.path_type == 'file' else None,
337 'type': 'file' if path_info.is_file else path_info.stat['type'],
338 'content_hash': path_info.sha1 if path_info.is_file else None,
339339 'mode': path_info.mode,
340340 'owner': path_info.owner,
341341 'group': path_info.group,
347347 'content_hash' in keys and
348348 self.attributes['content_type'] not in ('base64', 'binary') and
349349 sdict['size'] < DIFF_MAX_FILE_SIZE and
350 len(self.content) < DIFF_MAX_FILE_SIZE
350 len(self.content) < DIFF_MAX_FILE_SIZE and
351 PathInfo(self.node, self.name).is_text_file
351352 ):
352353 keys.remove('content_hash')
353354 keys.append('content')
155155 return None
156156 else:
157157 return {
158 'target': path_info.symlink_target if path_info.path_type == 'symlink' else "",
159 'type': path_info.path_type,
158 'target': path_info.symlink_target if path_info.is_symlink else "",
159 'type': 'symlink' if path_info.is_symlink else path_info.stat['type'],
160160 'owner': path_info.owner,
161161 'group': path_info.group,
162162 }
378378
379379 @cached_property
380380 def bundles(self):
381 if self._dynamic_group_lock.acquire(False):
382 self._dynamic_group_lock.release()
383 else:
384 raise RepositoryError(_(
385 "node bundles cannot be queried with members_add/remove"
386 ))
381387 with io.job(_("{node} loading bundles").format(node=bold(self.name))):
382388 added_bundles = []
383389 found_bundles = []
77 from .ui import io
88
99
10 def _parse_file_output(file_output):
11 if file_output.startswith("cannot open "):
12 # required for Mac OS X, OpenBSD, and CentOS/RHEL
13 return ('nonexistent', "")
14 elif file_output.endswith("directory"):
15 return ('directory', file_output)
16 elif file_output.startswith("block special") or \
17 file_output.startswith("character special"):
18 return ('other', file_output)
19 elif file_output.startswith("symbolic link to ") or \
20 file_output.startswith("broken symbolic link to "):
21 return ('symlink', file_output)
22 else:
23 return ('file', file_output)
24
25
26 def get_path_type(node, path):
27 """
28 Returns (TYPE, DESC) where TYPE is one of:
29
30 'directory', 'file', 'nonexistent', 'other', 'symlink'
31
32 and DESC is the output of the 'file' command line utility.
33 """
34 result = node.run("file -bh -- {}".format(quote(path)), may_fail=True)
35 file_output = force_text(result.stdout.strip())
36 if (
37 result.return_code != 0 or
38 "No such file or directory" in file_output # thanks CentOS
39 ):
40 return ('nonexistent', "")
41
42 return _parse_file_output(file_output)
43
44
4510 def stat(node, path):
4611 if node.os in node.OS_FAMILY_BSD:
47 result = node.run("stat -f '%Su:%Sg:%p:%z' -- {}".format(quote(path)))
12 result = node.run(
13 "stat -f '%Su:%Sg:%p:%z:%HT' -- {}".format(quote(path)),
14 may_fail=True,
15 )
4816 else:
49 result = node.run("stat -c '%U:%G:%a:%s' -- {}".format(quote(path)))
50 owner, group, mode, size = force_text(result.stdout).split(":")
17 result = node.run(
18 "stat -c '%U:%G:%a:%s:%F' -- {}".format(quote(path)),
19 may_fail=True,
20 )
21 if result.return_code != 0:
22 return {}
23 owner, group, mode, size, ftype = \
24 force_text(result.stdout).strip().split(":", 5)
5125 mode = mode[-4:].zfill(4) # cut off BSD file type
5226 file_stat = {
5327 'owner': owner,
5428 'group': group,
5529 'mode': mode,
5630 'size': int(size),
31 'type': ftype.lower(),
5732 }
5833 io.debug(_("stat for '{path}' on {node}: {result}".format(
5934 node=node.name,
6742 """
6843 Serves as a proxy to get_path_type.
6944 """
45
7046 def __init__(self, node, path):
7147 self.node = node
7248 self.path = path
73 self.path_type, self.desc = get_path_type(node, path)
74 self.stat = stat(node, path) if self.path_type != 'nonexistent' else {}
49 self.stat = stat(node, path)
7550
7651 def __repr__(self):
7752 return "<PathInfo for {}:{}>".format(self.node.name, quote(self.path))
7853
7954 @property
8055 def exists(self):
81 return self.path_type != 'nonexistent'
56 return bool(self.stat)
8257
8358 @property
8459 def group(self):
9065
9166 @property
9267 def is_directory(self):
93 return self.path_type == 'directory'
68 return self.stat['type'] == "directory"
9469
9570 @property
9671 def is_file(self):
97 return self.path_type == 'file'
72 return self.stat['type'] in ("regular file", "regular empty file")
9873
9974 @property
10075 def is_symlink(self):
101 return self.path_type == 'symlink'
76 return self.stat['type'] == "symbolic link"
10277
10378 @property
10479 def is_text_file(self):
10580 return self.is_file and (
10681 "text" in self.desc or
10782 self.desc in (
108 "empty",
109 "OpenSSH ED25519 public key",
110 "OpenSSH RSA public key",
111 "OpenSSH DSA public key",
112 )
83 "empty",
84 "OpenSSH ED25519 public key",
85 "OpenSSH RSA public key",
86 "OpenSSH DSA public key",
87 )
11388 )
11489
11590 @property
11994 @property
12095 def owner(self):
12196 return self.stat['owner']
97
98 @cached_property
99 def desc(self):
100 return force_text(self.node.run(
101 "file -bh -- {}".format(quote(self.path))
102 ).stdout).strip()
122103
123104 @cached_property
124105 def sha1(self):
0 bundlewrap (3.5.3-1) unstable; urgency=medium
1
2 * New upstream release
3 * Update stanards version to 4.3.0
4
5 -- Jonathan Carter <jcc@debian.org> Fri, 04 Jan 2019 15:56:26 +0200
6
07 bundlewrap (3.5.2-1) unstable; urgency=medium
18
29 * New upstream release
1616
1717 setup(
1818 name="bundlewrap",
19 version="3.5.2",
19 version="3.5.3",
2020 description="Config management with Python",
2121 long_description=(
2222 "By allowing for easy and low-overhead config management, BundleWrap fills the gap between complex deployments using Chef or Puppet and old school system administration over SSH.\n"