Пример #1
0
 def install(self, cfgfile, postrun, timeout, **kwargs):
     """create database intance"""
     if not os.path.exists(cfgfile):
         raise ValueError('Config file not exist')
     args = [SH, MYSQLINSTALL, '--defaults-file=%s' % cfgfile]
     args.extend(self.base_opts)
     replication = kwargs.pop('replication', None)
     auth = kwargs.pop('auth')
     logfile = kwargs.get('logfile')
     if not systemutils.POSIX:
         # just for test on windows
         LOG.info('will call %s', ' '.join(args))
     else:
         with goperation.tlock('gopdb-install', 30):
             pid = safe_fork()
             if pid == 0:
                 os.closerange(3, systemutils.MAXFD)
                 logfile = logfile or os.devnull
                 with open(logfile, 'wb') as f:
                     os.dup2(f.fileno(), 1)
                     os.dup2(f.fileno(), 2)
                 try:
                     os.execv(SH, args)
                 except OSError:
                     os._exit(1)
             else:
                 try:
                     wait(pid, timeout)
                 except:
                     raise
                 finally:
                     LOG.info('%s has been exit' % MYSQLINSTALL)
     eventlet.sleep(0)
     self.start(cfgfile)
     eventlet.sleep(3)
     binlog = self._init_passwd(cfgfile, auth, replication)
     if postrun:
         postrun(binlog)
Пример #2
0
def map_resources(resource_ids):
    # 删除过期缓存
    CDNRESOURCE.expire()

    need = set(resource_ids)
    provides = set(CDNRESOURCE.keys())
    notmiss = need & provides

    # 有资源在进程缓存字典中
    if notmiss:
        caches_time_dict = {}
        # 本地最旧缓存时间点
        time_point = int(time.time())
        for resource_id in notmiss:
            # 获取单个资源本地缓存时间点
            cache_on = int(CDNRESOURCE.expiretime(resource_id)) - cdncommon.CACHETIME
            if cache_on < time_point:
                time_point = cache_on
            caches_time_dict[resource_id] = cache_on
        cache = get_cache()
        scores = cache.zrangebyscore(name=cdncommon.CACHESETNAME,
                                     min=str(time_point - 3), max='+inf',
                                     withscores=True, score_cast_func=int)
        if scores:
            for data in scores:
                resource_id = int(data[0])
                cache_on = int(data[1])
                # redis中缓存时间点超过本地缓存时间点
                # 弹出本地缓存
                try:
                    # 保险做法本地缓存时间回退3秒
                    if cache_on > caches_time_dict[resource_id] - 3:
                        CDNRESOURCE.pop(resource_id, None)
                except KeyError:
                    continue
        caches_time_dict.clear()
    # 没有本地缓存的资源数量
    missed = need - set(CDNRESOURCE.keys())
    if missed:
        # 重新从数据库读取
        with goperation.tlock('gogamechen1-cdnresource'):
            resources = cdnresource_controller.list(resource_ids=missed,
                                                    versions=True, domains=True, metadatas=True)
            for resource in resources:
                resource_id = resource.get('resource_id')
                agent_id = resource.get('agent_id')
                port = resource.get('port')
                internal = resource.get('internal')
                name = resource.get('name')
                etype = resource.get('etype')
                domains = resource.get('domains')
                versions = resource.get('versions')
                metadata = resource.get('metadata')
                if internal:
                    if not metadata:
                        raise ValueError('Agent %d not online, get domain entity fail' % agent_id)
                    hostnames = [metadata.get('local_ip')]
                else:
                    if not domains:
                        if not metadata:
                            raise ValueError('Agent %d not online get domain entity fail' % agent_id)
                        if metadata.get('external_ips'):
                            hostnames = metadata.get('external_ips')
                        else:
                            hostnames = [metadata.get('local_ip')]
                    else:
                        hostnames = domains
                schema = 'http'
                if port == 443:
                    schema = 'https'
                netlocs = []
                for host in hostnames:
                    if port in (80, 443):
                        netloc = '%s://%s' % (schema, host)
                    else:
                        netloc = '%s://%s:%d' % (schema, host, port)
                    netlocs.append(netloc)
                CDNRESOURCE.setdefault(resource_id, dict(name=name, etype=etype, agent_id=agent_id,
                                                         internal=internal, versions=versions,
                                                         netlocs=netlocs, port=port,
                                                         domains=domains))
