def _safe_create(self, rsrc_id, path, data): """Create ephemeral node in Zookeeper. If the node is present, check if the owner session id is ours, if not, fail. """ try: zkutils.create(self.zkclient, path, data, ephemeral=True) _LOGGER.info('Created node: %s', path) except kazoo.client.NodeExistsError: content, metadata = zkutils.get_with_metadata(self.zkclient, path) session_id, _pwd = self.zkclient.client_id if metadata.owner_session_id != session_id: _LOGGER.info('Node exists, owned by other: %s - %s - %s', path, content, metadata.owner_session_id) self._watch(rsrc_id, path) return False if content != data: _LOGGER.info('Content different: %s - old: %s, new: %s', path, content, data) zkutils.update(self.zkclient, path, data) _LOGGER.info('Node is up to date: %s - %s', path, session_id) return True
def _safe_delete(self, path): """Safely delete node, checking that it is owned by the service.""" try: _content, metadata = zkutils.get_with_metadata(self.zkclient, path) session_id, _pwd = self.zkclient.client_id if metadata.owner_session_id == session_id: _LOGGER.info('Delete node: %s', path) zkutils.ensure_deleted(self.zkclient, path) else: _LOGGER.info('Node exists, owned by other: %s - %s', path, metadata.owner_session_id) except kazoo.client.NoNodeError: _LOGGER.info('Node does not exist: %s', path)
def _cache(self, zkclient, app, check_existing=False): """Read the manifest and placement data from Zk and store it as YAML in <cache>/<app>. :param ``str`` app: Instance name. :param ``bool`` check_existing: Whether to check if the file already exists and is up to date. """ placement_node = z.path.placement(self._hostname, app) try: placement_data, placement_metadata = zkutils.get_with_metadata( zkclient, placement_node ) placement_time = placement_metadata.ctime / 1000.0 except kazoo.exceptions.NoNodeError: _LOGGER.info('Placement %s/%s not found', self._hostname, app) return manifest_file = os.path.join(self.tm_env.cache_dir, app) if check_existing: try: manifest_time = os.stat(manifest_file).st_ctime except FileNotFoundError: manifest_time = None if manifest_time and manifest_time >= placement_time: _LOGGER.info('%s is up to date', manifest_file) return app_node = z.path.scheduled(app) try: manifest = zkutils.get(zkclient, app_node) # TODO: need a function to parse instance id from name. manifest['task'] = app[app.index('#') + 1:] if placement_data is not None: manifest.update(placement_data) fs.write_safe( manifest_file, lambda f: yaml.dump(manifest, stream=f), prefix='.%s-' % app, mode='w', permission=0o644 ) _LOGGER.info('Created cache manifest: %s', manifest_file) except kazoo.exceptions.NoNodeError: _LOGGER.info('App %s not found', app)
def _list_server_blackouts(zkclient, fmt): """List server blackouts.""" # List currently blacked out nodes. blacked_out = [] try: blacked_out_nodes = zkclient.get_children(z.BLACKEDOUT_SERVERS) for server in blacked_out_nodes: node_path = z.path.blackedout_server(server) data, metadata = zkutils.get_with_metadata(zkclient, node_path) blacked_out.append((metadata.created, server, data)) except kazoo.client.NoNodeError: pass # [%t] %h %r will be printed as below # [Thu, 05 May 2016 02:59:58 +0000] <hostname> - mapping = {'t': 0, 'h': 1, 'r': 2} formatter = _gen_formatter(mapping, fmt) for when, server, reason in reversed(sorted(blacked_out)): reason = '-' if reason is None else reason print(formatter.format(utils.strftime_utc(when), server, reason))
def _list_server_blackouts(zkclient, fmt): """List server blackouts.""" with_partition = '%p' in fmt with_version = '%v' in fmt blackouts = [] for node in zkclient.get_children(z.BLACKEDOUT_SERVERS): try: node_path = z.path.blackedout_server(node) data, metadata = zkutils.get_with_metadata(zkclient, node_path) except kazoo.client.NoNodeError: continue partition, version = None, None if with_partition: server_data = zkutils.get_default(zkclient, z.path.server(node)) if server_data and server_data.get('partition'): partition = server_data['partition'] if with_version: version_data = zkutils.get_default(zkclient, z.path.version(node)) if version_data and version_data.get('codepath'): version = version_data['codepath'] blackouts.append((metadata.created, node, partition, version, data)) # [%t] %h %r will be printed as below # [Thu, 05 May 2016 02:59:58 +0000] <hostname> - fields = ('t', 'h', 'p', 'v', 'r') formatter = _gen_formatter(fields, fmt) for when, node, partition, version, reason in reversed(sorted(blackouts)): cli.out( formatter.format(utils.strftime_utc(when), node, partition or '-', version or '-', reason or '-'))
def get_with_metadata(self, path): """Return stored object with metadata.""" try: return zkutils.get_with_metadata(self.zkclient, path) except kazoo.client.NoNodeError: raise backend.ObjectNotFoundError()