How to use _finish_job method in autotest

Best Python code snippet using autotest_python

web.py

Source:web.py Github

copy

Full Screen

...1971 if not cls.jobs.has_key(jobname):1972 return {'status': 'none', 'code': -1, 'msg': ''}1973 return cls.jobs[jobname]19741975 def _finish_job(self, jobname, code, msg, data=None):1976 cls = BackendHandler1977 cls.jobs[jobname]['status'] = 'finish'1978 cls.jobs[jobname]['code'] = code1979 cls.jobs[jobname]['msg'] = msg1980 if data: cls.jobs[jobname]['data'] = data19811982 def get(self, jobname):1983 """Get the status of the new process1984 """1985 self.authed()1986 self.write(self._get_job(_u(jobname)))19871988 def _call(self, callback):1989 #with tornado.stack_context.NullContext():1990 tornado.ioloop.IOLoop.instance().add_callback(callback)19911992 def post(self, jobname):1993 """Create a new backend process1994 """1995 self.authed()19961997 # centos/redhat only job1998 if jobname in ('yum_repolist', 'yum_installrepo', 'yum_info',1999 'yum_install', 'yum_uninstall', 'yum_ext_info'):2000 if self.settings['dist_name'] not in ('centos', 'redhat'):2001 self.write({'code': -1, 'msg': u'不支持的系统类型!'})2002 return20032004 if self.config.get('runtime', 'mode') == 'demo':2005 if jobname in ('update', 'datetime', 'swapon', 'swapoff', 'mount', 'umount', 'format'):2006 self.write({'code': -1, 'msg': u'DEMO状态不允许此类操作!'})2007 return20082009 if jobname == 'update':2010 self._call(self.update)2011 elif jobname in ('service_restart', 'service_start', 'service_stop'):2012 name = self.get_argument('name', '')2013 service = self.get_argument('service', '')20142015 if self.config.get('runtime', 'mode') == 'demo':2016 if service in ('network', 'sshd', 'vpsmate', 'iptables'):2017 self.write({'code': -1, 'msg': u'DEMO状态不允许此类操作!'})2018 return20192020 if service not in si.Service.support_services:2021 self.write({'code': -1, 'msg': u'未支持的服务!'})2022 return2023 if not name: name = service2024 dummy, action = jobname.split('_')2025 if service != '':2026 self._call(functools.partial(self.service,2027 _u(action),2028 _u(service),2029 _u(name)))2030 elif jobname == 'datetime':2031 newdatetime = self.get_argument('datetime', '')2032 # check datetime format2033 try:2034 datetime.datetime.strptime(newdatetime, '%Y-%m-%d %H:%M:%S')2035 except:2036 self.write({'code': -1, 'msg': u'时间格式有错误!'})2037 return2038 self._call(functools.partial(self.datetime,2039 _u(newdatetime)))2040 elif jobname in ('swapon', 'swapoff'):2041 devname = self.get_argument('devname', '')2042 if jobname == 'swapon':2043 action = 'on'2044 else:2045 action = 'off'2046 self._call(functools.partial(self.swapon,2047 _u(action),2048 _u(devname)))2049 elif jobname in ('mount', 'umount'):2050 devname = self.get_argument('devname', '')2051 mountpoint = self.get_argument('mountpoint', '')2052 fstype = self.get_argument('fstype', '')2053 if jobname == 'mount':2054 action = 'mount'2055 else:2056 action = 'umount'2057 self._call(functools.partial(self.mount,2058 _u(action),2059 _u(devname),2060 _u(mountpoint),2061 _u(fstype)))2062 elif jobname == 'format':2063 devname = self.get_argument('devname', '')2064 fstype = self.get_argument('fstype', '')2065 self._call(functools.partial(self.format,2066 _u(devname),2067 _u(fstype)))2068 elif jobname == 'yum_repolist':2069 self._call(self.yum_repolist)2070 elif jobname == 'yum_installrepo':2071 repo = self.get_argument('repo', '')2072 self._call(functools.partial(self.yum_installrepo,2073 _u(repo)))2074 elif jobname == 'yum_info':2075 pkg = self.get_argument('pkg', '')2076 repo = self.get_argument('repo', '*')2077 option = self.get_argument('option', '')2078 if option == 'update':2079 if not pkg in [v for k,vv in yum.yum_pkg_alias.iteritems() for v in vv]:2080 self.write({'code': -1, 'msg': u'未支持的软件包!'})2081 return2082 else:2083 option = 'install'2084 if not yum.yum_pkg_alias.has_key(pkg):2085 self.write({'code': -1, 'msg': u'未支持的软件包!'})2086 return2087 if repo not in yum.yum_repolist + ('installed', '*'):2088 self.write({'code': -1, 'msg': u'未知的软件源 %s!' % repo})2089 return2090 self._call(functools.partial(self.yum_info,2091 _u(pkg),2092 _u(repo),2093 _u(option)))2094 elif jobname in ('yum_install', 'yum_uninstall', 'yum_update'):2095 repo = self.get_argument('repo', '')2096 pkg = self.get_argument('pkg', '')2097 ext = self.get_argument('ext', '')2098 version = self.get_argument('version', '')2099 release = self.get_argument('release', '')21002101 if self.config.get('runtime', 'mode') == 'demo':2102 if pkg in ('sshd', 'iptables'):2103 self.write({'code': -1, 'msg': u'DEMO状态不允许此类操作!'})2104 return21052106 if not yum.yum_pkg_relatives.has_key(pkg):2107 self.write({'code': -1, 'msg': u'软件包不存在!'})2108 return2109 if ext and not yum.yum_pkg_relatives[pkg].has_key(ext):2110 self.write({'code': -1, 'msg': u'扩展不存在!'})2111 return2112 if jobname == 'yum_install':2113 if repo not in yum.yum_repolist:2114 self.write({'code': -1, 'msg': u'未知的软件源 %s!' % repo})2115 return2116 handler = self.yum_install2117 elif jobname == 'yum_uninstall':2118 handler = self.yum_uninstall2119 elif jobname == 'yum_update':2120 handler = self.yum_update2121 self._call(functools.partial(handler,2122 _u(repo),2123 _u(pkg),2124 _u(version),2125 _u(release),2126 _u(ext)))2127 elif jobname == 'yum_ext_info':2128 pkg = self.get_argument('pkg', '')2129 if not yum.yum_pkg_relatives.has_key(pkg):2130 self.write({'code': -1, 'msg': u'软件包不存在!'})2131 return2132 self._call(functools.partial(self.yum_ext_info,2133 _u(pkg)))2134 elif jobname in ('move', 'copy'):2135 srcpath = self.get_argument('srcpath', '')2136 despath = self.get_argument('despath', '')21372138 if self.config.get('runtime', 'mode') == 'demo':2139 if jobname == 'move':2140 if not srcpath.startswith('/var/www') or not despath.startswith('/var/www'):2141 self.write({'code': -1, 'msg': u'DEMO状态不允许修改除 /var/www 以外的目录!'})2142 return2143 elif jobname == 'copy':2144 if not despath.startswith('/var/www'):2145 self.write({'code': -1, 'msg': u'DEMO状态不允许修改除 /var/www 以外的目录!'})2146 return21472148 if not os.path.exists(srcpath):2149 if not os.path.exists(srcpath.strip('*')):2150 self.write({'code': -1, 'msg': u'源路径不存在!'})2151 return2152 if jobname == 'copy':2153 handler = self.copy2154 elif jobname == 'move':2155 handler = self.move2156 self._call(functools.partial(handler,2157 _u(srcpath),2158 _u(despath)))2159 elif jobname == 'remove':2160 paths = self.get_argument('paths', '')2161 paths = _u(paths).split(',')21622163 if self.config.get('runtime', 'mode') == 'demo':2164 for p in paths:2165 if not p.startswith('/var/www') and not p.startswith(self.settings['package_path']):2166 self.write({'code': -1, 'msg': u'DEMO状态不允许在 /var/www 以外的目录下执行删除操作!'})2167 return21682169 self._call(functools.partial(self.remove, paths))2170 elif jobname == 'compress':2171 zippath = self.get_argument('zippath', '')2172 paths = self.get_argument('paths', '')2173 paths = _u(paths).split(',')21742175 if self.config.get('runtime', 'mode') == 'demo':2176 if not zippath.startswith('/var/www'):2177 self.write({'code': -1, 'msg': u'DEMO状态不允许在 /var/www 以外的目录下创建压缩包!'})2178 return2179 for p in paths:2180 if not p.startswith('/var/www'):2181 self.write({'code': -1, 'msg': u'DEMO状态不允许在 /var/www 以外的目录下创建压缩包!'})2182 return21832184 self._call(functools.partial(self.compress,2185 _u(zippath), paths))2186 elif jobname == 'decompress':2187 zippath = self.get_argument('zippath', '')2188 despath = self.get_argument('despath', '')21892190 if self.config.get('runtime', 'mode') == 'demo':2191 if not zippath.startswith('/var/www') and not zippath.startswith(self.settings['package_path']) or \2192 not despath.startswith('/var/www') and not despath.startswith(self.settings['package_path']):2193 self.write({'code': -1, 'msg': u'DEMO状态不允许在 /var/www 以外的目录下执行解压操作!'})2194 return21952196 self._call(functools.partial(self.decompress,2197 _u(zippath),2198 _u(despath)))2199 elif jobname == 'ntpdate':2200 server = self.get_argument('server', '')2201 self._call(functools.partial(self.ntpdate,2202 _u(server)))2203 elif jobname == 'chown':2204 paths = _u(self.get_argument('paths', ''))2205 paths = paths.split(',')22062207 if self.config.get('runtime', 'mode') == 'demo':2208 for p in paths:2209 if not p.startswith('/var/www'):2210 self.write({'code': -1, 'msg': u'DEMO状态不允许在 /var/www 以外的目录下执行此操作!'})2211 return22122213 a_user = _u(self.get_argument('user', ''))2214 a_group = _u(self.get_argument('group', ''))2215 recursively = self.get_argument('recursively', '')2216 option = recursively == 'on' and '-R' or ''2217 self._call(functools.partial(self.chown, paths, a_user, a_group, option))2218 elif jobname == 'chmod':2219 paths = _u(self.get_argument('paths', ''))2220 paths = paths.split(',')22212222 if self.config.get('runtime', 'mode') == 'demo':2223 for p in paths:2224 if not p.startswith('/var/www'):2225 self.write({'code': -1, 'msg': u'DEMO状态不允许在 /var/www 以外的目录下执行此操作!'})2226 return22272228 perms = _u(self.get_argument('perms', ''))2229 recursively = self.get_argument('recursively', '')2230 option = recursively == 'on' and '-R' or ''2231 self._call(functools.partial(self.chmod, paths, perms, option))2232 elif jobname == 'wget':2233 url = _u(self.get_argument('url', ''))2234 path = _u(self.get_argument('path', ''))22352236 if self.config.get('runtime', 'mode') == 'demo':2237 if not path.startswith('/var/www') and not path.startswith(self.settings['package_path']):2238 self.write({'code': -1, 'msg': u'DEMO状态不允许下载到 /var/www 以外的目录!'})2239 return22402241 self._call(functools.partial(self.wget, url, path))2242 elif jobname == 'mysql_fupdatepwd':2243 password = _u(self.get_argument('password', ''))2244 passwordc = _u(self.get_argument('passwordc', ''))2245 if password != passwordc:2246 self.write({'code': -1, 'msg': u'两次密码输入不一致!'})2247 return2248 self._call(functools.partial(self.mysql_fupdatepwd, password))2249 elif jobname == 'mysql_databases':2250 password = _u(self.get_argument('password', ''))2251 self._call(functools.partial(self.mysql_databases, password))2252 elif jobname == 'mysql_dbinfo':2253 password = _u(self.get_argument('password', ''))2254 dbname = _u(self.get_argument('dbname', ''))2255 self._call(functools.partial(self.mysql_dbinfo, password, dbname))2256 elif jobname == 'mysql_users':2257 password = _u(self.get_argument('password', ''))2258 dbname = _u(self.get_argument('dbname', ''))2259 self._call(functools.partial(self.mysql_users, password, dbname))2260 elif jobname == 'mysql_rename':2261 password = _u(self.get_argument('password', ''))2262 dbname = _u(self.get_argument('dbname', ''))2263 newname = _u(self.get_argument('newname', ''))2264 if dbname == newname:2265 self.write({'code': -1, 'msg': u'数据库名无变化!'})2266 return2267 self._call(functools.partial(self.mysql_rename, password, dbname, newname))2268 elif jobname == 'mysql_create':2269 password = _u(self.get_argument('password', ''))2270 dbname = _u(self.get_argument('dbname', ''))2271 collation = _u(self.get_argument('collation', ''))2272 self._call(functools.partial(self.mysql_create, password, dbname, collation))2273 elif jobname == 'mysql_export':2274 password = _u(self.get_argument('password', ''))2275 dbname = _u(self.get_argument('dbname', ''))2276 path = _u(self.get_argument('path', ''))2277 2278 if not path:2279 self.write({'code': -1, 'msg': u'请选择数据库导出目录!'})2280 return22812282 if self.config.get('runtime', 'mode') == 'demo':2283 if not path.startswith('/var/www') and not path.startswith(self.settings['package_path']):2284 self.write({'code': -1, 'msg': u'DEMO状态不允许导出到 /var/www 以外的目录!'})2285 return22862287 self._call(functools.partial(self.mysql_export, password, dbname, path))2288 elif jobname == 'mysql_drop':2289 password = _u(self.get_argument('password', ''))2290 dbname = _u(self.get_argument('dbname', ''))2291 self._call(functools.partial(self.mysql_drop, password, dbname))2292 elif jobname == 'mysql_createuser':2293 password = _u(self.get_argument('password', ''))2294 user = _u(self.get_argument('user', ''))2295 host = _u(self.get_argument('host', ''))2296 pwd = _u(self.get_argument('pwd', ''))2297 self._call(functools.partial(self.mysql_createuser, password, user, host, pwd))2298 elif jobname == 'mysql_userprivs':2299 password = _u(self.get_argument('password', ''))2300 username = _u(self.get_argument('username', ''))2301 if not '@' in username:2302 self.write({'code': -1, 'msg': u'用户不存在!'})2303 return2304 user, host = username.split('@', 1)2305 self._call(functools.partial(self.mysql_userprivs, password, user, host))2306 elif jobname == 'mysql_updateuserprivs':2307 password = _u(self.get_argument('password', ''))2308 username = _u(self.get_argument('username', ''))2309 privs = self.get_argument('privs', '')2310 try:2311 privs = tornado.escape.json_decode(privs)2312 except:2313 self.write({'code': -1, 'msg': u'权限数据有误!'})2314 return2315 dbname = _u(self.get_argument('dbname', ''))2316 if not '@' in username:2317 self.write({'code': -1, 'msg': u'用户不存在!'})2318 return2319 user, host = username.split('@', 1)2320 privs = [2321 priv.replace('_priv', '').replace('_', ' ').upper()2322 .replace('CREATE TMP TABLE', 'CREATE TEMPORARY TABLES')2323 .replace('SHOW DB', 'SHOW DATABASES')2324 .replace('REPL CLIENT', 'REPLICATION CLIENT')2325 .replace('REPL SLAVE', 'REPLICATION SLAVE')2326 for priv, value in privs.iteritems() if '_priv' in priv and value == 'Y']2327 self._call(functools.partial(self.mysql_updateuserprivs, password, user, host, privs, dbname))2328 elif jobname == 'mysql_setuserpassword':2329 password = _u(self.get_argument('password', ''))2330 username = _u(self.get_argument('username', ''))2331 if not '@' in username:2332 self.write({'code': -1, 'msg': u'用户不存在!'})2333 return2334 user, host = username.split('@', 1)2335 pwd = _u(self.get_argument('pwd', ''))2336 self._call(functools.partial(self.mysql_setuserpassword, password, user, host, pwd))2337 elif jobname == 'mysql_dropuser':2338 password = _u(self.get_argument('password', ''))2339 username = _u(self.get_argument('username', ''))2340 if not '@' in username:2341 self.write({'code': -1, 'msg': u'用户不存在!'})2342 return2343 user, host = username.split('@', 1)2344 user, host = user.strip(), host.strip()2345 if user == 'root' and host != '%':2346 self.write({'code': -1, 'msg': u'该用户不允许删除!'})2347 return2348 self._call(functools.partial(self.mysql_dropuser, password, user, host))2349 elif jobname == 'ssh_genkey':2350 path = _u(self.get_argument('path', ''))2351 password = _u(self.get_argument('password', ''))2352 if not path: path = '/root/.ssh/sshkey_vpsmate'2353 self._call(functools.partial(self.ssh_genkey, path, password))2354 elif jobname == 'ssh_chpasswd':2355 path = _u(self.get_argument('path', ''))2356 oldpassword = _u(self.get_argument('oldpassword', ''))2357 newpassword = _u(self.get_argument('newpassword', ''))2358 if not path: path = '/root/.ssh/sshkey_vpsmate'2359 self._call(functools.partial(self.ssh_chpasswd, path, oldpassword, newpassword))2360 else: # undefined job2361 self.write({'code': -1, 'msg': u'未定义的操作!'})2362 return23632364 self.write({'code': 0, 'msg': ''})23652366 @tornado.gen.engine2367 def update(self):2368 if not self._start_job('update'): return2369 2370 root_path = self.settings['root_path']2371 data_path = self.settings['data_path']2372 distname = self.settings['dist_name']23732374 # don't do it in dev environment2375 if os.path.exists('%s/../.svn' % root_path):2376 self._finish_job('update', 0, u'升级成功!')2377 return2378 2379 # install the latest version2380 http = tornado.httpclient.AsyncHTTPClient()2381 response = yield tornado.gen.Task(http.fetch, 'http://www.vpsmate.org/api/latest')2382 if response.error:2383 self._update_job('update', -1, u'获取版本信息失败!')2384 return2385 versioninfo = tornado.escape.json_decode(response.body)2386 downloadurl = versioninfo['download']2387 initscript = u'%s/tools/init.d/%s/vpsmate' % (root_path, distname)2388 steps = [2389 {'desc': u'正在下载安装包...',2390 'cmd': u'wget -q "%s" -O %s/vpsmate.tar.gz' % (downloadurl, data_path),2391 }, {'desc': u'正在创建解压目录...',2392 'cmd': u'mkdir %s/vpsmate' % data_path,2393 }, {'desc': u'正在解压安装包...',2394 'cmd': u'tar zxmf %s/vpsmate.tar.gz -C %s/vpsmate' % (data_path, data_path),2395 }, {'desc': u'正在删除旧版本...',2396 'cmd': u'find %s -mindepth 1 -maxdepth 1 -path %s -prune -o -exec rm -rf {} \;' % (root_path, data_path),2397 }, {'desc': u'正在复制新版本...',2398 'cmd': u'find %s/vpsmate -mindepth 1 -maxdepth 1 -exec cp -r {} %s \;' % (data_path, root_path),2399 }, {'desc': u'正在删除旧的服务脚本...',2400 'cmd': u'rm -f /etc/init.d/vpsmate',2401 }, {'desc': u'正在安装新的服务脚本...',2402 'cmd': u'cp %s /etc/init.d/vpsmate' % initscript,2403 }, {'desc': u'正在更改脚本权限...',2404 'cmd': u'chmod +x /etc/init.d/vpsmate %s/config.py %s/server.py' % (root_path, root_path),2405 }, {'desc': u'正在删除安装临时文件...',2406 'cmd': u'rm -rf %s/vpsmate %s/vpsmate.tar.gz' % (data_path, data_path),2407 },2408 ]2409 for step in steps:2410 desc = _u(step['desc'])2411 cmd = _u(step['cmd'])2412 self._update_job('update', 2, desc)2413 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2414 if result != 0:2415 self._update_job('update', -1, desc+'失败!')2416 break2417 2418 if result == 0:2419 code = 02420 msg = u'升级成功!请刷新页面重新登录。'2421 else:2422 code = -12423 msg = u'升级失败!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>'))24242425 self._finish_job('update', code, msg)24262427 @tornado.gen.engine2428 def service(self, action, service, name):2429 """Service operation.2430 """2431 jobname = 'service_%s_%s' % (action, service)2432 if not self._start_job(jobname): return24332434 action_str = {'start': u'启动', 'stop': u'停止', 'restart': u'重启'}2435 self._update_job(jobname, 2, u'正在%s %s 服务...' % (action_str[action], _d(name)))2436 2437 # patch before start sendmail in redhat/centos 5.x2438 # REF: http://www.mombu.com/gnu_linux/red-hat/t-why-does-sendmail-hang-during-rh-9-start-up-1068528.html2439 if action == 'start' and service in ('sendmail', )\2440 and self.settings['dist_name'] in ('redhat', 'centos')\2441 and self.settings['dist_verint'] == 5:2442 # check if current hostname line in /etc/hosts have a char '.'2443 hostname = si.Server.hostname()2444 hostname_found = False2445 dot_found = False2446 lines = []2447 with open('/etc/hosts') as f:2448 for line in f:2449 if not line.startswith('#') and not hostname_found:2450 fields = line.strip().split()2451 if hostname in fields:2452 hostname_found = True2453 # find '.' in this line2454 dot_found = any(field for field in fields[1:] if '.' in field)2455 if not dot_found:2456 line = '%s %s.localdomain\n' % (line.strip(), hostname)2457 lines.append(line)2458 if not dot_found:2459 with open('/etc/hosts', 'w') as f: f.writelines(lines)24602461 cmd = '/etc/init.d/%s %s' % (service, action)2462 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2463 if result == 0:2464 code = 02465 msg = u'%s 服务%s成功!' % (_d(name), action_str[action])2466 else:2467 code = -12468 msg = u'%s 服务%s失败!<p style="margin:10px">%s</p>' % (_d(name), action_str[action], _d(output.strip().replace('\n', '<br>')))24692470 self._finish_job(jobname, code, msg)24712472 @tornado.gen.engine2473 def datetime(self, newdatetime):2474 """Set datetime using system's date command.2475 """2476 jobname = 'datetime'2477 if not self._start_job(jobname): return24782479 self._update_job(jobname, 2, u'正在设置系统时间...')24802481 cmd = 'date -s \'%s\'' % (newdatetime, )2482 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2483 if result == 0:2484 code = 02485 msg = u'系统时间设置成功!'2486 else:2487 code = -12488 msg = u'系统时间设置失败!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>'))24892490 self._finish_job(jobname, code, msg)24912492 @tornado.gen.engine2493 def ntpdate(self, server):2494 """Run ntpdate command to sync time.2495 """2496 jobname = 'ntpdate_%s' % server2497 if not self._start_job(jobname): return24982499 self._update_job(jobname, 2, u'正在从 %s 同步时间...' % server)2500 cmd = 'ntpdate -u %s' % server2501 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2502 if result == 0:2503 code = 02504 offset = float(output.split(' offset ')[-1].split()[0])2505 msg = u'同步时间成功!(时间偏差 %f 秒)' % _d(offset)2506 else:2507 code = -12508 # no server suitable for synchronization found2509 if 'no server suitable' in output:2510 msg = u'同步时间失败!没有找到合适同步服务器。'2511 else:2512 msg = u'同步时间失败!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>'))25132514 self._finish_job(jobname, code, msg)25152516 @tornado.gen.engine2517 def swapon(self, action, devname):2518 """swapon or swapoff swap partition.2519 """2520 jobname = 'swapon_%s_%s' % (action, devname)2521 if not self._start_job(jobname): return25222523 action_str = {'on': u'启用', 'off': u'停用'}2524 self._update_job(jobname, 2, u'正在%s %s...' % \2525 (action_str[action], _d(devname)))25262527 if action == 'on':2528 cmd = 'swapon /dev/%s' % devname2529 else:2530 cmd = 'swapoff /dev/%s' % devname25312532 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2533 if result == 0:2534 code = 02535 msg = u'%s %s 成功!' % (action_str[action], _d(devname))2536 else:2537 code = -12538 msg = u'%s %s 失败!<p style="margin:10px">%s</p>' % (action_str[action], _d(devname), _d(output.strip().replace('\n', '<br>')))25392540 self._finish_job(jobname, code, msg)25412542 @tornado.gen.engine2543 def mount(self, action, devname, mountpoint, fstype):2544 """Mount or umount using system's mount command.2545 """2546 jobname = 'mount_%s_%s' % (action, devname)2547 if not self._start_job(jobname): return25482549 action_str = {'mount': u'挂载', 'umount': u'卸载'}2550 self._update_job(jobname, 2, u'正在%s %s 到 %s...' % \2551 (action_str[action], _d(devname), _d(mountpoint)))25522553 if action == 'mount':2554 # write config to /etc/fstab2555 sc.Server.fstab(_u(devname), {2556 'devname': _u(devname),2557 'mount': _u(mountpoint),2558 'fstype': _u(fstype),2559 })2560 cmd = 'mount -t %s /dev/%s %s' % (fstype, devname, mountpoint)2561 else:2562 cmd = 'umount /dev/%s' % (devname)25632564 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2565 if result == 0:2566 code = 02567 msg = u'%s %s 成功!' % (action_str[action], _d(devname))2568 else:2569 code = -12570 msg = u'%s %s 失败!<p style="margin:10px">%s</p>' % (action_str[action], _d(devname), _d(output.strip().replace('\n', '<br>')))25712572 self._finish_job(jobname, code, msg)25732574 @tornado.gen.engine2575 def format(self, devname, fstype):2576 """Format partition using system's mkfs.* commands.2577 """2578 jobname = 'format_%s' % devname2579 if not self._start_job(jobname): return25802581 self._update_job(jobname, 2, u'正在格式化 %s,可能需要较长时间,请耐心等候...' % _d(devname))25822583 if fstype in ('ext2', 'ext3', 'ext4'):2584 cmd = 'mkfs.%s -F /dev/%s' % (fstype, devname)2585 elif fstype in ('xfs', 'reiserfs', 'btrfs'):2586 cmd = 'mkfs.%s -f /dev/%s' % (fstype, devname)2587 elif fstype == 'swap':2588 cmd = 'mkswap -f /dev/%s' % devname2589 else:2590 cmd = 'mkfs.%s /dev/%s' % (fstype, devname)2591 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2592 if result == 0:2593 code = 02594 msg = u'%s 格式化成功!' % _d(devname)2595 else:2596 code = -12597 msg = u'%s 格式化失败!<p style="margin:10px">%s</p>' % (_d(devname), _d(output.strip().replace('\n', '<br>')))25982599 self._finish_job(jobname, code, msg)26002601 @tornado.gen.engine2602 def yum_repolist(self):2603 """Get yum repository list.2604 """2605 jobname = 'yum_repolist'2606 if not self._start_job(jobname): return2607 if not self._lock_job('yum'):2608 self._finish_job(jobname, -1, u'已有一个YUM进程在运行,读取软件源列表失败。')2609 return26102611 self._update_job(jobname, 2, u'正在获取软件源列表...')26122613 cmd = 'yum repolist --disableplugin=fastestmirror'2614 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2615 data = []2616 if result == 0:2617 code = 02618 msg = u'获取软件源列表成功!'2619 lines = output.split('\n')2620 for line in lines:2621 if not line: continue2622 repo = line.split()[0]2623 if repo in yum.yum_repolist:2624 data.append(repo)2625 else:2626 code = -12627 msg = u'获取软件源列表失败!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>'))26282629 self._finish_job(jobname, code, msg, data)2630 self._unlock_job('yum')26312632 @tornado.gen.engine2633 def yum_installrepo(self, repo):2634 """Install yum repository.2635 2636 REFs:2637 http://jyrxs.blogspot.com/2008/02/using-centos-5-repos-in-rhel5-server.html2638 http://www.tuxradar.com/answers/4402639 """2640 jobname = 'yum_installrepo_%s' % repo2641 if not self._start_job(jobname): return26422643 if repo not in yum.yum_repolist:2644 self._finish_job(jobname, -1, u'不可识别的软件源!')2645 self._unlock_job('yum')2646 return26472648 self._update_job(jobname, 2, u'正在安装软件源 %s...' % _d(repo))26492650 arch = self.settings['arch']2651 dist_verint = self.settings['dist_verint']2652 2653 cmds = []2654 if repo == 'base':2655 if dist_verint == 5:2656 if self.settings['dist_name'] == 'redhat':2657 # backup system version info2658 cmds.append('cp -f /etc/redhat-release /etc/redhat-release.vpsmate')2659 cmds.append('cp -f /etc/issue /etc/issue.vpsmate')2660 #cmds.append('rpm -e redhat-release-notes-5Server --nodeps')2661 cmds.append('rpm -e redhat-release-5Server --nodeps')26622663 for rpm in yum.yum_reporpms[repo][dist_verint][arch]:2664 cmds.append('rpm -U %s' % rpm)26652666 cmds.append('cp -f /etc/issue.vpsmate /etc/issue')2667 cmds.append('cp -f /etc/redhat-release.vpsmate /etc/redhat-release')26682669 elif repo in ('epel', 'CentALT', 'ius'):2670 # CentALT and ius depends on epel2671 for rpm in yum.yum_reporpms['epel'][dist_verint][arch]:2672 cmds.append('rpm -U %s' % rpm)26732674 if repo in ('CentALT', 'ius'):2675 for rpm in yum.yum_reporpms[repo][dist_verint][arch]:2676 cmds.append('rpm -U %s' % rpm)2677 2678 elif repo == '10gen':2679 # REF: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-redhat-centos-or-fedora-linux/2680 with open('/etc/yum.repos.d/10gen.repo', 'w') as f:2681 f.write(yum.yum_repostr['10gen'][self.settings['arch']])2682 2683 elif repo == 'atomic':2684 # REF: http://www.atomicorp.com/channels/atomic/2685 result, output = yield tornado.gen.Task(call_subprocess, self, yum.yum_repoinstallcmds['atomic'], shell=True)2686 if result != 0: error = True26872688 error = False2689 for cmd in cmds:2690 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2691 if result !=0 and not 'already installed' in output:2692 error = True2693 break2694 2695 # CentALT doesn't have any mirror, we have make a mirror for it2696 if repo == 'CentALT':2697 repofile = '/etc/yum.repos.d/centalt.repo'2698 if os.path.exists(repofile):2699 lines = []2700 baseurl_found = False2701 with open(repofile) as f:2702 for line in f:2703 if line.startswith('baseurl='):2704 baseurl_found = True2705 line = '#%s' % line2706 lines.append(line)2707 # add a mirrorlist line2708 metalink = 'http://www.vpsmate.org/mirrorlist?'\2709 'repo=centalt-%s&arch=$basearch' % self.settings['dist_verint']2710 line = 'mirrorlist=%s\n' % metalink2711 lines.append(line)2712 if baseurl_found:2713 with open(repofile, 'w') as f: f.writelines(lines)27142715 if not error:2716 code = 02717 msg = u'软件源 %s 安装成功!' % _d(repo)2718 else:2719 code = -12720 msg = u'软件源 %s 安装失败!<p style="margin:10px">%s</p>' % (_d(repo), _d(output.strip().replace('\n', '<br>')))27212722 self._finish_job(jobname, code, msg)27232724 @tornado.gen.engine2725 def yum_info(self, pkg, repo, option):2726 """Get package info in repository.2727 2728 Option can be 'install' or 'update'.2729 """2730 jobname = 'yum_info_%s' % pkg2731 if not self._start_job(jobname): return2732 if not self._lock_job('yum'):2733 self._finish_job(jobname, -1, u'已有一个YUM进程在运行,读取软件包信息失败。')2734 return27352736 self._update_job(jobname, 2, u'正在获取软件版本信息...')27372738 if repo == '*': repo = ''2739 if option == 'install':2740 cmds = ['yum info %s %s.%s --showduplicates --disableplugin=fastestmirror'2741 % (repo, alias, self.settings['arch']) for alias in yum.yum_pkg_alias[pkg]]2742 else:2743 cmds = ['yum info %s.%s --disableplugin=fastestmirror' % (pkg, self.settings['arch'])]27442745 data = []2746 matched = False2747 for cmd in cmds:2748 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2749 if result == 0:2750 matched = True2751 lines = output.split('\n')2752 for line in lines:2753 if any(line.startswith(word)2754 for word in ('Name', 'Version', 'Release', 'Size',2755 'Repo', 'From repo')):2756 fields = line.strip().split(':', 1)2757 if len(fields) != 2: continue2758 field_name = fields[0].strip().lower().replace(' ', '_')2759 field_value = fields[1].strip()2760 if field_name == 'name': data.append({})2761 data[-1][field_name] = field_value2762 2763 if matched:2764 code = 02765 msg = u'获取软件版本信息成功!'2766 data = [pkg for pkg in data if pkg['repo'] in yum.yum_repolist+('installed',)]2767 if option == 'update' and len(data) == 1:2768 msg = u'没有找到可用的新版本!'2769 else:2770 code = -12771 msg = u'获取软件版本信息失败!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>'))27722773 self._finish_job(jobname, code, msg, data)2774 self._unlock_job('yum')27752776 @tornado.gen.engine2777 def yum_install(self, repo, pkg, version, release, ext):2778 """Install specified version of package.2779 """2780 jobname = 'yum_install_%s_%s_%s_%s_%s' % (repo, pkg, ext, version, release)2781 jobname = jobname.strip('_').replace('__', '_')2782 if not self._start_job(jobname): return2783 if not self._lock_job('yum'):2784 self._finish_job(jobname, -1, u'已有一个YUM进程在运行,安装失败。')2785 return27862787 if ext:2788 self._update_job(jobname, 2, u'正在下载并安装扩展包,请耐心等候...')2789 else:2790 self._update_job(jobname, 2, u'正在下载并安装软件包,请耐心等候...')2791 2792 if ext: # install extension2793 if version: 2794 if release:2795 pkgs = ['%s-%s-%s.%s' % (ext, version, release, self.settings['arch'])]2796 else:2797 pkgs = ['%s-%s.%s' % (ext, version, self.settings['arch'])]2798 else:2799 pkgs = ['%s.%s' % (ext, self.settings['arch'])]2800 else: # install package2801 if version: # install special version2802 if release:2803 pkgs = ['%s-%s-%s.%s' % (p, version, release, self.settings['arch'])2804 for p, pinfo in yum.yum_pkg_relatives[pkg].iteritems() if pinfo['default']]2805 else:2806 pkgs = ['%s-%s.%s' % (p, version, self.settings['arch'])2807 for p, pinfo in yum.yum_pkg_relatives[pkg].iteritems() if pinfo['default']]2808 else: # or judge by the system2809 pkgs = ['%s.%s' % (p, self.settings['arch'])2810 for p, pinfo in yum.yum_pkg_relatives[pkg].iteritems() if pinfo['default']]2811 repos = [repo, ]2812 if repo in ('CentALT', 'ius', 'atomic', '10gen'):2813 repos.extend(['base', 'updates', 'epel'])2814 exclude_repos = [r for r in yum.yum_repolist if r not in repos]28152816 endinstall = False2817 hasconflict = False2818 conflicts_backups = []2819 while not endinstall:2820 cmd = 'yum install -y %s --disablerepo=%s' % (' '.join(pkgs), ','.join(exclude_repos))2821 #cmd = 'yum install -y %s' % (' '.join(pkgs), )2822 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2823 pkgstr = version and '%s v%s-%s' % (ext and ext or pkg, version, release) or (ext and ext or pkg)2824 if result == 0:2825 if hasconflict:2826 # install the conflict packages we just remove2827 cmd = 'yum install -y %s' % (' '.join(conflicts_backups), )2828 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2829 endinstall = True2830 code = 02831 msg = u'%s 安装成功!' % _d(pkgstr)2832 else:2833 # check if conflicts occur2834 # error message like this:2835 # Error: mysql55 conflicts with mysql2836 # or:2837 # file /etc/my.cnf conflicts between attempted installs of mysql-libs-5.5.28-1.el6.x86_64 and mysql55-libs-5.5.28-2.ius.el6.x86_642838 # file /usr/lib64/mysql/libmysqlclient.so.18.0.0 conflicts between attempted installs of mysql-libs-5.5.28-1.el6.x86_64 and mysql55-libs-5.5.28-2.ius.el6.x86_642839 clines = output.split('\n')2840 for cline in clines:2841 if cline.startswith('Error:') and ' conflicts with ' in cline:2842 hasconflict = True2843 conflict_pkg = cline.split(' conflicts with ', 1)[1]2844 # remove the conflict package and packages depend on it2845 self._update_job(jobname, 2, u'检测到软件冲突,正在卸载处理冲突...')2846 tcmd = 'yum erase -y %s' % conflict_pkg2847 result, output = yield tornado.gen.Task(call_subprocess, self, tcmd)2848 if result == 0:2849 lines = output.split('\n')2850 conflicts_backups = []2851 linestart = False2852 for line in lines:2853 if not linestart:2854 if not line.startswith('Removing for dependencies:'): continue2855 linestart = True2856 if not line.strip(): break # end2857 fields = line.split()2858 conflicts_backups.append('%s-%s' % (fields[0], fields[2]))2859 else:2860 endinstall = True2861 break2862 elif 'conflicts between' in cline:2863 pass2864 if not hasconflict:2865 endinstall = True2866 if endinstall:2867 code = -12868 msg = u'%s 安装失败!<p style="margin:10px">%s</p>' % (_d(pkgstr), _d(output.strip().replace('\n', '<br>')))28692870 self._finish_job(jobname, code, msg)2871 self._unlock_job('yum')28722873 @tornado.gen.engine2874 def yum_uninstall(self, repo, pkg, version, release, ext):2875 """Uninstall specified version of package.2876 """2877 jobname = 'yum_uninstall_%s_%s_%s_%s' % (pkg, ext, version, release)2878 jobname = jobname.strip('_').replace('__', '_')2879 if not self._start_job(jobname): return2880 if not self._lock_job('yum'):2881 self._finish_job(jobname, -1, u'已有一个YUM进程在运行,卸载失败。')2882 return28832884 if ext:2885 self._update_job(jobname, 2, u'正在卸载扩展包...')2886 else:2887 self._update_job(jobname, 2, u'正在卸载软件包...')2888 2889 if ext:2890 pkgs = ['%s-%s-%s.%s' % (ext, version, release, self.settings['arch'])]2891 else:2892 pkgs = ['%s-%s-%s.%s' % (p, version, release, self.settings['arch'])2893 for p, pinfo in yum.yum_pkg_relatives[pkg].iteritems()2894 if pinfo.has_key('base') and pinfo['base']]2895 ## also remove depends pkgs2896 #for p, pinfo in yum.yum_pkg_relatives[pkg].iteritems():2897 # if pinfo.has_key('depends'):2898 # pkgs += pinfo['depends']2899 cmd = 'yum erase -y %s' % (' '.join(pkgs), )2900 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2901 if result == 0:2902 code = 02903 msg = u'%s v%s-%s 卸载成功!' % (_d(ext and ext or pkg), _d(version), _d(release))2904 else:2905 code = -12906 msg = u'%s v%s-%s 卸载失败!<p style="margin:10px">%s</p>' % \2907 (_d(ext and ext or pkg), _d(version), _d(release), _d(output.strip().replace('\n', '<br>')))29082909 self._finish_job(jobname, code, msg)2910 self._unlock_job('yum')29112912 @tornado.gen.engine2913 def yum_update(self, repo, pkg, version, release, ext):2914 """Update a package.2915 2916 The parameter repo and version here are only for showing.2917 """2918 jobname = 'yum_update_%s_%s_%s_%s_%s' % (repo, pkg, ext, version, release)2919 jobname = jobname.strip('_').replace('__', '_')2920 if not self._start_job(jobname): return2921 if not self._lock_job('yum'):2922 self._finish_job(jobname, -1, u'已有一个YUM进程在运行,更新失败。')2923 return29242925 if ext:2926 self._update_job(jobname, 2, u'正在下载并升级扩展包,请耐心等候...')2927 else:2928 self._update_job(jobname, 2, u'正在下载并升级软件包,请耐心等候...')29292930 cmd = 'yum update -y %s-%s-%s.%s' % (ext and ext or pkg, version, release, self.settings['arch'])2931 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2932 if result == 0:2933 code = 02934 msg = u'成功升级 %s 到版本 v%s-%s!' % (_d(ext and ext or pkg), _d(version), _d(release))2935 else:2936 code = -12937 msg = u'%s 升级到版本 v%s-%s 失败!<p style="margin:10px">%s</p>' % \2938 (_d(ext and ext or pkg), _d(version), _d(release), _d(output.strip().replace('\n', '<br>')))29392940 self._finish_job(jobname, code, msg)2941 self._unlock_job('yum')29422943 @tornado.gen.engine2944 def yum_ext_info(self, pkg):2945 """Get ext info list of a pkg info.2946 """2947 jobname = 'yum_ext_info_%s' % pkg2948 if not self._start_job(jobname): return2949 if not self._lock_job('yum'):2950 self._finish_job(jobname, -1, u'已有一个YUM进程在运行,获取扩展信息失败。')2951 return2952 2953 self._update_job(jobname, 2, u'正在收集扩展信息...')29542955 exts = [k for k, v in yum.yum_pkg_relatives[pkg].iteritems() if v.has_key('isext') and v['isext']]2956 cmd = 'yum info %s --disableplugin=fastestmirror' % (' '.join(['%s.%s' % (ext, self.settings['arch']) for ext in exts]))29572958 data = []2959 matched = False2960 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)2961 if result == 0:2962 matched = True2963 lines = output.split('\n')2964 for line in lines:2965 if any(line.startswith(word)2966 for word in ('Name', 'Version', 'Release', 'Size',2967 'Repo', 'From repo')):2968 fields = line.strip().split(':', 1)2969 if len(fields) != 2: continue2970 field_name = fields[0].strip().lower().replace(' ', '_')2971 field_value = fields[1].strip()2972 if field_name == 'name': data.append({})2973 data[-1][field_name] = field_value2974 if matched:2975 code = 02976 msg = u'获取扩展信息成功!'2977 else:2978 code = -12979 msg = u'获取扩展信息失败!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>'))29802981 self._finish_job(jobname, code, msg, data)2982 self._unlock_job('yum')2983 2984 @tornado.gen.engine2985 def copy(self, srcpath, despath):2986 """Copy a directory or file to a new path.2987 """2988 jobname = 'copy_%s_%s' % (srcpath, despath)2989 if not self._start_job(jobname): return2990 2991 self._update_job(jobname, 2, u'正在复制 %s 到 %s...' % (_d(srcpath), _d(despath)))29922993 cmd = 'cp -rf %s %s' % (srcpath, despath)2994 result, output = yield tornado.gen.Task(call_subprocess, self, cmd, shell='*' in srcpath)2995 if result == 0:2996 code = 02997 msg = u'复制 %s 到 %s 完成!' % (_d(srcpath), _d(despath))2998 else:2999 code = -13000 msg = u'复制 %s 到 %s 失败!<p style="margin:10px">%s</p>' % (_d(srcpath), _d(despath), _d(output.strip().replace('\n', '<br>')))30013002 self._finish_job(jobname, code, msg)3003 3004 @tornado.gen.engine3005 def move(self, srcpath, despath):3006 """Move a directory or file recursively to a new path.3007 """3008 jobname = 'move_%s_%s' % (srcpath, despath)3009 if not self._start_job(jobname): return3010 3011 self._update_job(jobname, 2, u'正在移动 %s 到 %s...' % (_d(srcpath), _d(despath)))3012 3013 # check if the despath exists3014 # if exists, we first copy srcpath to despath, then remove the srcpath3015 despath_exists = os.path.exists(despath)30163017 shell = False3018 if despath_exists:3019 # secure check3020 if not os.path.exists(srcpath):3021 self._finish_job(jobname, -1, u'不可识别的源!')3022 return3023 cmd = 'cp -rf %s/* %s' % (srcpath, despath)3024 shell = True3025 else:3026 cmd = 'mv %s %s' % (srcpath, despath)3027 result, output = yield tornado.gen.Task(call_subprocess, self, cmd, shell=shell)3028 if result == 0:3029 code = 03030 msg = u'移动 %s 到 %s 完成!' % (_d(srcpath), _d(despath))3031 else:3032 code = -13033 msg = u'移动 %s 到 %s 失败!<p style="margin:10px">%s</p>' % (_d(srcpath), _d(despath), _d(output.strip().replace('\n', '<br>')))30343035 if despath_exists and code == 0:3036 # remove the srcpath3037 cmd = 'rm -rf %s' % (srcpath, )3038 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3039 if result == 0:3040 code = 03041 msg = u'移动 %s 到 %s 完成!' % (_d(srcpath), _d(despath))3042 else:3043 code = -13044 msg = u'移动 %s 到 %s 失败!<p style="margin:10px">%s</p>' % (_d(srcpath), _d(despath), _d(output.strip().replace('\n', '<br>')))30453046 self._finish_job(jobname, code, msg)30473048 @tornado.gen.engine3049 def remove(self, paths):3050 """Remove a directory or file recursively.3051 """3052 jobname = 'remove_%s' % ','.join(paths)3053 if not self._start_job(jobname): return3054 3055 for path in paths:3056 self._update_job(jobname, 2, u'正在删除 %s...' % _d(path))3057 cmd = 'rm -rf %s' % (path)3058 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3059 if result == 0:3060 code = 03061 msg = u'删除 %s 成功!' % _d(path)3062 else:3063 code = -13064 msg = u'删除 %s 失败!<p style="margin:10px">%s</p>' % (_d(path), _d(output.strip().replace('\n', '<br>')))30653066 self._finish_job(jobname, code, msg)3067 3068 @tornado.gen.engine3069 def compress(self, zippath, paths):3070 """Compress files or directorys.3071 """3072 jobname = 'compress_%s_%s' % (zippath, ','.join(paths))3073 if not self._start_job(jobname): return3074 3075 self._update_job(jobname, 2, u'正在压缩生成 %s...' % _d(zippath))30763077 shell = False3078 if zippath.endswith('.gz'): path = ' '.join(paths)30793080 basepath = os.path.dirname(zippath)+'/'3081 paths = [path.replace(basepath, '') for path in paths]30823083 if zippath.endswith('.tar.gz') or zippath.endswith('.tgz'):3084 cmd = 'tar zcf %s -C %s %s' % (zippath, basepath, ' '.join(paths))3085 elif zippath.endswith('.tar.bz2'):3086 cmd = 'tar jcf %s -C %s %s' % (zippath, basepath, ' '.join(paths))3087 elif zippath.endswith('.zip'):3088 self._update_job(jobname, 2, u'正在安装 zip...')3089 if not os.path.exists('/usr/bin/zip'):3090 if self.settings['dist_name'] in ('centos', 'redhat'):3091 cmd = 'yum install -y zip unzip'3092 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3093 if result == 0:3094 self._update_job(jobname, 0, u'zip 安装成功!')3095 else:3096 self._update_job(jobname, -1, u'zip 安装失败!')3097 return3098 cmd = 'cd %s; zip -rq9 %s %s' % (basepath, zippath, ' '.join(paths))3099 shell = True3100 elif zippath.endswith('.gz'):3101 cmd = 'gzip -f %s' % path3102 else:3103 self._finish_job(jobname, -1, u'不支持的类型!')3104 return31053106 result, output = yield tornado.gen.Task(call_subprocess, self, cmd, shell=shell)3107 if result == 0:3108 code = 03109 msg = u'压缩到 %s 成功!' % _d(zippath)3110 else:3111 code = -13112 msg = u'压缩失败!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>'))31133114 self._finish_job(jobname, code, msg)3115 3116 @tornado.gen.engine3117 def decompress(self, zippath, despath):3118 """Decompress a zip file.3119 """3120 jobname = 'decompress_%s_%s' % (zippath, despath)3121 if not self._start_job(jobname): return31223123 self._update_job(jobname, 2, u'正在解压 %s...' % _d(zippath))3124 if zippath.endswith('.tar.gz') or zippath.endswith('.tgz'):3125 cmd = 'tar zxf %s -C %s' % (zippath, despath)3126 elif zippath.endswith('.tar.bz2'):3127 cmd = 'tar jxf %s -C %s' % (zippath, despath)3128 elif zippath.endswith('.zip'):3129 if not os.path.exists('/usr/bin/unzip'):3130 self._update_job(jobname, 2, u'正在安装 unzip...')3131 if self.settings['dist_name'] in ('centos', 'redhat'):3132 cmd = 'yum install -y zip unzip'3133 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3134 if result == 0:3135 self._update_job(jobname, 0, u'unzip 安装成功!')3136 else:3137 self._update_job(jobname, -1, u'unzip 安装失败!')3138 return3139 cmd = 'unzip -q -o %s -d %s' % (zippath, despath)3140 elif zippath.endswith('.gz'):3141 cmd = 'gunzip -f %s' % zippath3142 else:3143 self._finish_job(jobname, -1, u'不支持的类型!')3144 return31453146 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3147 if result == 0:3148 code = 03149 msg = u'解压 %s 成功!' % _d(zippath)3150 else:3151 code = -13152 msg = u'解压 %s 失败!<p style="margin:10px">%s</p>' % (_d(zippath), _d(output.strip().replace('\n', '<br>')))31533154 self._finish_job(jobname, code, msg)31553156 @tornado.gen.engine3157 def chown(self, paths, user, group, option):3158 """Change owner of paths.3159 """3160 jobname = 'chown_%s' % ','.join(paths)3161 if not self._start_job(jobname): return31623163 self._update_job(jobname, 2, u'正在设置用户和用户组...')3164 3165 #cmd = 'chown %s %s:%s %s' % (option, user, group, ' '.join(paths))3166 3167 for path in paths:3168 result = yield tornado.gen.Task(callbackable(file.chown), path, user, group, option=='-R')3169 if result == True:3170 code = 03171 msg = u'设置用户和用户组成功!'3172 else:3173 code = -13174 msg = u'设置 %s 的用户和用户组时失败!' % _d(path)3175 break31763177 self._finish_job(jobname, code, msg)31783179 @tornado.gen.engine3180 def chmod(self, paths, perms, option):3181 """Change perms of paths.3182 """3183 jobname = 'chmod_%s' % ','.join(paths)3184 if not self._start_job(jobname): return31853186 self._update_job(jobname, 2, u'正在设置权限...')3187 3188 #cmd = 'chmod %s %s %s' % (option, perms, ' '.join(paths))3189 try:3190 perms = int(perms, 8)3191 except:3192 self._finish_job(jobname, -1, u'权限值输入有误!')3193 return31943195 for path in paths:3196 result = yield tornado.gen.Task(callbackable(file.chmod), path, perms, option=='-R')3197 if result == True:3198 code = 03199 msg = u'权限修改成功!'3200 else:3201 code = -13202 msg = u'修改 %s 的权限时失败!' % _d(path)3203 break32043205 self._finish_job(jobname, code, msg)32063207 @tornado.gen.engine3208 def wget(self, url, path):3209 """Run wget command to download file.3210 """3211 jobname = 'wget_%s' % tornado.escape.url_escape(url)3212 if not self._start_job(jobname): return32133214 self._update_job(jobname, 2, u'正在下载 %s...' % _d(url))3215 3216 if os.path.isdir(path): # download to the directory3217 cmd = 'wget -q "%s" --directory-prefix=%s' % (url, path)3218 else:3219 cmd = 'wget -q "%s" -O %s' % (url, path)3220 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3221 if result == 0:3222 code = 03223 msg = u'下载成功!'3224 else:3225 code = -13226 msg = u'下载失败!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>'))32273228 self._finish_job(jobname, code, msg)3229 3230 @tornado.gen.engine3231 def mysql_fupdatepwd(self, password):3232 """Force updating mysql root password.3233 """3234 jobname = 'mysql_fupdatepwd'3235 if not self._start_job(jobname): return32363237 self._update_job(jobname, 2, u'正在检测 MySQL 服务状态...')3238 cmd = 'service mysqld status'3239 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3240 isstopped = 'stopped' in output3241 3242 if not isstopped:3243 self._update_job(jobname, 2, u'正在停止 MySQL 服务...')3244 cmd = 'service mysqld stop'3245 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3246 if result != 0:3247 self._finish_job(jobname, -1, u'停止 MySQL 服务时出错!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>')))3248 return32493250 self._update_job(jobname, 2, u'正在启用 MySQL 恢复模式...')3251 manually = False3252 cmd = 'service mysqld startsos'3253 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3254 if result != 0:3255 # some version of mysqld init.d script may not have startsos option3256 # we run it manually3257 manually = True3258 cmd = 'mysqld_safe --skip-grant-tables --skip-networking'3259 p = subprocess.Popen(cmd,3260 stdout=subprocess.PIPE,3261 stderr=subprocess.STDOUT,3262 close_fds=True, shell=True)3263 if not p:3264 self._finish_job(jobname, -1, u'启用 MySQL 恢复模式时出错!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>')))3265 return32663267 # wait for the mysqld_safe to start up3268 if manually: time.sleep(2)32693270 error = False3271 self._update_job(jobname, 2, u'正在强制重置 root 密码...')3272 if not mysql.fupdatepwd(password):3273 error = True32743275 if manually:3276 # 'service mysqld restart' cannot stop the manually start-up mysqld_safe process3277 result = yield tornado.gen.Task(callbackable(mysql.shutdown), password)3278 if result:3279 self._update_job(jobname, 0, u'成功停止 MySQL 服务!')3280 else:3281 self._update_job(jobname, -1, u'停止 MySQL 服务失败!')3282 p.terminate()3283 p.wait()32843285 msg = ''3286 if not isstopped:3287 if error:3288 msg = u'重置 root 密码时发生错误!正在重启 MySQL 服务...'3289 self._update_job(jobname, -1, msg)3290 else:3291 self._update_job(jobname, 2, u'正在重启 MySQL 服务...')3292 if manually:3293 cmd = 'service mysqld start'3294 else:3295 cmd = 'service mysqld restart'3296 else:3297 if error:3298 msg = u'重置 root 密码时发生错误!正在停止 MySQL 服务...'3299 self._update_job(jobname, -1, msg)3300 else:3301 self._update_job(jobname, 2, u'正在停止 MySQL 服务...')3302 if manually:3303 cmd = ''3304 else:3305 cmd = 'service mysqld stop'33063307 if not cmd:3308 if error:3309 code = -13310 msg = u'%sOK' % msg3311 else:3312 code = 03313 msg = u'root 密码重置成功!'3314 else:3315 result, output = yield tornado.gen.Task(call_subprocess, self, cmd)3316 if result == 0:3317 if error:3318 code = -13319 msg = u'%sOK' % msg3320 else:3321 code = 03322 msg = u'root 密码重置成功!'3323 else:3324 if error:3325 code = -13326 msg = u'%sOK' % msg3327 else:3328 code = -13329 msg = u'root 密码重置成功,但在操作服务时出错!<p style="margin:10px">%s</p>' % _d(output.strip().replace('\n', '<br>'))33303331 self._finish_job(jobname, code, msg)3332 3333 @tornado.gen.engine3334 def mysql_databases(self, password):3335 """Show MySQL database list.3336 """3337 jobname = 'mysql_databases'3338 if not self._start_job(jobname): return33393340 self._update_job(jobname, 2, u'正在获取数据库列表...')3341 dbs = []3342 dbs = yield tornado.gen.Task(callbackable(mysql.show_databases), password)3343 if dbs:3344 code = 03345 msg = u'获取数据库列表成功!'3346 else:3347 code = -13348 msg = u'获取数据库列表失败!'33493350 self._finish_job(jobname, code, msg, dbs)3351 3352 @tornado.gen.engine3353 def mysql_users(self, password, dbname=None):3354 """Show MySQL user list.3355 """3356 if not dbname:3357 jobname = 'mysql_users'3358 else:3359 jobname = 'mysql_users_%s' % dbname3360 if not self._start_job(jobname): return33613362 if not dbname:3363 self._update_job(jobname, 2, u'正在获取用户列表...')3364 else:3365 self._update_job(jobname, 2, u'正在获取数据库 %s 的用户列表...' % _d(dbname))33663367 users = []3368 users = yield tornado.gen.Task(callbackable(mysql.show_users), password, dbname)3369 if users:3370 code = 03371 msg = u'获取用户列表成功!'3372 else:3373 code = -13374 msg = u'获取用户列表失败!'33753376 self._finish_job(jobname, code, msg, users)3377 3378 @tornado.gen.engine3379 def mysql_dbinfo(self, password, dbname):3380 """Get MySQL database info.3381 """3382 jobname = 'mysql_dbinfo_%s' % dbname3383 if not self._start_job(jobname): return33843385 self._update_job(jobname, 2, u'正在获取数据库 %s 的信息...' % _d(dbname))3386 dbinfo = False3387 dbinfo = yield tornado.gen.Task(callbackable(mysql.show_database), password, dbname)3388 if dbinfo:3389 code = 03390 msg = u'获取数据库 %s 的信息成功!' % _d(dbname)3391 else:3392 code = -13393 msg = u'获取数据库 %s 的信息失败!' % _d(dbname)33943395 self._finish_job(jobname, code, msg, dbinfo)3396 3397 @tornado.gen.engine3398 def mysql_rename(self, password, dbname, newname):3399 """MySQL database rename.3400 """3401 jobname = 'mysql_rename_%s' % dbname3402 if not self._start_job(jobname): return34033404 self._update_job(jobname, 2, u'正在重命名 %s...' % _d(dbname))3405 result = yield tornado.gen.Task(callbackable(mysql.rename_database), password, dbname, newname)3406 if result == True:3407 code = 03408 msg = u'%s 重命名成功!' % _d(dbname)3409 else:3410 code = -13411 msg = u'%s 重命名失败!' % _d(dbname)34123413 self._finish_job(jobname, code, msg)3414 3415 @tornado.gen.engine3416 def mysql_create(self, password, dbname, collation):3417 """Create MySQL database.3418 """3419 jobname = 'mysql_create_%s' % dbname3420 if not self._start_job(jobname): return34213422 self._update_job(jobname, 2, u'正在创建 %s...' % _d(dbname))3423 result = yield tornado.gen.Task(callbackable(mysql.create_database), password, dbname, collation=collation)3424 if result == True:3425 code = 03426 msg = u'%s 创建成功!' % _d(dbname)3427 else:3428 code = -13429 msg = u'%s 创建失败!' % _d(dbname)34303431 self._finish_job(jobname, code, msg)3432 3433 @tornado.gen.engine3434 def mysql_export(self, password, dbname, path):3435 """MySQL database export.3436 """3437 jobname = 'mysql_export_%s' % dbname3438 if not self._start_job(jobname): return34393440 self._update_job(jobname, 2, u'正在导出 %s...' % _d(dbname))3441 result = yield tornado.gen.Task(callbackable(mysql.export_database), password, dbname, path)3442 if result == True:3443 code = 03444 msg = u'%s 导出成功!' % _d(dbname)3445 else:3446 code = -13447 msg = u'%s 导出失败!' % _d(dbname)34483449 self._finish_job(jobname, code, msg)34503451 @tornado.gen.engine3452 def mysql_drop(self, password, dbname):3453 """Drop a MySQL database.3454 """3455 jobname = 'mysql_drop_%s' % dbname3456 if not self._start_job(jobname): return34573458 self._update_job(jobname, 2, u'正在删除 %s...' % _d(dbname))3459 result = yield tornado.gen.Task(callbackable(mysql.drop_database), password, dbname)3460 if result == True:3461 code = 03462 msg = u'%s 删除成功!' % _d(dbname)3463 else:3464 code = -13465 msg = u'%s 删除失败!' % _d(dbname)34663467 self._finish_job(jobname, code, msg)3468 3469 @tornado.gen.engine3470 def mysql_createuser(self, password, user, host, pwd=None):3471 """Create MySQL user.3472 """3473 username = '%s@%s' % (user, host)3474 jobname = 'mysql_createuser_%s' % username3475 if not self._start_job(jobname): return34763477 self._update_job(jobname, 2, u'正在添加用户 %s...' % _d(username))3478 result = yield tornado.gen.Task(callbackable(mysql.create_user), password, user, host, pwd)3479 if result == True:3480 code = 03481 msg = u'用户 %s 添加成功!' % _d(username)3482 else:3483 code = -13484 msg = u'用户 %s 添加失败!' % _d(username)34853486 self._finish_job(jobname, code, msg)34873488 @tornado.gen.engine3489 def mysql_userprivs(self, password, user, host):3490 """Get MySQL user privileges.3491 """3492 username = '%s@%s' % (user, host)3493 jobname = 'mysql_userprivs_%s' % username3494 if not self._start_job(jobname): return34953496 self._update_job(jobname, 2, u'正在获取用户 %s 的权限...' % _d(username))3497 3498 privs = {'global':{}, 'bydb':{}}3499 globalprivs = yield tornado.gen.Task(callbackable(mysql.show_user_globalprivs), password, user, host)3500 if globalprivs != False:3501 code = 03502 msg = u'获取用户 %s 的全局权限成功!' % _d(username)3503 privs['global'] = globalprivs3504 else:3505 code = -13506 msg = u'获取用户 %s 的全局权限失败!' % _d(username)3507 privs = False3508 3509 if privs:3510 dbprivs = yield tornado.gen.Task(callbackable(mysql.show_user_dbprivs), password, user, host)3511 if dbprivs != False:3512 code = 03513 msg = u'获取用户 %s 的数据库权限成功!' % _d(username)3514 privs['bydb'] = dbprivs3515 else:3516 code = -13517 msg = u'获取用户 %s 的数据库权限失败!' % _d(username)3518 privs = False35193520 self._finish_job(jobname, code, msg, privs)35213522 @tornado.gen.engine3523 def mysql_updateuserprivs(self, password, user, host, privs, dbname=None):3524 """Update MySQL user privileges.3525 """3526 username = '%s@%s' % (user, host)3527 if dbname:3528 jobname = 'mysql_updateuserprivs_%s_%s' % (username, dbname)3529 else:3530 jobname = 'mysql_updateuserprivs_%s' % username3531 if not self._start_job(jobname): return35323533 if dbname:3534 self._update_job(jobname, 2, u'正在更新用户 %s 在数据库 %s 中的权限...' % (_d(username), _d(dbname)))3535 else:3536 self._update_job(jobname, 2, u'正在更新用户 %s 的权限...' % _d(username))3537 3538 rt = yield tornado.gen.Task(callbackable(mysql.update_user_privs), password, user, host, privs, dbname)3539 if rt != False:3540 code = 03541 msg = u'用户 %s 的权限更新成功!' % _d(username)3542 else:3543 code = -13544 msg = u'用户 %s 的权限更新失败!' % _d(username)35453546 self._finish_job(jobname, code, msg)35473548 @tornado.gen.engine3549 def mysql_setuserpassword(self, password, user, host, pwd):3550 """Set password of MySQL user.3551 """3552 username = '%s@%s' % (user, host)3553 jobname = 'mysql_setuserpassword_%s' % username3554 if not self._start_job(jobname): return35553556 self._update_job(jobname, 2, u'正在更新用户 %s 的密码...' % _d(username))3557 3558 rt = yield tornado.gen.Task(callbackable(mysql.set_user_password), password, user, host, pwd)3559 if rt != False:3560 code = 03561 msg = u'用户 %s 的密码更新成功!' % _d(username)3562 else:3563 code = -13564 msg = u'用户 %s 的密码更新失败!' % _d(username)35653566 self._finish_job(jobname, code, msg)35673568 @tornado.gen.engine3569 def mysql_dropuser(self, password, user, host):3570 """Drop a MySQL user.3571 """3572 username = '%s@%s' % (user, host)3573 jobname = 'mysql_dropuser_%s' % username3574 if not self._start_job(jobname): return35753576 self._update_job(jobname, 2, u'正在删除用户 %s...' % _d(username))3577 3578 rt = yield tornado.gen.Task(callbackable(mysql.drop_user), password, user, host)3579 if rt != False:3580 code = 03581 msg = u'用户 %s 删除成功!' % _d(username)3582 else:3583 code = -13584 msg = u'用户 %s 删除失败!' % _d(username)35853586 self._finish_job(jobname, code, msg)35873588 @tornado.gen.engine3589 def ssh_genkey(self, path, password=''):3590 """Generate a ssh key pair.3591 """3592 jobname = 'ssh_genkey'3593 if not self._start_job(jobname): return35943595 self._update_job(jobname, 2, u'正在生成密钥对...')3596 3597 rt = yield tornado.gen.Task(callbackable(ssh.genkey), path, password)3598 if rt != False:3599 code = 03600 msg = u'密钥对生成成功!'3601 else:3602 code = -13603 msg = u'密钥对生成失败!'36043605 self._finish_job(jobname, code, msg)36063607 @tornado.gen.engine3608 def ssh_chpasswd(self, path, oldpassword, newpassword=''):3609 """Change password of a ssh private key.3610 """3611 jobname = 'ssh_chpasswd'3612 if not self._start_job(jobname): return36133614 self._update_job(jobname, 2, u'正在修改私钥密码...')3615 3616 rt = yield tornado.gen.Task(callbackable(ssh.chpasswd), path, oldpassword, newpassword)3617 if rt != False:3618 code = 03619 msg = u'私钥密码修改成功!'3620 else:3621 code = -13622 msg = u'私钥密码修改失败!'3623 ...