Пример #3
0
    def upload(self, user, group, ipaddr, port, rootpath, fileinfo, logfile,
               timeout):
        jsonutils.schema_validate(fileinfo, FILEINFOSCHEMA)
        if timeout:
            timeout = int(timeout)
        if timeout > 7200:
            raise ValueError('Timeout over 7200 seconds')
        with goperation.tlock(self.executer):
            logfile = logfile or os.devnull
            executable = systemutils.find_executable(self.executer)
            token = str(uuidutils.generate_uuid()).replace('-', '')
            args = [
                executable, '--home', rootpath, '--token', token, '--port',
                str(port)
            ]

            ext = fileinfo.get('ext') or os.path.splitext(
                fileinfo.get('filename'))[1][1:]
            if ext.startswith('.'):
                ext = ext[1:]
            if not ext:
                raise exceptions.PreWebSocketError('ext is empty')

            filename = '%s.%s' % (fileinfo.get('md5'), ext)
            self.output = os.path.join(rootpath, filename)
            # 判断文件是否存在
            if os.path.exists(self.output):
                raise exceptions.PreWebSocketError('file exist with same name')
            self.size = fileinfo.get('size')
            # 准备文件目录
            path = os.path.dirname(self.output)
            if not os.path.exists(path):
                os.makedirs(path, mode=0o775)
                if user or group:
                    os.chown(path, user, group)
            else:
                if not os.path.isdir(path):
                    raise exceptions.PreWebSocketError(
                        'prefix path is not dir')

            if not ext or ext == 'tmp':
                raise exceptions.PreWebSocketError(
                    'Can not find file ext or ext is tmp')
            # 临时文件名
            self.tmp = os.path.join(
                rootpath,
                '%s.tmp' % str(uuidutils.generate_uuid()).replace('-', ''))
            args.extend(['--outfile', self.tmp])
            args.extend(['--md5', fileinfo.get('md5')])
            args.extend(['--size', str(fileinfo.get('size'))])
            args.extend(['--log-file', logfile])
            args.extend(['--loglevel', 'info'])

            changeuser = functools.partial(systemutils.drop_privileges, user,
                                           group)

            with open(os.devnull, 'wb') as f:
                LOG.debug('Websocket command %s %s' %
                          (executable, ' '.join(args)))
                if systemutils.WINDOWS:
                    sub = subprocess.Popen(executable=executable,
                                           args=args,
                                           stdout=f.fileno(),
                                           stderr=f.fileno(),
                                           close_fds=True,
                                           preexec_fn=changeuser)
                    pid = sub.pid
                else:
                    pid = safe_fork(user=user, group=group)
                    if pid == 0:
                        os.dup2(f.fileno(), sys.stdout.fileno())
                        os.dup2(f.fileno(), sys.stderr.fileno())
                        os.closerange(3, systemutils.MAXFD)
                        try:
                            os.execv(executable, args)
                        except OSError:
                            os._exit(1)
                LOG.info('Websocket recver start with pid %d' % pid)

            def _kill():
                try:
                    p = psutil.Process(pid=pid)
                    name = p.name()
                except psutil.NoSuchProcess:
                    return
                if name == self.executer:
                    LOG.warning('Websocket recver overtime, kill it')
                    p.kill()

            self.pid = pid
            hub = hubs.get_hub()
            self.timer = hub.schedule_call_global(timeout or 3600, _kill)

            return dict(port=port,
                        token=token,
                        ipaddr=ipaddr,
                        filename=filename)