Full Screen

Full Screen

job.py

Source:job.py Github

copy

Full Screen

...66 if not succ:67 job_brief = ""68 return (self.job_id, self.job_guid, self.job_name, self.job_all_stage, \69 self.job_stage, self.job_status, job_brief)70 def _finish_job(self, finish_status):71 self.job_end_time = time.strftime("%Y-%m-%d %H:%M:%S")72 self.job_status = finish_status73 logger.info("job finished [job_guid:%s] [job_status:%s]" % (self.job_guid, Job.STATUS_STRINGS[self.job_status]))74 self.environ["storage"].update_job(self._job_status_tuple())75 self.environ["rmgr"].batch_release([ r["__guid__"] for r in self._resource_replacer.values() ])76 self._resource_replacer.clear()77 pass78 def _schedule_task(self, task):79 rc = task.do_pre()80 if rc == rcode.RC_SUCCEED:81 task.do_run()82 elif rc == rcode.RC_FAILED:83 task.do_finish(rcode.RC_FAILED, with_post=False)84 return rc85 def _schedule(self):86 if self.job_status in [ Job.ST_SUCCEED, Job.ST_FAILED, Job.ST_CANCELED ]:87 return88 89 if self.job_status == Job.ST_WAITING:90 self.job_begin_time = time.strftime("%Y-%m-%d %H:%M:%S")91 self.job_status = Job.ST_RUNNING92 if len(self._tasks) == 0:93 if self.job_stage >= self.job_all_stage:94 self._finish_job(Job.ST_SUCCEED)95 return96 if self._canceled:97 self._finish_job(Job.ST_CANCELED)98 return99 task_desc = self.job_desc["job_tasks"][self.job_stage]100 task_nums = int(task_desc.get("amount", 1))101 for i in range(task_nums):102 self._tasks.append(Task(self, task_desc, self.job_stage, i))103 self.environ["storage"].update_job(self._job_status_tuple())104 105 count_array = [ 0 ] * len(Task.STATUS_INTEGER)106 count_all_flag = True107 for t in self._tasks:108 count_array[t.task_status] += 1109 if (not self._canceled) and count_array[Task.ST_FAILED] == 0 and t.task_status == Task.ST_WAITING:110 if self._schedule_task(t) != rcode.RC_SUCCEED:111 count_all_flag = False112 break113 if count_all_flag:114 if count_array[Task.ST_SUCCEED] == len(self._tasks):115 del self._tasks[:]116 self.job_stage += 1117 elif count_array[Task.ST_RUNNING] == 0:118 if count_array[Task.ST_FAILED] > 0:119 self._finish_job(Job.ST_FAILED)120 elif self._canceled:121 self._finish_job(Job.ST_CANCELED)122 pass123 def schedule(self):124 with self._lock:125 self._schedule()126 pass127 def cancel(self):128 logger.info("job cancel [job_guid:%s]" % self.job_guid)129 with self._lock:130 if self.job_status not in [ Job.ST_SUCCEED, Job.ST_FAILED, Job.ST_CANCELED ]:131 self._canceled = True132 pass133 def update_status(self, task_guid, retcode):134 logger.info("job update_status [job_guid:%s] [task_guid:%s] [retcode:%d]" % (self.job_guid, task_guid, retcode))135 with self._lock:...

Full Screen

Full Screen

job_scheduler.py

Source:job_scheduler.py Github

copy

Full Screen

...16 def cancel_job(self, job_id):17 status = self.redis.get(job_id)18 if status is not None and status.decode('utf-8') == 'RUNNING':19 self.redis.set(job_id, "CANCELLED")20 def _finish_job(self, job_id):21 self.job_map[job_id].pop()22 def get_jobs(self):23 return self.job_map24 def get_job_state(self, job_id):25 if job_id in self.job_map:...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run autotest automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful