def install_waptserver_service(options, conf=None): if conf is None: conf = waptserver.config.load_config(options.configfile) print("install waptserver") service_binary = os.path.abspath( os.path.join(wapt_root_dir, 'waptpython.exe')) service_parameters = '"%s"' % os.path.join(wapt_root_dir, 'waptserver', 'server.py') service_logfile = os.path.join(log_directory, 'nssm_waptserver.log') service_dependencies = 'WAPTPostgresql' install_windows_nssm_service('WAPTServer', service_binary, service_parameters, service_logfile, service_dependencies) tasks_db = os.path.join(wapt_root_dir, 'db') mkdir_p(tasks_db) setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % tasks_db) if not conf.get('secret_key'): conf['secret_key'] = ''.join( random.SystemRandom().choice(string.letters + string.digits) for _ in range(64)) waptserver.config.write_config_file(options.configfile, conf) if options.setpassword: conf['wapt_password'] = pbkdf2_sha256.hash( base64.b64decode(options.setpassword).encode('utf8')) waptserver.config.write_config_file(options.configfile, conf) # ensure Packages index repo = WaptLocalRepo(conf['wapt_folder']) repo.update_packages_index()
def migrate_pg_db(old_pgsql_root_dir,old_pgsql_data_dir,pgsql_root_dir,pgsql_data_dir): # try: cwd = os.getcwd() tmpdir = os.path.join(cwd,'temp') mkdir_p(tmpdir) os.chdir(tmpdir) setuphelpers.run(r'icacls "%s" /t /grant "*S-1-1-0":(OI)(CI)(M)' % tmpdir) old_pgsql_root_dir = old_pgsql_root_dir.replace('\\','/') old_pgsql_data_dir = old_pgsql_data_dir.replace('\\','/') pgsql_root_dir = pgsql_root_dir.replace('\\','/') pgsql_data_dir = pgsql_data_dir.replace('\\','/') cmd = r'"{pgsql_root_dir}/bin/pg_upgrade.exe" -U postgres --old-datadir "{old_pgsql_data_dir}" --new-datadir "{pgsql_data_dir}" --old-bindir "{old_pgsql_root_dir}/bin" --new-bindir "{pgsql_root_dir}/bin"'.format(**locals()) print('Running %s' % cmd) print(run(cmd,cwd=tmpdir)) os.rename(old_pgsql_root_dir,old_pgsql_root_dir+'.old') os.rename(old_pgsql_data_dir,old_pgsql_data_dir+'.old') return True except Exception as e: print('Unable to migrate database : %s' % ensure_unicode(e)) return False finally: os.chdir(cwd)
def sign_exe(exe_path, p12path, p12password): #SIGNTOOL = os.path.join(setuphelpers.programfiles64,'Microsoft SDKs','Windows','v7.1','Bin','signtool.exe') SIGNTOOL = os.path.join(wapt_root_dir, 'utils', 'signtool.exe') if not os.path.exists(SIGNTOOL): SIGNTOOL = os.path.join(setuphelpers.programfiles32, 'wapt', 'utils', 'signtool.exe') if not os.path.exists(SIGNTOOL): SIGNTOOL = os.path.join(r'c:\wapt', 'utils', 'signtool.exe') for attempt in [1, 2, 3]: try: print("Signing attempt #" + str(attempt)) setuphelpers.run( r'"%s" sign /f "%s" /p "%s" /t http://timestamp.verisign.com/scripts/timstamp.dll "%s"' % (SIGNTOOL, p12path, p12password, exe_path), return_stderr=False) break except subprocess.CalledProcessError as cpe: cpe.cmd = cpe.cmd.replace(p12password, '********') cpe.output = cpe.output.replace(p12password, '********') print("Got CalledProcessError from subprocess.check_output: %s" % str(cpe)) except Exception as e: print("Got an exception from subprocess.check_output") raise
def install_wapttasks_service(options, conf=None): if setuphelpers.service_installed('WAPTTasks'): if setuphelpers.service_is_running('WAPTTasks'): setuphelpers.service_stop('WAPTTasks') setuphelpers.service_delete('WAPTTasks') if conf is None: conf = waptserver.config.load_config(options.configfile) print("install wapttasks") service_binary = os.path.abspath( os.path.join(wapt_root_dir, 'waptpython.exe')) service_parameters = '"%s" %s' % (os.path.join( wapt_root_dir, 'waptserver', 'wapthuey.py'), 'tasks_common.huey -w 2') service_logfile = os.path.join(log_directory, 'nssm_wapttasks.log') service_dependencies = 'WAPTPostgresql' install_windows_nssm_service('WAPTTasks', service_binary, service_parameters, service_logfile, service_dependencies) tasks_db = os.path.join(wapt_root_dir, 'db') setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % tasks_db) if setuphelpers.service_installed('WAPTTasks'): if not setuphelpers.service_is_running('WAPTTasks'): setuphelpers.service_start('WAPTTasks')
def migrate_pg_db(old_pgsql_root_dir, old_pgsql_data_dir, pgsql_root_dir, pgsql_data_dir): # try: cwd = os.getcwd() tmpdir = os.path.join(cwd, 'temp') mkdir_p(tmpdir) os.chdir(tmpdir) setuphelpers.run(r'icacls "%s" /t /grant "*S-1-1-0":(OI)(CI)(M)' % tmpdir) old_pgsql_root_dir = old_pgsql_root_dir.replace('\\', '/') old_pgsql_data_dir = old_pgsql_data_dir.replace('\\', '/') pgsql_root_dir = pgsql_root_dir.replace('\\', '/') pgsql_data_dir = pgsql_data_dir.replace('\\', '/') cmd = r'"{pgsql_root_dir}/bin/pg_upgrade.exe" -U postgres --old-datadir "{old_pgsql_data_dir}" --new-datadir "{pgsql_data_dir}" --old-bindir "{old_pgsql_root_dir}/bin" --new-bindir "{pgsql_root_dir}/bin"'.format( **locals()) print('Running %s' % cmd) print(run(cmd, cwd=tmpdir)) os.rename(old_pgsql_root_dir, old_pgsql_root_dir + '.old') os.rename(old_pgsql_data_dir, old_pgsql_data_dir + '.old') return True except Exception as e: print('Unable to migrate database : %s' % ensure_unicode(e)) return False finally: os.chdir(cwd)
def install_nginx_service(options,conf=None): if conf is None: conf = waptserver.config.load_config(options.configfile) print("register nginx frontend") repository_path = os.path.join(wapt_root_dir,'waptserver','repository') for repo_path in ('wapt','wapt-host','waptwua'): mkdir_p(os.path.join(repository_path,repo_path)) run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % os.path.join(repository_path,repo_path)) mkdir_p(os.path.join(wapt_root_dir,'waptserver','nginx','temp')) run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % (os.path.join(wapt_root_dir,'waptserver','nginx','temp'))) run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % os.path.join(wapt_root_dir,'waptserver','nginx','logs')) run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % os.path.join(wapt_root_dir,'log')) make_nginx_config(wapt_root_dir, conf['wapt_folder'],force=options.force) service_binary = os.path.abspath(os.path.join(wapt_root_dir,'waptserver','nginx','nginx.exe')) service_parameters = '' service_logfile = os.path.join(log_directory, 'nssm_nginx.log') service_name = 'WAPTNginx' if setuphelpers.service_installed(service_name) and setuphelpers.service_is_running(service_name): setuphelpers.service_stop(service_name) #print('Register "%s" in registry' % service_name) install_windows_nssm_service(service_name,service_binary,service_parameters,service_logfile) time.sleep(5) if setuphelpers.service_installed(service_name) and not setuphelpers.service_is_running(service_name): setuphelpers.service_start(service_name)
def create_wapt_setup(wapt,default_public_cert='',default_repo_url='',default_wapt_server='',destination='',company=''): r"""Build a customized waptsetup with provided certificate included. Returns filename >>> from common import Wapt >>> wapt = Wapt(config_filename=r'C:\Users\htouvet\AppData\Local\waptconsole\waptconsole.ini') >>> create_wapt_setup(wapt,r'C:\private\ht.crt',destination='c:\\tranquilit\\wapt\\waptsetup') u'c:\\tranquilit\\wapt\\waptsetup\\waptsetup.exe' """ if not company: company = registered_organization() outputfile = '' iss_template = makepath(wapt.wapt_base_dir,'waptsetup','waptsetup.iss') custom_iss = makepath(wapt.wapt_base_dir,'waptsetup','custom_waptsetup.iss') iss = codecs.open(iss_template,'r',encoding='utf8').read().splitlines() new_iss=[] for line in iss: if line.startswith('#define default_repo_url'): new_iss.append('#define default_repo_url "%s"' % (default_repo_url)) elif line.startswith('#define default_wapt_server'): new_iss.append('#define default_wapt_server "%s"' % (default_wapt_server)) elif line.startswith('#define output_dir'): new_iss.append('#define output_dir "%s"' % (destination)) elif line.startswith('#define Company'): new_iss.append('#define Company "%s"' % (company)) elif line.startswith('#define install_certs'): new_iss.append('#define install_certs') elif line.startswith('WizardImageFile='): pass elif not line.startswith('#define signtool'): new_iss.append(line) if line.startswith('OutputBaseFilename'): outputfile = makepath(wapt.wapt_base_dir,'waptsetup','%s.exe' % line.split('=')[1]) source = os.path.normpath(default_public_cert) target = os.path.join(os.path.dirname(iss_template),'..','ssl') if not (os.path.normcase(os.path.abspath( os.path.dirname(source))) == os.path.normcase(os.path.abspath(target))): filecopyto(source,target) codecs.open(custom_iss,'wb',encoding='utf8').write('\n'.join(new_iss)) #inno_directory = '%s\\Inno Setup 5\\Compil32.exe' % programfiles32 inno_directory = makepath(wapt.wapt_base_dir,'waptsetup','innosetup','ISCC.exe') if not os.path.isfile(inno_directory): raise Exception(u"Innosetup n'est pas disponible (emplacement %s), veuillez l'installer" % inno_directory) run('"%s" %s' % (inno_directory,custom_iss)) #print('%s compiled successfully' % (outputfile, )) # create a sha256 file for waptupgrade package result = os.path.abspath(os.path.join(destination,os.path.basename(outputfile))) with open(makepath(wapt.wapt_base_dir,'waptupgrade','waptagent.sha256'),'wb') as f: f.write("%s %s\n" % (sha256_for_file(result),'waptagent.exe')) return result
def main(): parser=OptionParser(usage=__doc__) parser.add_option("-l","--laz-build-path", dest="lazbuildpath", default=r'C:\lazarus\lazbuild.exe', help="Path to lazbuild or lazbuild.exe (default: %default)") parser.add_option("-p","--primary-config-path", dest="primary_config_path", default='%LOCALAPPDATA%\\lazarus', help="Path to lazbuild primary config dir. (default: %default)") parser.add_option("-v","--wapt-version", dest="waptversion", default=waptutils.__version__, help="Wapt version to put in exe metadata. (default: %default)") parser.add_option("-b","--build-nr", dest="buildnr", default=None, help="Wapt compile build to put in exe metadata. (default: %default)") parser.add_option("-e","--wapt-edition", dest="waptedition", default='community', help="Wapt edition to build (community, enterprise...). (default: %default)") parser.add_option("-u","--update-hash-file", dest="update_hash_filepath", default=r'{lpi_dirname}\\..\\{lpi_name}.sha256',help="Hash file to update vars (lpi_rootname,lpi_name,lpi_path,lpi_dirname,lpi_basename) (default: <lpi-base-name>.sha256") parser.add_option("-c","--compress", action='store_true', dest="compress", default=False, help="Compress with UPX. (default: %default)") parser.add_option("-k","--sign-key", dest="sign_key_path", help="Sign with this key. (default: %default)") parser.add_option("-w","--sign-key-pwd-path", dest="sign_key_pwd_path", help="Path to password file. (default: %default)") parser.add_option("-t","--target-dir", dest="target_dir", help="Target exe directory (default: ") (options,args) = parser.parse_args() if len(args) != 1: parser.usage sys.exit(1) if options.buildnr is None: r = Repo(wapt_root_dir,search_parent_directories = True) options.buildnr = str(r.active_branch.commit.count()) for lpi_path in args: lpi_path = os.path.abspath(lpi_path) (lpi_rootname,lpi_ext) = os.path.splitext(lpi_path) lpi_dirname = os.path.dirname(lpi_path) lpi_basename = os.path.basename(lpi_path) (lpi_name,lpi_ext) = os.path.splitext(os.path.basename(lpi_path)) print('Configure %s' % lpi_path) set_lpi_options(lpi_path,options.waptedition,waptutils.Version(options.waptversion,4),options.buildnr) set_app_ico(lpi_path,options.waptedition) update_hash_file(os.path.abspath(options.update_hash_filepath.format(**locals()))) cmd = '"%s" --primary-config-path="%s" -B "%s"'% (os.path.expandvars(options.lazbuildpath),os.path.expandvars(options.primary_config_path),os.path.expandvars(lpi_path)) print(u'Running: %s' % cmd) setuphelpers.run(cmd,cwd = os.path.dirname(os.path.expandvars(options.lazbuildpath))) (fn,ext) = os.path.splitext(get_lpi_output(lpi_path)) if ext in ('','.'): ext = '.exe' exe_fn = os.path.abspath(os.path.abspath(os.path.join(lpi_dirname,fn+ext))) if options.compress: print(u'Compress %s with UPX' % exe_fn) setuphelpers.run('"%s" "%s"' % (os.path.join(setuphelpers.programfiles32,'upx','upx.exe'),exe_fn)) if options.sign_key_path: sign_exe(exe_fn,options.sign_key_path,open(options.sign_key_pwd_path,'rb').read())
def sign_exe(exe_path,p12path,p12password): #SIGNTOOL = os.path.join(setuphelpers.programfiles64,'Microsoft SDKs','Windows','v7.1','Bin','signtool.exe') SIGNTOOL = os.path.join('c:\\wapt','utils','signtool.exe') for attempt in [1, 2, 3]: try: print "Signing attempt #" + str(attempt) setuphelpers.run(r'"%s" sign /f "%s" /p "%s" /t http://timestamp.verisign.com/scripts/timstamp.dll "%s"' % (SIGNTOOL,p12path,p12password,exe_path),return_stderr=False) break except subprocess.CalledProcessError as cpe: cpe.cmd = cpe.cmd.replace(p12password, '********') cpe.output = cpe.output.replace(p12password, '********') print "Got CalledProcessError from subprocess.check_output: %s" % str(cpe) except Exception as e: print "Got an exception from subprocess.check_output" raise
def _run(self): """Launch an external 'wapt-get waptupgrade' process to upgrade local copy of wapt client""" from setuphelpers import run output = ensure_unicode( run('"%s" %s' % (os.path.join(wapt_root_dir, 'wapt-get.exe'), 'waptupgrade'))) self.result = {'result': 'OK', 'message': output}
def sign_exe(exe_path, p12path, p12password): KSIGN = os.path.join(setuphelpers.programfiles32, 'kSign', 'kSignCMD.exe') for attempt in [1, 2, 3]: try: print "Signing attempt #" + str(attempt) setuphelpers.run(r'"%s" /f "%s" /p"%s" "%s"' % (KSIGN, p12path, p12password, exe_path), return_stderr=False) break except subprocess.CalledProcessError as cpe: cpe.cmd = cpe.cmd.replace(p12password, '********') cpe.output = cpe.output.replace(p12password, '********') print "Got CalledProcessError from subprocess.check_output: %s" % str( cpe) except Exception as e: print "Got an exception from subprocess.check_output" raise
def install_wapttasks_service(options,conf=None): if setuphelpers.service_installed('WAPTTasks'): if setuphelpers.service_is_running('WAPTTasks'): setuphelpers.service_stop('WAPTTasks') setuphelpers.service_delete('WAPTTasks') if conf is None: conf = waptserver.config.load_config(options.configfile) print("install wapttasks") service_binary = os.path.abspath(os.path.join(wapt_root_dir,'waptpython.exe')) service_parameters = '"%s" %s' % (os.path.join(wapt_root_dir,'waptserver','wapthuey.py'),'waptenterprise.waptserver.wsus_tasks.huey -w 2') service_logfile = os.path.join(log_directory, 'nssm_wapttasks.log') service_dependencies = 'WAPTPostgresql' install_windows_nssm_service('WAPTTasks',service_binary,service_parameters,service_logfile,service_dependencies) tasks_db = os.path.join(wapt_root_dir,'db') setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % tasks_db) if setuphelpers.service_installed('WAPTTasks'): if not setuphelpers.service_is_running('WAPTTasks'): setuphelpers.service_start('WAPTTasks')
def install_nginx_service(): print("register nginx frontend") repository_path = os.path.join(wapt_root_dir, 'waptserver', 'repository') for repo_path in ('wapt', 'wapt-host', 'wapt-hostref'): mkdir_p(os.path.join(repository_path, repo_path)) run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % os.path.join(repository_path, repo_path)) mkdir_p(os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'temp')) run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % (os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'temp'))) run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'logs')) make_nginx_config(wapt_root_dir, conf['wapt_folder']) service_binary = os.path.abspath( os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'nginx.exe')) service_parameters = '' service_logfile = os.path.join(log_directory, 'nssm_nginx.log') service_name = 'WAPTNginx' #print('Register "%s" in registry' % service_name) install_windows_nssm_service(service_name, service_binary, service_parameters, service_logfile) time.sleep(5)
def install_windows_service(): """Setup waptserver as a windows Service managed by nssm >>> install_windows_service() """ import setuphelpers from setuphelpers import registry_set, REG_DWORD, REG_EXPAND_SZ, REG_MULTI_SZ, REG_SZ datatypes = {"dword": REG_DWORD, "sz": REG_SZ, "expand_sz": REG_EXPAND_SZ, "multi_sz": REG_MULTI_SZ} if setuphelpers.service_installed("waptserver"): if setuphelpers.service_is_running("waptserver"): logger.info("Stop running waptserver") setuphelpers.run("net stop waptserver") while setuphelpers.service_is_running("waptserver"): logger.debug("Waiting for waptserver to terminate") time.sleep(2) logger.info("Unregister existing waptserver") setuphelpers.run("sc delete waptserver") if setuphelpers.iswin64(): nssm = os.path.join(wapt_root_dir, "waptservice", "win64", "nssm.exe") else: nssm = os.path.join(wapt_root_dir, "waptservice", "win32", "nssm.exe") logger.info("Register new waptserver with nssm") setuphelpers.run( '"{nssm}" install WAPTServer "{waptpython}" ""{waptserverpy}""'.format( waptpython=os.path.abspath(os.path.join(wapt_root_dir, "waptpython.exe")), nssm=nssm, waptserverpy=os.path.abspath(__file__), ) ) # fix some parameters (quotes for path with spaces... params = { "Description": "sz:Wapt test server", "DelayedAutostart": 1, "DisplayName": "sz:WAPTServer", "AppStdout": r"expand_sz:{}".format(os.path.join(log_directory, "waptserver.log")), "Parameters\\AppStderr": r"expand_sz:{}".format(os.path.join(log_directory, "waptserver.log")), "Parameters\\AppParameters": r'expand_sz:"{}"'.format(os.path.abspath(__file__)), } root = setuphelpers.HKEY_LOCAL_MACHINE base = r"SYSTEM\CurrentControlSet\services\WAPTServer" for key in params: if isinstance(params[key], int): (valuetype, value) = ("dword", params[key]) elif ":" in params[key]: (valuetype, value) = params[key].split(":", 1) if valuetype == "dword": value = int(value) else: (valuetype, value) = ("sz", params[key]) fullpath = base + "\\" + key (path, keyname) = fullpath.rsplit("\\", 1) if keyname == "@" or keyname == "": keyname = None registry_set(root, path, keyname, value, type=datatypes[valuetype])
def main(): parser=OptionParser(usage=__doc__) parser.add_option("-l","--iscc-binary", dest="iscc_binary", default=os.path.join(os.path.dirname(__file__),'innosetup','ISCC.exe'), help="Path to ISCC compiler (default: %default)") parser.add_option("-v","--wapt-version", dest="waptversion", default=waptutils.__version__, help="Wapt edition to build (community, enterprise...). (default: %default)") parser.add_option("-e","--wapt-edition", dest="waptedition", default='community', help="Wapt edition to build (community, enterprise...). (default: %default)") parser.add_option("-k","--sign-key", dest="sign_key_path", help="Sign with this key. (default: %default)") parser.add_option("-w","--sign-key-pwd-path", dest="sign_key_pwd_path", help="Path to password file. (default: %default)") parser.add_option("-x","--sign-exe-filenames", dest="exe_filenames", help="Additional executables to sign. (default: %default)") (options,args) = parser.parse_args() if len(args) != 1: parser.usage sys.exit(1) for iss_path in args: iss_path = os.path.abspath(iss_path) (iss_rootname,issext) = os.path.splitext(iss_path) # add a revision.txt file with git short r = Repo(search_parent_directories=True) rev_file = open(os.path.join(os.path.dirname(iss_path), '..', 'revision.txt'), 'w') rev_file.write(r.head.object.hexsha[:8]) rev_file.close() r.close() iss_file = iss_rootname + ".iss" if options.sign_key_path and options.exe_filenames: exes = options.exe_filenames.split(',') for exe_fn in exes: sign_exe(exe_fn,options.sign_key_path,open(options.sign_key_pwd_path,'rb').read()) cmd = '"%(issc_binary)s" /Dwapt%(waptedition)s %(issfile)s' % { 'issc_binary':options.iscc_binary, 'issfile':iss_file, 'waptedition':options.waptedition.lower() } res = setuphelpers.run(cmd) exe_fn = res.splitlines()[-1] if options.sign_key_path: sign_exe(exe_fn,options.sign_key_path,open(options.sign_key_pwd_path,'rb').read())
if p['package'].section == 'host': hosts[1].append(p['filename']) else: others[1].append(p['filename']) for package_group in (hosts,others): if package_group[1]: # add quotes for command line files_list = ['"%s"' % f for f in package_group[1]] cmd_dict = {'waptfile': files_list,'waptdir':package_group[0]} res = mywapt.upload_package(cmd_dict) print('Status : %s, %s'%(res['status'],res['message'])) if package_group != hosts: if mywapt.after_upload: print 'Run after upload script...' print setuphelpers.run(mywapt.after_upload % cmd_dict) else: print u'\nYou can upload to repository with\n %s upload-package %s ' % (sys.argv[0],'"%s"' % (' '.join([p['filename'] for p in packages]),) ) elif action=='sign-package': if len(args)<2: print u"You must provide at least one source directory or package to sign" sys.exit(1) for waptfile in [os.path.abspath(p) for p in args[1:]]: if os.path.isdir(waptfile) or os.path.isfile(waptfile): print('Signing %s' % waptfile) signature = mywapt.sign_package(waptfile, excludes=options.excludes.split(',')) print u"Package %s signed : signature :\n%s" % (waptfile,signature) sys.exit(0)
def install_postgresql_service(options, conf=None): if conf is None: conf = waptserver.config.load_config(options.configfile) print("install postgres database") pgsql_root_dir = r'%s\waptserver\pgsql-9.6' % wapt_root_dir pgsql_data_dir = r'%s\waptserver\pgsql_data-9.6' % wapt_root_dir pgsql_data_dir = pgsql_data_dir.replace('\\', '/') print("build database directory") if not os.path.exists(os.path.join(pgsql_data_dir, 'postgresql.conf')): setuphelpers.mkdirs(pgsql_data_dir) # need to have specific write acls for current user otherwise initdb fails... setuphelpers.run(r'icacls "%s" /t /grant "%s":(OI)(CI)(M)' % (pgsql_data_dir, GetUserName())) setuphelpers.run(r'"%s\bin\initdb" -U postgres -E=UTF8 -D "%s"' % (pgsql_root_dir, pgsql_data_dir)) setuphelpers.run(r'icacls "%s" /t /grant "*S-1-5-20":(OI)(CI)(M)' % pgsql_data_dir) print("start postgresql database") if setuphelpers.service_installed('WaptPostgresql'): if setuphelpers.service_is_running('WaptPostgresql'): setuphelpers.service_stop('waptPostgresql') setuphelpers.service_delete('waptPostgresql') cmd = r'"%s\bin\pg_ctl" register -N WAPTPostgresql -U "nt authority\networkservice" -S auto -D "%s" ' % ( pgsql_root_dir, pgsql_data_dir) print cmd run(cmd) setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % log_directory) setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % pgsql_data_dir) else: print("database already instanciated, doing nothing") # try to migrate from old version (pg 9.4, wapt 1.5) old_pgsql_root_dir = r'%s\waptserver\pgsql' % wapt_root_dir old_pgsql_data_dir = r'%s\waptserver\pgsql_data' % wapt_root_dir old_pgsql_data_dir = old_pgsql_data_dir.replace('\\', '/') if os.path.isdir(old_pgsql_data_dir) and os.path.isdir(old_pgsql_root_dir): print('migrating database from previous postgresql DB') migrate_pg_db(old_pgsql_root_dir, old_pgsql_data_dir, pgsql_root_dir, pgsql_data_dir) print('starting postgresql') if not setuphelpers.service_is_running('waptpostgresql'): setuphelpers.service_start('waptpostgresql') # waiting for postgres to be ready time.sleep(2) print("creating wapt database") import psycopg2 from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT conn = None cur = None try: conn = psycopg2.connect('dbname=template1 user=postgres') conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) cur = conn.cursor() cur.execute("select 1 from pg_roles where rolname='%(db_user)s'" % conf) val = cur.fetchone() if val is None: print( "%(db_user)s pgsql user does not exists, creating %(db_user)s user" % conf) cur.execute("create user %(db_user)s" % conf) cur.execute("select 1 from pg_database where datname='%(db_name)s'" % conf) val = cur.fetchone() if val is None: print( "database %(db_name)s does not exists, creating %(db_name)s db" % conf) cur.execute("create database %(db_name)s owner %(db_user)s" % conf) finally: if cur: cur.close() if conn: conn.close() print("Creating/upgrading wapt tables") run(r'"%s\waptpython.exe" "%s\waptserver\model.py" init_db -c "%s"' % (wapt_root_dir, wapt_root_dir, options.configfile)) print("Done") print('Import lcoal Packages data into database') repo = WaptLocalRepo(conf['wapt_folder']) load_db_config(conf) Packages.update_from_repo(repo)
def create_wapt_setup(wapt, default_public_cert='', default_repo_url='', default_wapt_server='', destination='', company=''): r"""Build a customized waptsetup with provided certificate included. Returns filename >>> from common import Wapt >>> wapt = Wapt(config_filename=r'C:\Users\htouvet\AppData\Local\waptconsole\waptconsole.ini') >>> create_wapt_setup(wapt,r'C:\private\ht.crt',destination='c:\\tranquilit\\wapt\\waptsetup') u'c:\\tranquilit\\wapt\\waptsetup\\waptsetup.exe' """ if not company and sys.platform == 'win32': company = registered_organization() outputfile = '' iss_template = makepath(wapt.wapt_base_dir, 'waptsetup', 'waptsetup.iss') custom_iss = makepath(wapt.wapt_base_dir, 'waptsetup', 'custom_waptsetup.iss') iss = codecs.open(iss_template, 'r', encoding='utf8').read().splitlines() new_iss = [] for line in iss: if line.startswith('#define default_repo_url'): new_iss.append('#define default_repo_url "%s"' % (default_repo_url)) elif line.startswith('#define default_wapt_server'): new_iss.append('#define default_wapt_server "%s"' % (default_wapt_server)) elif line.startswith('#define output_dir'): new_iss.append('#define output_dir "%s"' % (destination)) elif line.startswith('#define Company'): new_iss.append('#define Company "%s"' % (company)) elif line.startswith('#define install_certs'): new_iss.append('#define install_certs') elif line.startswith('WizardImageFile='): pass elif not line.startswith('#define signtool'): new_iss.append(line) if line.startswith('OutputBaseFilename'): outputfile = makepath(wapt.wapt_base_dir, 'waptsetup', '%s.exe' % line.split('=')[1]) source = os.path.normpath(default_public_cert) target = os.path.join(os.path.dirname(iss_template), '..', 'ssl') if not (os.path.normcase(os.path.abspath(os.path.dirname(source))) == os.path.normcase(os.path.abspath(target))): filecopyto(source, target) codecs.open(custom_iss, 'wb', encoding='utf8').write('\n'.join(new_iss)) #inno_directory = '%s\\Inno Setup 5\\Compil32.exe' % programfiles32 inno_directory = makepath(wapt.wapt_base_dir, 'waptsetup', 'innosetup', 'ISCC.exe') if not os.path.isfile(inno_directory): raise Exception( u"Innosetup n'est pas disponible (emplacement %s), veuillez l'installer" % inno_directory) run('"%s" %s' % (inno_directory, custom_iss)) #print('%s compiled successfully' % (outputfile, )) # create a sha256 file for waptupgrade package result = os.path.abspath( os.path.join(destination, os.path.basename(outputfile))) with open(makepath(wapt.wapt_base_dir, 'waptupgrade', 'waptagent.sha256'), 'wb') as f: f.write("%s %s\n" % (sha256_for_file(result), 'waptagent.exe')) return result
if conf['wapt_folder'].endswith('\\') or conf['wapt_folder'].endswith('/'): conf['wapt_folder'] = conf['wapt_folder'][:-1] log_directory = os.path.join(wapt_root_dir, 'log') if not os.path.exists(log_directory): os.mkdir(log_directory) if args == ['all']: args = ['install_nginx', 'install_postgresql', 'install_waptserver'] for action in args: if action == 'install_nginx': print('Installing postgresql as a service managed by nssm') install_nginx_service(options, conf) elif action == 'install_postgresql': print('Installing NGINX as a service managed by nssm') install_postgresql_service(options, conf) elif action == 'install_waptserver': print('Installing WAPT Server as a service managed by nssm') install_waptserver_service(options, conf) if os.path.isfile( os.path.join(wapt_root_dir, 'waptenterprise', 'waptserver', 'wsus_tasks.py')): install_wapttasks_service(options, conf) setuphelpers.run(r'icacls "%s" /t /grant "*S-1-5-20":(OI)(CI)(M)' % os.path.join(wapt_root_dir, 'conf')) setuphelpers.run(r'icacls "%s" /t /grant "*S-1-5-20":(OI)(CI)(M)' % os.path.join(wapt_root_dir, 'log'))
def install_postgresql_service(): print("install postgres database") pgsql_root_dir = r'%s\waptserver\pgsql' % wapt_root_dir pgsql_data_dir = r'%s\waptserver\pgsql_data' % wapt_root_dir pgsql_data_dir = pgsql_data_dir.replace('\\', '/') print("build database directory") if os.path.exists(os.path.join(pgsql_data_dir, 'postgresql.conf')): print("database already instanciated, doing nothing") # TODO: check that database is fully working and up to date # TODO: add a force option return print("init pgsql data directory") pg_data_dir = os.path.join(wapt_root_dir, 'waptserver', 'pgsql_data') setuphelpers.mkdirs(pg_data_dir) # need to have specific write acls for current user otherwise initdb fails... setuphelpers.run(r'icacls "%s" /t /grant "%s":(OI)(CI)(M)' % (pg_data_dir, GetUserName())) setuphelpers.run( r'"%s\waptserver\pgsql\bin\initdb" -U postgres -E=UTF8 -D "%s\waptserver\pgsql_data"' % (wapt_root_dir, wapt_root_dir)) setuphelpers.run(r'icacls "%s" /t /grant "*S-1-5-20":(OI)(CI)(M)' % pg_data_dir) print("start postgresql database") if setuphelpers.service_installed('WaptPostgresql'): if setuphelpers.service_is_running('WaptPostgresql'): setuphelpers.service_stop('waptPostgresql') setuphelpers.service_delete('waptPostgresql') cmd = r'"%s\bin\pg_ctl" register -N WAPTPostgresql -U "nt authority\networkservice" -S auto -D "%s" ' % ( pgsql_root_dir, os.path.join(wapt_root_dir, 'waptserver', 'pgsql_data')) print cmd run(cmd) setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % log_directory) setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % pgsql_data_dir) print('starting postgresql') run('net start waptpostgresql') #cmd = r"%s\bin\pg_ctl.exe -D %s start" % (pgsql_root_dir, pgsql_data_dir) #devnull = open(os.devnull,'wb') #print(subprocess.Popen(cmd,shell=True)) # waiting for postgres to be ready time.sleep(1) print("creating wapt database") import psycopg2 from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT conn = psycopg2.connect('dbname=template1 user=postgres') conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) cur = conn.cursor() cur.execute("select 1 from pg_roles where rolname='wapt'") val = cur.fetchone() if val != 1: print("wapt pgsql user does not exists, creating wapt user") cur.execute("create user wapt") val = cur.execute("select 1 from pg_database where datname='wapt'") if val != 1: print("database wapt does not exists, creating wapt db") cur.execute(r"create extension hstore") cur.execute("create database wapt owner wapt") cur.close() conn.close() run(r'"%s\waptpython.exe" "%s\waptserver\waptserver_model.py" init_db' % (wapt_root_dir, wapt_root_dir)) time.sleep(1) setuphelpers.service_stop('waptpostgresql')
def main(): parser = OptionParser(usage=__doc__) parser.add_option( "-l", "--laz-build-path", dest="lazbuildpath", default=r'C:\lazarus\lazbuild.exe', help="Path to lazbuild or lazbuild.exe (default: %default)") parser.add_option( "-p", "--primary-config-path", dest="primary_config_path", default='%LOCALAPPDATA%\\lazarus', help="Path to lazbuild primary config dir. (default: %default)") parser.add_option( "-v", "--wapt-version", dest="waptversion", default=waptutils.__version__, help="Wapt version to put in exe metadata. (default: %default)") parser.add_option( "-b", "--build-nr", dest="buildnr", default=None, help="Wapt compile build to put in exe metadata. (default: %default)") parser.add_option( "-e", "--wapt-edition", dest="waptedition", default='community', help= "Wapt edition to build (community, enterprise...). (default: %default)" ) parser.add_option( "-u", "--update-hash-file", dest="update_hash_filepath", default=r'{lpi_dirname}\\..\\{lpi_name}.sha256', help= "Hash file to update vars (lpi_rootname,lpi_name,lpi_path,lpi_dirname,lpi_basename) (default: <lpi-base-name>.sha256" ) parser.add_option("-c", "--compress", action='store_true', dest="compress", default=False, help="Compress with UPX. (default: %default)") parser.add_option("-k", "--sign-key", dest="sign_key_path", help="Sign with this key. (default: %default)") parser.add_option("-w", "--sign-key-pwd-path", dest="sign_key_pwd_path", help="Path to password file. (default: %default)") parser.add_option("-t", "--target-dir", dest="target_dir", help="Target exe directory (default: ") (options, args) = parser.parse_args() if len(args) != 1: parser.usage sys.exit(1) if options.buildnr is None: r = Repo(wapt_root_dir, search_parent_directories=True) options.buildnr = str(r.active_branch.commit.count()) for lpi_path in args: lpi_path = os.path.abspath(lpi_path) (lpi_rootname, lpi_ext) = os.path.splitext(lpi_path) lpi_dirname = os.path.dirname(lpi_path) lpi_basename = os.path.basename(lpi_path) (lpi_name, lpi_ext) = os.path.splitext(os.path.basename(lpi_path)) print('Configure %s' % lpi_path) set_lpi_options(lpi_path, options.waptedition, waptutils.Version(options.waptversion, 4), options.buildnr) set_app_ico(lpi_path, options.waptedition) update_hash_file( os.path.abspath(options.update_hash_filepath.format(**locals()))) cmd = '"%s" --primary-config-path="%s" -B "%s"' % ( os.path.expandvars(options.lazbuildpath), os.path.expandvars( options.primary_config_path), os.path.expandvars(lpi_path)) print(u'Running: %s' % cmd) setuphelpers.run(cmd, cwd=os.path.dirname( os.path.expandvars(options.lazbuildpath))) (fn, ext) = os.path.splitext(get_lpi_output(lpi_path)) if ext in ('', '.'): ext = '.exe' exe_fn = os.path.abspath( os.path.abspath(os.path.join(lpi_dirname, fn + ext))) if options.compress: print(u'Compress %s with UPX' % exe_fn) setuphelpers.run('"%s" "%s"' % (os.path.join( setuphelpers.programfiles32, 'upx', 'upx.exe'), exe_fn)) if options.sign_key_path: sign_exe(exe_fn, options.sign_key_path, open(options.sign_key_pwd_path, 'rb').read())
(options, args) = parser.parse_args() logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s') if options.loglevel is not None: setloglevel(logger, options.loglevel) conf = waptserver.config.load_config(options.configfile) if conf['wapt_folder'].endswith('\\') or conf['wapt_folder'].endswith('/'): conf['wapt_folder'] = conf['wapt_folder'][:-1] log_directory = os.path.join(wapt_root_dir, 'log') if not os.path.exists(log_directory): os.mkdir(log_directory) run(r'icacls "%s" /t /grant "*S-1-5-20":(OI)(CI)(M)' % os.path.join(wapt_root_dir,'log')) if args == ['all']: args = ['install_nginx','install_postgresql','install_waptserver'] for action in args: if action == 'install_nginx': print('Installing nginx as a service managed by nssm') install_nginx_service(options,conf) elif action == 'install_postgresql': print('Installing PostgreSQL as a service managed by nssm') install_postgresql_service(options,conf) elif action == 'install_waptserver': print('Installing WAPT Server as a service managed by nssm') install_waptserver_service(options,conf) if os.path.isfile(os.path.join(wapt_root_dir,'waptenterprise','waptserver','wsus_tasks.py')):
def install_windows_nssm_service( service_name, service_binary, service_parameters, service_logfile, service_dependencies=None): """Setup a program as a windows Service managed by nssm >>> install_windows_nssm_service("WAPTServer", os.path.abspath(os.path.join(wapt_root_dir,'waptpython.exe')), os.path.abspath(__file__), os.path.join(log_directory,'nssm_waptserver.log'), service_logfile, 'WAPTApache') """ import setuphelpers from setuphelpers import registry_set, REG_DWORD, REG_EXPAND_SZ, REG_MULTI_SZ, REG_SZ datatypes = { 'dword': REG_DWORD, 'sz': REG_SZ, 'expand_sz': REG_EXPAND_SZ, 'multi_sz': REG_MULTI_SZ, } if setuphelpers.service_installed(service_name): if not setuphelpers.service_is_stopped(service_name): logger.info('Stop running "%s"' % service_name) setuphelpers.run('net stop "%s" /yes' % service_name) while not setuphelpers.service_is_stopped(service_name): logger.debug('Waiting for "%s" to terminate' % service_name) time.sleep(2) logger.info('Unregister existing "%s"' % service_name) setuphelpers.run('sc delete "%s"' % service_name) if not setuphelpers.iswin64(): raise Exception('Windows 32bit install not supported') nssm = os.path.join(wapt_root_dir, 'waptservice', 'win64', 'nssm.exe') logger.info('Register service "%s" with nssm' % service_name) cmd = '"{nssm}" install "{service_name}" "{service_binary}" {service_parameters}'.format( nssm=nssm, service_name=service_name, service_binary=service_binary, service_parameters=service_parameters ) logger.info('running command : %s' % cmd) setuphelpers.run(cmd) # fix some parameters (quotes for path with spaces... params = { 'Description': 'sz:%s' % service_name, 'DelayedAutostart': 1, 'DisplayName': 'sz:%s' % service_name, 'AppStdout': r'expand_sz:{}'.format(service_logfile), 'ObjectName': r'NT AUTHORITY\NetworkService', 'Parameters\\AppStderr': r'expand_sz:{}'.format(service_logfile), 'Parameters\\AppParameters': r'expand_sz:{}'.format(service_parameters), 'Parameters\\AppNoConsole': 1, } root = setuphelpers.HKEY_LOCAL_MACHINE base = r'SYSTEM\CurrentControlSet\services\%s' % service_name for key in params: if isinstance(params[key], int): (valuetype, value) = ('dword', params[key]) elif ':' in params[key]: (valuetype, value) = params[key].split(':', 1) if valuetype == 'dword': value = int(value) else: (valuetype, value) = ('sz', params[key]) fullpath = base + '\\' + key (path, keyname) = fullpath.rsplit('\\', 1) if keyname == '@' or keyname == '': keyname = None registry_set(root, path, keyname, value, type=datatypes[valuetype]) if service_dependencies: logger.info( 'Register dependencies for service "%s" with nssm : %s ' % (service_name, service_dependencies)) cmd = '"{nssm}" set "{service_name}" DependOnService {service_dependencies}'.format( nssm=nssm, service_name=service_name, service_dependencies=service_dependencies ) logger.info('running command : %s' % cmd) setuphelpers.run(cmd)
def install_waptserver_service(options,conf=None): if setuphelpers.service_installed('WAPTServer'): if setuphelpers.service_is_running('WAPTServer'): setuphelpers.service_stop('WAPTServer') setuphelpers.service_delete('WAPTServer') if conf is None: conf = waptserver.config.load_config(options.configfile) conf_dir = os.path.join(wapt_root_dir,'conf') if not os.path.isdir(conf_dir): os.makedirs(conf_dir) run(r'icacls "%s" /t /grant "*S-1-5-20":(OI)(CI)(M)' % conf_dir) print("install waptserver") service_binary = os.path.abspath(os.path.join(wapt_root_dir,'waptpython.exe')) service_parameters = '"%s"' % os.path.join(wapt_root_dir,'waptserver','server.py') service_logfile = os.path.join(log_directory, 'nssm_waptserver.log') service_dependencies = 'WAPTPostgresql' install_windows_nssm_service('WAPTServer',service_binary,service_parameters,service_logfile,service_dependencies) tasks_db = os.path.join(wapt_root_dir,'db') mkdir_p(tasks_db) setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % tasks_db) if not conf.get('secret_key'): conf['secret_key'] = ''.join(random.SystemRandom().choice(string.letters + string.digits) for _ in range(64)) waptserver.config.write_config_file(options.configfile,conf) if options.setpassword: conf['wapt_password'] = pbkdf2_sha256.hash(base64.b64decode(options.setpassword).encode('utf8')) waptserver.config.write_config_file(options.configfile,conf) clients_signing_certificate = conf.get('clients_signing_certificate') clients_signing_key = conf.get('clients_signing_key') if not clients_signing_certificate or not clients_signing_key: clients_signing_certificate = os.path.join(wapt_root_dir,'conf','ca-%s.crt' % fqdn()) clients_signing_key = os.path.join(wapt_root_dir,'conf','ca-%s.pem' % fqdn()) conf['clients_signing_certificate'] = clients_signing_certificate conf['clients_signing_key'] = clients_signing_key waptserver.config.write_config_file(options.configfile,conf) if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(clients_signing_certificate): print('Create a certificate and key for clients certificate signing') key = SSLPrivateKey(clients_signing_key) if not os.path.isfile(clients_signing_key): print('Create SSL RSA Key %s' % clients_signing_key) key.create() key.save_as_pem() crt = key.build_sign_certificate(cn=fqdn(),is_code_signing=False,is_ca=True) print('Create X509 cert %s' % clients_signing_certificate) crt.save_as_pem(clients_signing_certificate) # ensure Packages index repo = WaptLocalRepo(conf['wapt_folder']) repo.update_packages_index() if setuphelpers.service_installed('WAPTServer'): if not setuphelpers.service_is_running('WAPTServer'): setuphelpers.service_start('WAPTServer')
def install_postgresql_service(options,conf=None): if conf is None: conf = waptserver.config.load_config(options.configfile) print ("install postgres database") pgsql_root_dir = r'%s\waptserver\pgsql-9.6' % wapt_root_dir pgsql_data_dir = r'%s\waptserver\pgsql_data-9.6' % wapt_root_dir pgsql_data_dir = pgsql_data_dir.replace('\\','/') print ("about to build database directory") if setuphelpers.service_installed('waptpostgresql') and setuphelpers.service_is_running('waptpostgresql'): print('stopping postgresql') setuphelpers.service_stop('waptpostgresql') # waiting for postgres to be ready time.sleep(2) if not os.path.exists(os.path.join(pgsql_data_dir,'postgresql.conf')): setuphelpers.mkdirs(pgsql_data_dir) # need to have specific write acls for current user otherwise initdb fails... setuphelpers.run(r'icacls "%s" /t /grant "%s":(OI)(CI)(M)' % (pgsql_data_dir,GetUserName())) setuphelpers.run(r'"%s\bin\initdb" -U postgres -E=UTF8 -D "%s"' % (pgsql_root_dir,pgsql_data_dir)) setuphelpers.run(r'icacls "%s" /t /grant "*S-1-5-20":(OI)(CI)(M)' % pgsql_data_dir) else: print("database already instanciated, doing nothing") print("start postgresql database") if setuphelpers.service_installed('WaptPostgresql'): if setuphelpers.service_is_running('WaptPostgresql'): setuphelpers.service_stop('waptPostgresql') setuphelpers.service_delete('waptPostgresql') cmd = r'"%s\bin\pg_ctl" register -N WAPTPostgresql -U "nt authority\networkservice" -S auto -D "%s" ' % (pgsql_root_dir ,pgsql_data_dir) run(cmd) setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % log_directory) setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % pgsql_data_dir) # try to migrate from old version (pg 9.4, wapt 1.5) old_pgsql_root_dir = r'%s\waptserver\pgsql' % wapt_root_dir old_pgsql_data_dir = r'%s\waptserver\pgsql_data' % wapt_root_dir old_pgsql_data_dir = old_pgsql_data_dir.replace('\\','/') if os.path.isdir(old_pgsql_data_dir) and os.path.isdir(old_pgsql_root_dir): print('migrating database from previous postgresql DB') migrate_pg_db(old_pgsql_root_dir,old_pgsql_data_dir,pgsql_root_dir,pgsql_data_dir) print('starting postgresql') if not setuphelpers.service_is_running('waptpostgresql'): setuphelpers.service_start('waptpostgresql') # waiting for postgres to be ready time.sleep(2) print("checking wapt database") import psycopg2 from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT conn = None cur = None try: conn = psycopg2.connect('dbname=template1 user=postgres') conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) cur = conn.cursor() cur.execute("select 1 from pg_roles where rolname='%(db_user)s'" % conf) val = cur.fetchone() if val is None: print("%(db_user)s pgsql user does not exists, creating %(db_user)s user" % conf) cur.execute("create user %(db_user)s" % conf) cur.execute("select 1 from pg_database where datname='%(db_name)s'" % conf) val = cur.fetchone() if val is None: print ("database %(db_name)s does not exists, creating %(db_name)s db" % conf) cur.execute("create database %(db_name)s owner %(db_user)s" % conf) finally: if cur: cur.close() if conn: conn.close() print("Creating/upgrading wapt db tables") run(r'"%s\waptpython.exe" "%s\waptserver\model.py" init_db -c "%s"' % (wapt_root_dir, wapt_root_dir, options.configfile )) print("Done") print('Import lcoal Packages data into database') repo = WaptLocalRepo(conf['wapt_folder']) load_db_config(conf) Packages.update_from_repo(repo)
def install_waptserver_service(options,conf=None): if setuphelpers.service_installed('WAPTServer'): if setuphelpers.service_is_running('WAPTServer'): setuphelpers.service_stop('WAPTServer') setuphelpers.service_delete('WAPTServer') if conf is None: conf = waptserver.config.load_config(options.configfile) conf_dir = os.path.join(wapt_root_dir,'conf') if not os.path.isdir(conf_dir): os.makedirs(conf_dir) run(r'icacls "%s" /t /grant "*S-1-5-20":(OI)(CI)(M)' % conf_dir) if not conf.get('server_uuid'): conf['server_uuid'] = str(uuid.uuid1()) waptserver.config.write_config_file(options.configfile,conf) print("install waptserver") service_binary = os.path.abspath(os.path.join(wapt_root_dir,'waptpython.exe')) service_parameters = '"%s"' % os.path.join(wapt_root_dir,'waptserver','server.py') service_logfile = os.path.join(log_directory, 'nssm_waptserver.log') service_dependencies = 'WAPTPostgresql' install_windows_nssm_service('WAPTServer',service_binary,service_parameters,service_logfile,service_dependencies) tasks_db = os.path.join(wapt_root_dir,'db') mkdir_p(tasks_db) setuphelpers.run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % tasks_db) if not conf.get('secret_key'): conf['secret_key'] = ''.join(random.SystemRandom().choice(string.letters + string.digits) for _ in range(64)) waptserver.config.write_config_file(options.configfile,conf) if options.setpassword: conf['wapt_password'] = pbkdf2_sha256.hash(base64.b64decode(options.setpassword).encode('utf8')) waptserver.config.write_config_file(options.configfile,conf) clients_signing_certificate = conf.get('clients_signing_certificate') clients_signing_key = conf.get('clients_signing_key') if not clients_signing_certificate or not clients_signing_key: clients_signing_certificate = os.path.join(wapt_root_dir,'conf','ca-%s.crt' % fqdn()) clients_signing_key = os.path.join(wapt_root_dir,'conf','ca-%s.pem' % fqdn()) conf['clients_signing_certificate'] = clients_signing_certificate conf['clients_signing_key'] = clients_signing_key waptserver.config.write_config_file(options.configfile,conf) if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(clients_signing_certificate): print('Create a certificate and key for clients certificate signing') key = SSLPrivateKey(clients_signing_key) if not os.path.isfile(clients_signing_key): print('Create SSL RSA Key %s' % clients_signing_key) key.create() key.save_as_pem() crt = key.build_sign_certificate(cn=fqdn(),is_code_signing=False,is_ca=True) print('Create X509 cert %s' % clients_signing_certificate) crt.save_as_pem(clients_signing_certificate) # ensure Packages index repo = WaptLocalRepo(conf['wapt_folder']) repo.update_packages_index() #Migrate file for new version waptwua wuafolder = conf['waptwua_folder'] for (root,dirs,files) in list(os.walk(wuafolder,topdown=False)): if root == os.path.join(wuafolder,'.stfolder'): continue for f in files: oldpath = os.path.join(root,f) newpath = os.path.join(wuafolder,f) if os.path.isfile(newpath): continue print('Move %s --> %s' % (oldpath,newpath)) os.rename(oldpath,newpath) for d in dirs: if d == '.stfolder': continue print('Delete folder %s' % os.path.join(root,d)) shutil.rmtree(os.path.join(root,d)) if setuphelpers.service_installed('WAPTServer'): if not setuphelpers.service_is_running('WAPTServer'): setuphelpers.service_start('WAPTServer')
def run_external(self, *args, **kwargs): """Run an external process, register pid in current task to be able to kill it""" result = setuphelpers.run(*args, pidlist=self.external_pids, **kwargs)
def on_trigger_host_action(self, args, result_callback=None): try: start_time = time.time() actions = args if not isinstance(actions, list): actions = [actions] # check signatures if not self.wapt: raise Exception('Wapt not available') verified_by = None for action in actions: logger.info('Host actions "%s" triggered by SocketIO by %s' % (action['action'], action['signer'])) name = action['action'] verified_by = None # full cert chain provided with the signed action if action.get('signer_certificate', None): signer_cert_ca = SSLCABundle() signer_cert_ca.add_certificates_from_pem( action['signer_certificate']) signer_cert_chain = signer_cert_ca.certificates() else: # only sha256 fingerprint provided. (lighter). issuer must be in the authorized cabundle signer_cert = self.wapt.cabundle.certificate( action['signer']) if signer_cert: signer_cert_chain = [signer_cert] else: signer_cert_chain = [] chain = self.wapt.cabundle.check_certificates_chain( signer_cert_chain) if chain: required_attributes = ['uuid', 'action'] if name in [ 'trigger_install_packages', 'trigger_remove_packages', 'trigger_forget_packages' ]: required_attributes.append('packages') if name in ['trigger_change_description']: required_attributes.append('computer_description') if name in waptservice_remote_actions: required_attributes.extend( waptservice_remote_actions[name]. required_attributes) verified_by = chain[0].verify_claim( action, max_age_secs=waptconfig.signature_clockskew, required_attributes=required_attributes) else: raise SSLVerifyException( 'Untrusted certificate %s for signed action %s, aborting' % (signer_cert_chain, action)) if not verified_by: raise SSLVerifyException( 'Bad signature for action %s, aborting' % action) if verified_by: verified_by = verified_by.get('verified_by', None) result = [] for action in actions: uuid = action['uuid'] if uuid != self.wapt.host_uuid: raise Exception('Task is not targeted to this host. task' 's uuid does not match host' 'uuid') name = action['action'] if name in ['trigger_cancel_all_tasks']: data = [ t.as_dict() for t in self.task_manager.cancel_all_tasks() ] result.append(data) elif name in ['trigger_host_update', 'trigger_host_register']: if name == 'trigger_host_update': task = WaptUpdate() elif name == 'trigger_host_register': task = WaptRegisterComputer( computer_description=action.get( 'computer_description', None)) task.force = action.get('force', False) task.notify_user = action.get('notify_user', False) task.notify_server_on_finish = action.get( 'notify_server', False) task.created_by = verified_by data = self.task_manager.add_task(task).as_dict() result.append(data) elif name in ['trigger_change_description']: desc = action.get('computer_description', None) if desc is not None: setuphelpers.set_computer_description(desc) msg = u'Computer description of %s changed to %s' % ( setuphelpers.get_hostname(), setuphelpers.get_computer_description()) if not setuphelpers.get_computer_description() == desc: raise Exception( u'Computer description has not been changed') result.append(dict( success=True, msg=msg, result=msg, )) if action.get('notify_server', False): task = WaptUpdate(created_by=verified_by) task.notify_server_on_finish = True self.task_manager.add_task(task) result.append(task.as_dict()) elif name == 'trigger_host_upgrade': notify_user = action.get('notify_user', False) notify_server_on_finish = action.get( 'notify_server', False) force = action.get('force', False) only_priorities = action.get('only_priorities', None) only_if_not_process_running = action.get( 'only_if_not_process_running', False) update_packages = action.get('update', True) if update_packages: result.append( self.task_manager.add_task( WaptUpdate( force=force, notify_user=notify_user, )).as_dict()) result.append( self.task_manager.add_task( WaptUpgrade(notify_user=notify_user, created_by=verified_by, only_priorities=only_priorities, only_if_not_process_running= only_if_not_process_running, force=force)).as_dict()) result.append( self.task_manager.add_task( WaptCleanup(notify_user=False, created_by=verified_by, priority=200)).as_dict()) elif name in [ 'trigger_install_packages', 'trigger_remove_packages', 'trigger_forget_packages' ]: packagenames = action['packages'] only_priorities = action.get('only_priorities', None) only_if_not_process_running = action.get( 'only_if_not_process_running', False) for packagename in packagenames: if name == 'trigger_install_packages': task = WaptPackageInstall(packagenames=packagename) elif name == 'trigger_remove_packages': task = WaptPackageRemove(packagenames=packagename) elif name == 'trigger_forget_packages': task = WaptPackageForget(packagenames=packagename) task.force = action.get('force', False) task.notify_user = action.get('notify_user', False) task.notify_server_on_finish = action.get( 'notify_server', False) task.created_by = verified_by task.only_priorities = only_priorities task.only_if_not_process_running = only_if_not_process_running result.append( self.task_manager.add_task(task).as_dict()) if name == 'trigger_install_packages': self.task_manager.add_task( WaptAuditPackage(packagenames=packagenames, force=task.force, notify_user=task.notify_user, notify_server_on_finish=task. notify_server_on_finish, priority=200)).as_dict() elif name == 'trigger_waptservicerestart': try: if platform.system() == 'Windows': msg = setuphelpers.create_onetime_task( 'waptservicerestart', 'cmd.exe', '/C net stop waptservice & net start waptservice' ) elif platform.system() == 'Darwin': msg = setuphelpers.run( 'launchctl unload /Library/LaunchDaemons/com.tranquilit.tis-waptagent.plist;launchctl trigload /Library/LaunchDaemons/com.tranquilit.tis-waptagent.plist;' ) else: msg = setuphelpers.run( 'systemctl restart waptservice') result.append(dict(success=True, msg=msg, result=msg)) except: # restart by nssm os._exit(10) elif name == 'trigger_longtask': task = WaptLongTask() task.force = args.get('force', False) task.notify_user = args.get('notify_user', False) task.notify_server_on_finish = args.get( 'notify_server', False) task.created_by = verified_by result.append(self.task_manager.add_task(task).as_dict()) elif name in waptservice_remote_actions: waptservice_remote_actions[name].trigger_action( self, action, verified_by) else: raise EWaptException('Unhandled remote action %s' % name) #self.emit('trigger_update_result',{'result':data}) if result_callback: result_callback( make_response(result, uuid=self.wapt.host_uuid, request_time=time.time() - start_time)) except BaseException as e: logger.info('Exception for actions %s: %s' % (repr(args), repr(e))) if result_callback: result_callback( make_response_from_exception(e, uuid=self.wapt.host_uuid, request_time=time.time() - start_time))
def install_windows_nssm_service(service_name, service_binary, service_parameters, service_logfile, service_dependencies=None): """Setup a program as a windows Service managed by nssm >>> install_windows_nssm_service("WAPTServer", os.path.abspath(os.path.join(wapt_root_dir,'waptpython.exe')), os.path.abspath(__file__), os.path.join(log_directory,'nssm_waptserver.log'), service_logfile, 'WAPTApache') """ import setuphelpers from setuphelpers import registry_set, REG_DWORD, REG_EXPAND_SZ, REG_MULTI_SZ, REG_SZ datatypes = { 'dword': REG_DWORD, 'sz': REG_SZ, 'expand_sz': REG_EXPAND_SZ, 'multi_sz': REG_MULTI_SZ, } if setuphelpers.service_installed(service_name): if not setuphelpers.service_is_stopped(service_name): logger.info('Stop running "%s"' % service_name) setuphelpers.run('net stop "%s" /yes' % service_name) while not setuphelpers.service_is_stopped(service_name): logger.debug('Waiting for "%s" to terminate' % service_name) time.sleep(2) logger.info('Unregister existing "%s"' % service_name) setuphelpers.run('sc delete "%s"' % service_name) if not setuphelpers.iswin64(): raise Exception('Windows 32bit install not supported') nssm = os.path.join(wapt_root_dir, 'waptservice', 'win64', 'nssm.exe') logger.info('Register service "%s" with nssm' % service_name) cmd = '"{nssm}" install "{service_name}" "{service_binary}" {service_parameters}'.format( nssm=nssm, service_name=service_name, service_binary=service_binary, service_parameters=service_parameters) logger.info('running command : %s' % cmd) setuphelpers.run(cmd) # fix some parameters (quotes for path with spaces... params = { 'Description': 'sz:%s' % service_name, 'DelayedAutostart': 1, 'DisplayName': 'sz:%s' % service_name, 'AppStdout': r'expand_sz:{}'.format(service_logfile), 'ObjectName': r'NT AUTHORITY\NetworkService', 'Parameters\\AppStderr': r'expand_sz:{}'.format(service_logfile), 'Parameters\\AppParameters': r'expand_sz:{}'.format(service_parameters), 'Parameters\\AppNoConsole': 1, } root = setuphelpers.HKEY_LOCAL_MACHINE base = r'SYSTEM\CurrentControlSet\services\%s' % service_name for key in params: if isinstance(params[key], int): (valuetype, value) = ('dword', params[key]) elif ':' in params[key]: (valuetype, value) = params[key].split(':', 1) if valuetype == 'dword': value = int(value) else: (valuetype, value) = ('sz', params[key]) fullpath = base + '\\' + key (path, keyname) = fullpath.rsplit('\\', 1) if keyname == '@' or keyname == '': keyname = None registry_set(root, path, keyname, value, type=datatypes[valuetype]) if service_dependencies: logger.info('Register dependencies for service "%s" with nssm : %s ' % (service_name, service_dependencies)) cmd = '"{nssm}" set "{service_name}" DependOnService {service_dependencies}'.format( nssm=nssm, service_name=service_name, service_dependencies=service_dependencies) logger.info('running command : %s' % cmd) setuphelpers.run(cmd)
def main(): if len(args) == 0: print "ERROR : You must provide one action to perform" parser.print_usage() sys.exit(2) action = args[0] # Config file if not os.path.isfile(config_file): logger.error("Error : could not find file : " + config_file + ", please check the path") logger.debug("Config file: %s" % config_file) defaults = { "repositories": "", "repo_url": "", "default_source_url": "", "private_key": "", "public_cert": "", "default_development_base": "c:\tranquilit", "default_package_prefix": "tis", "default_sources_suffix": "wapt", "default_sources_url": "", "upload_cmd": "", "wapt_server": "", "loglevel": "info", } cp = RawConfigParser(defaults=defaults) cp.add_section("global") cp.read(config_file) global loglevel if not loglevel and cp.has_option("global", "loglevel"): loglevel = cp.get("global", "loglevel") setloglevel(loglevel) mywapt = Wapt(config=cp) if options.wapt_url: mywapt.wapt_repourl = options.wapt_url if options.private_key: mywapt.private_key = options.private_key else: mywapt.private_key = cp.get("global", "private_key") mywapt.dry_run = options.dry_run # logger.info("Main wapt Repository %s" % mywapt.wapt_repourl) logger.debug("WAPT base directory : %s" % mywapt.wapt_base_dir) logger.debug("Package cache dir : %s" % mywapt.packagecachedir) logger.debug("WAPT DB Structure version;: %s" % mywapt.waptdb.db_version) try: params_dict = {} try: params_dict = json.loads(options.params.replace("'", '"')) except: raise Exception("Install Parameters must be in json format") if action == "install" or action == "download": if len(args) < 2: print "You must provide at least one package name" sys.exit(1) if os.path.isdir(args[1]) or os.path.isfile(args[1]): print "installing WAPT file %s" % args[1] if action == "install": mywapt.install_wapt(args[1], params_dict=params_dict) else: print "%sing WAPT packages %s" % (action, ",".join(args[1:])) if options.update_packages: print "Update package list" mywapt.update() result = mywapt.install( args[1:], force=options.force, params_dict=params_dict, download_only=(action == "download") ) print "\nResults :" if action <> "download": for k in ("install", "additional", "upgrade", "skipped", "errors"): if result.get(k, []): print "\n=== %s packages ===\n%s" % ( k, "\n".join( [" %-30s | %s (%s)" % (s[0], s[1].package, s[1].version) for s in result[k]] ), ) else: for k in ("downloaded", "skipped", "errors"): if result.get("downloads", {"downloaded": [], "skipped": [], "errors": []})[k]: print "\n=== %s packages ===\n%s" % ( k, "\n".join([" %s" % (s,) for s in result["downloads"][k]]), ) elif action == "download": if len(args) < 2: print "You must provide at least one package name to download" sys.exit(1) if options.update_packages: print "Update package list" mywapt.update() print "Downloading packages %s" % (",".join(args[1:]),) result = mywapt.download_packages(args[1:], usecache=not options.force) if result["downloaded"]: print "\nDownloaded packages : \n%s" % "\n".join([" %s" % p for p in result["downloaded"]]) if result["skipped"]: print "Skipped packages : \n%s" % "\n".join([" %s" % p for p in result["skipped"]]) if result["errors"]: logger.critical("Unable to download some files : %s" % (result["errors"],)) sys.exit(1) elif action == "show": if len(args) < 2: print "You must provide at least one package name to show" sys.exit(1) if os.path.isdir(args[1]) or os.path.isfile(args[1]): entry = PackageEntry().load_control_from_wapt(args[1]) print "%s" % entry else: print "Display package control data for %s\n" % (",".join(args[1:]),) if options.update_packages: print "Update package list" mywapt.update() for packagename in args[1:]: entries = mywapt.waptdb.packages_matching(packagename) if entries: for e in entries: print "%s\n" % e.ascontrol(with_non_control_attributes=True) else: print "None packages found matching package name and version" elif action == "show-params": if len(args) < 2: print "You must provide at one package name to show params for" sys.exit(1) for packagename in args[1:]: params = mywapt.waptdb.params(packagename) print "%s" % params elif action == "list-registry": print "%-39s%-70s%-20s%-70s" % ("UninstallKey", "Software", "Version", "Uninstallstring") print "-" * 39 + "-" * 70 + "-" * 20 + "-" * 70 for p in setuphelpers.installed_softwares(" ".join(args[1:])): print u"%-39s%-70s%-20s%-70s" % (p["key"], p["name"], p["version"], p["uninstall_string"]) elif action == "showlog": if len(args) < 2: print "You must provide at least one package name" sys.exit(1) for packagename in args[1:]: result = mywapt.last_install_log(packagename) print "Package : %s\nStatus : %s\n\nInstallation log:\n%s" % ( packagename, result["status"], result["log"], ) elif action == "remove": if len(args) < 2: print "You must provide at least one package name to remove" sys.exit(1) for packagename in args[1:]: print "Removing %s ..." % (packagename,), mywapt.remove(packagename, force=options.force) print "done" elif action == "session-setup": if len(args) < 2: print "You must provide at least one package to be configured in user's session" sys.exit(1) for packagename in args[1:]: print "Configuring %s ..." % (packagename,), mywapt.session_setup(packagename, params_dict=params_dict) print "done" elif action == "uninstall": # launch the setup.uninstall() procedure for the given packages # can be used when registering in registry a custom install with a python script if len(args) < 2: print "You must provide at least one package to be uninstalled" sys.exit(1) for packagename in args[1:]: print "uninstalling %s ..." % (packagename,), mywapt.uninstall(packagename, params_dict=params_dict) print "uninstall done" elif action == "update": print "Update package list" result = mywapt.update() print "Total packages : %i" % result["count"] print "Added packages : \n%s" % "\n".join([" %s (%s)" % p for p in result["added"]]) print "Removed packages : \n%s" % "\n".join([" %s (%s)" % p for p in result["removed"]]) print "Repositories URL : \n%s" % "\n".join([" %s" % p for p in result["repos"]]) elif action == "upgradedb": (old, new) = mywapt.waptdb.upgradedb() if old == new: print "No database upgrade required, current %s, required %s" % (old, mywapt.waptdb.curr_db_version) else: print "Old version : %s to new : %s" % (old, new) elif action == "upgrade": if options.update_packages: print "Update package list" mywapt.update() result = mywapt.upgrade() if not result["install"] and not result["additional"] and not result["upgrade"] and not result["skipped"]: print "Nothing to upgrade" else: for k in ("install", "additional", "upgrade", "skipped", "errors"): if result[k]: print "\n=== %s packages ===\n%s" % ( k, "\n".join([" %-30s | %s (%s)" % (s[0], s[1].package, s[1].version) for s in result[k]]), ) sys.exit(0) elif action == "list-upgrade": if options.update_packages: print "Update package list" mywapt.update() q = mywapt.list_upgrade() if not q: print "Nothing to upgrade" else: print ppdicttable([p[0] for p in q], [("package", 20), ("version", 10)]) elif action == "download-upgrade": if options.update_packages: print "Update package list" mywapt.update() result = mywapt.download_upgrades() print "Downloaded packages : \n%s" % "\n".join([" %s" % p for p in result["downloaded"]]) print "Skipped packages : \n%s" % "\n".join([" %s" % p for p in result["skipped"]]) if result["errors"]: logger.critical("Unable to download some files : %s" % (result["errors"],)) sys.exit(1) elif action == "update-packages": if len(args) < 2: print "You must provide the directory" sys.exit(1) print update_packages(args[1]) elif action == "sources": if len(args) < 2: print "You must provide the package name" sys.exit(1) os.startfile(mywapt.get_sources(args[1])) elif action == "make-template": if len(args) < 2: print "You must provide the installer path" sys.exit(1) source_dir = mywapt.maketemplate(*args[1:]) print "Template created. You can build the WAPT package by launching\n %s build-package %s" % ( sys.argv[0], source_dir, ) os.startfile(source_dir) elif action == "make-host-template": source_dir = mywapt.makehosttemplate(*args[1:]) print "Template created. You can build the WAPT package by launching\n %s build-package %s" % ( sys.argv[0], source_dir, ) os.startfile(source_dir) elif action == "build-package": if len(args) < 2: print "You must provide at least one source directory for package build" sys.exit(1) for source_dir in [os.path.abspath(p) for p in args[1:]]: if os.path.isdir(source_dir): print ("Building %s" % source_dir) result = mywapt.buildpackage( source_dir, inc_package_release=options.increlease, excludes=options.excludes.split(",") ) package_fn = result["filename"] if package_fn: print "Package content:" for f in result["files"]: print " %s" % f[0] print ("...done. Package filename %s" % (package_fn,)) def pwd_callback(*args): """Default password callback for opening private keys""" return open(options.private_key_passwd, "r").read() if mywapt.private_key: print ("Signing %s" % package_fn) if options.private_key_passwd: signature = mywapt.signpackage( package_fn, excludes=options.excludes.split(","), callback=pwd_callback ) else: signature = mywapt.signpackage(package_fn, excludes=options.excludes.split(",")) print "Package %s signed : signature :\n%s" % (package_fn, signature) else: logger.warning("No private key provided, package %s is unsigned !" % package_fn) if mywapt.upload_cmd: print "\nYou can upload to repository with\n %s upload-package %s " % ( sys.argv[0], package_fn, ) return 0 else: logger.critical("package not created") return 1 else: logger.critical("Directory %s not found" % source_dir) elif action == "sign-package": if len(args) < 2: print "You must provide at least one source directory or package to sign" sys.exit(1) for waptfile in [os.path.abspath(p) for p in args[1:]]: if os.path.isdir(waptfile) or os.path.isfile(waptfile): print ("Signing %s" % waptfile) signature = mywapt.signpackage(waptfile, excludes=options.excludes.split(",")) print "Package %s signed : signature :\n%s" % (waptfile, signature) else: logger.critical("Package %s not found" % waptfile) return 1 elif action == "upload-package": if len(args) < 2: print "You must provide a package to upload" sys.exit(1) waptfiles = [] for a in args[1:]: waptfiles += glob.glob(a) waptfile_arg = " ".join(['"%s"' % f for f in waptfiles]) print setuphelpers.run(mywapt.upload_cmd % {"waptfile": waptfile_arg}) if mywapt.after_upload: print setuphelpers.run(mywapt.after_upload % {"waptfile": waptfile_arg}) elif action == "search": if options.update_packages: print "Update package list" mywapt.update() result = mywapt.waptdb.packages_search(args[1:]) print ppdicttable(result, (("package", 30), ("version", 10), ("description", 80))) elif action == "cleanup": result = mywapt.cleanup() print "Removed files : \n%s" % "\n".join([" %s" % p for p in result]) elif action == "inventory": print mywapt.inventory() elif action == "setup-tasks": print mywapt.setup_tasks() elif action == "list": def cb(fieldname, value): if value and fieldname == "install_date": return value[0:16] else: return value print ppdicttable( mywapt.waptdb.installed_search(args[1:]).values(), (("package", 20), ("version", 15), ("install_status", 10), ("install_date", 16), ("description", 80)), callback=cb, ) else: print "Unknown action %s" % action sys.exit(1) except Exception, e: print "FATAL ERROR : %s" % e if logger.level == logging.DEBUG: raise sys.exit(3)
def main(): if len(args) == 0: print "ERROR : You must provide one action to perform" parser.print_usage() sys.exit(2) action = args[0] # Config file if not os.path.isfile(config_file): logger.error("Error : could not find file : " + config_file + ", please check the path") logger.debug('Config file: %s' % config_file) defaults = { 'repositories': '', 'repo_url': '', 'default_source_url': '', 'private_key': '', 'public_cert': '', 'default_development_base': 'c:\tranquilit', 'default_package_prefix': 'tis', 'default_sources_suffix': 'wapt', 'default_sources_url': '', 'upload_cmd': '', 'wapt_server': '', 'loglevel': 'info', } cp = RawConfigParser(defaults=defaults) cp.add_section('global') cp.read(config_file) global loglevel if not loglevel and cp.has_option('global', 'loglevel'): loglevel = cp.get('global', 'loglevel') setloglevel(loglevel) mywapt = Wapt(config=cp) if options.wapt_url: mywapt.wapt_repourl = options.wapt_url if options.private_key: mywapt.private_key = options.private_key else: mywapt.private_key = cp.get('global', 'private_key') mywapt.dry_run = options.dry_run #logger.info("Main wapt Repository %s" % mywapt.wapt_repourl) logger.debug('WAPT base directory : %s' % mywapt.wapt_base_dir) logger.debug('Package cache dir : %s' % mywapt.packagecachedir) logger.debug('WAPT DB Structure version;: %s' % mywapt.waptdb.db_version) try: params_dict = {} try: params_dict = json.loads(options.params.replace("'", '"')) except: raise Exception('Install Parameters must be in json format') if action == 'install' or action == 'download': if len(args) < 2: print "You must provide at least one package name" sys.exit(1) if os.path.isdir(args[1]) or os.path.isfile(args[1]): print "installing WAPT file %s" % args[1] if action == 'install': mywapt.install_wapt(args[1], params_dict=params_dict) else: print "%sing WAPT packages %s" % (action, ','.join(args[1:])) if options.update_packages: print "Update package list" mywapt.update() result = mywapt.install( args[1:], force=options.force, params_dict=params_dict, download_only=(action == 'download'), ) print "\nResults :" if action <> 'download': for k in ('install', 'additional', 'upgrade', 'skipped', 'errors'): if result.get(k, []): print "\n=== %s packages ===\n%s" % ( k, '\n'.join([ " %-30s | %s (%s)" % (s[0], s[1].package, s[1].version) for s in result[k] ]), ) else: for k in ('downloaded', 'skipped', 'errors'): if result.get('downloads', { 'downloaded': [], 'skipped': [], 'errors': [] })[k]: print "\n=== %s packages ===\n%s" % ( k, '\n'.join([ " %s" % (s, ) for s in result['downloads'][k] ]), ) elif action == 'download': if len(args) < 2: print "You must provide at least one package name to download" sys.exit(1) if options.update_packages: print "Update package list" mywapt.update() print "Downloading packages %s" % (','.join(args[1:]), ) result = mywapt.download_packages(args[1:], usecache=not options.force) if result['downloaded']: print "\nDownloaded packages : \n%s" % "\n".join( [" %s" % p for p in result['downloaded']]) if result['skipped']: print "Skipped packages : \n%s" % "\n".join( [" %s" % p for p in result['skipped']]) if result['errors']: logger.critical('Unable to download some files : %s' % (result['errors'], )) sys.exit(1) elif action == 'show': if len(args) < 2: print "You must provide at least one package name to show" sys.exit(1) if os.path.isdir(args[1]) or os.path.isfile(args[1]): entry = PackageEntry().load_control_from_wapt(args[1]) print "%s" % entry else: print "Display package control data for %s\n" % (','.join( args[1:]), ) if options.update_packages: print "Update package list" mywapt.update() for packagename in args[1:]: entries = mywapt.waptdb.packages_matching(packagename) if entries: for e in entries: print "%s\n" % e.ascontrol( with_non_control_attributes=True) else: print "None packages found matching package name and version" elif action == 'show-params': if len(args) < 2: print "You must provide at one package name to show params for" sys.exit(1) for packagename in args[1:]: params = mywapt.waptdb.params(packagename) print "%s" % params elif action == 'list-registry': print "%-39s%-70s%-20s%-70s" % ('UninstallKey', 'Software', 'Version', 'Uninstallstring') print '-' * 39 + '-' * 70 + '-' * 20 + '-' * 70 for p in setuphelpers.installed_softwares(' '.join(args[1:])): print u"%-39s%-70s%-20s%-70s" % ( p['key'], p['name'], p['version'], p['uninstall_string']) elif action == 'showlog': if len(args) < 2: print "You must provide at least one package name" sys.exit(1) for packagename in args[1:]: result = mywapt.last_install_log(packagename) print "Package : %s\nStatus : %s\n\nInstallation log:\n%s" % ( packagename, result['status'], result['log']) elif action == 'remove': if len(args) < 2: print "You must provide at least one package name to remove" sys.exit(1) for packagename in args[1:]: print "Removing %s ..." % (packagename, ), mywapt.remove(packagename, force=options.force) print "done" elif action == 'session-setup': if len(args) < 2: print "You must provide at least one package to be configured in user's session" sys.exit(1) for packagename in args[1:]: print "Configuring %s ..." % (packagename, ), mywapt.session_setup(packagename, params_dict=params_dict) print "done" elif action == 'uninstall': # launch the setup.uninstall() procedure for the given packages # can be used when registering in registry a custom install with a python script if len(args) < 2: print "You must provide at least one package to be uninstalled" sys.exit(1) for packagename in args[1:]: print "uninstalling %s ..." % (packagename, ), mywapt.uninstall(packagename, params_dict=params_dict) print "uninstall done" elif action == 'update': print "Update package list" result = mywapt.update() print "Total packages : %i" % result['count'] print "Added packages : \n%s" % "\n".join( [" %s (%s)" % p for p in result['added']]) print "Removed packages : \n%s" % "\n".join( [" %s (%s)" % p for p in result['removed']]) print "Repositories URL : \n%s" % "\n".join( [" %s" % p for p in result['repos']]) elif action == 'upgradedb': (old, new) = mywapt.waptdb.upgradedb() if old == new: print "No database upgrade required, current %s, required %s" % ( old, mywapt.waptdb.curr_db_version) else: print "Old version : %s to new : %s" % (old, new) elif action == 'upgrade': if options.update_packages: print "Update package list" mywapt.update() result = mywapt.upgrade() if not result['install'] and not result[ 'additional'] and not result['upgrade'] and not result[ 'skipped']: print "Nothing to upgrade" else: for k in ('install', 'additional', 'upgrade', 'skipped', 'errors'): if result[k]: print "\n=== %s packages ===\n%s" % ( k, '\n'.join([ " %-30s | %s (%s)" % (s[0], s[1].package, s[1].version) for s in result[k] ]), ) sys.exit(0) elif action == 'list-upgrade': if options.update_packages: print "Update package list" mywapt.update() q = mywapt.list_upgrade() if not q: print "Nothing to upgrade" else: print ppdicttable([p[0] for p in q], [('package', 20), ('version', 10)]) elif action == 'download-upgrade': if options.update_packages: print "Update package list" mywapt.update() result = mywapt.download_upgrades() print "Downloaded packages : \n%s" % "\n".join( [" %s" % p for p in result['downloaded']]) print "Skipped packages : \n%s" % "\n".join( [" %s" % p for p in result['skipped']]) if result['errors']: logger.critical('Unable to download some files : %s' % (result['errors'], )) sys.exit(1) elif action == 'update-packages': if len(args) < 2: print "You must provide the directory" sys.exit(1) print update_packages(args[1]) elif action == 'sources': if len(args) < 2: print "You must provide the package name" sys.exit(1) os.startfile(mywapt.get_sources(args[1])) elif action == 'make-template': if len(args) < 2: print "You must provide the installer path" sys.exit(1) source_dir = mywapt.maketemplate(*args[1:]) print "Template created. You can build the WAPT package by launching\n %s build-package %s" % ( sys.argv[0], source_dir) os.startfile(source_dir) elif action == 'make-host-template': source_dir = mywapt.makehosttemplate(*args[1:]) print "Template created. You can build the WAPT package by launching\n %s build-package %s" % ( sys.argv[0], source_dir) os.startfile(source_dir) elif action == 'build-package': if len(args) < 2: print "You must provide at least one source directory for package build" sys.exit(1) for source_dir in [os.path.abspath(p) for p in args[1:]]: if os.path.isdir(source_dir): print('Building %s' % source_dir) result = mywapt.buildpackage( source_dir, inc_package_release=options.increlease, excludes=options.excludes.split(',')) package_fn = result['filename'] if package_fn: print "Package content:" for f in result['files']: print " %s" % f[0] print('...done. Package filename %s' % (package_fn, )) def pwd_callback(*args): """Default password callback for opening private keys""" return open(options.private_key_passwd, 'r').read() if mywapt.private_key: print('Signing %s' % package_fn) if options.private_key_passwd: signature = mywapt.signpackage( package_fn, excludes=options.excludes.split(','), callback=pwd_callback) else: signature = mywapt.signpackage( package_fn, excludes=options.excludes.split(',')) print "Package %s signed : signature :\n%s" % ( package_fn, signature) else: logger.warning( 'No private key provided, package %s is unsigned !' % package_fn) if mywapt.upload_cmd: print '\nYou can upload to repository with\n %s upload-package %s ' % ( sys.argv[0], package_fn) return 0 else: logger.critical('package not created') return 1 else: logger.critical('Directory %s not found' % source_dir) elif action == 'sign-package': if len(args) < 2: print "You must provide at least one source directory or package to sign" sys.exit(1) for waptfile in [os.path.abspath(p) for p in args[1:]]: if os.path.isdir(waptfile) or os.path.isfile(waptfile): print('Signing %s' % waptfile) signature = mywapt.signpackage( waptfile, excludes=options.excludes.split(',')) print "Package %s signed : signature :\n%s" % (waptfile, signature) else: logger.critical('Package %s not found' % waptfile) return 1 elif action == 'upload-package': if len(args) < 2: print "You must provide a package to upload" sys.exit(1) waptfiles = [] for a in args[1:]: waptfiles += glob.glob(a) waptfile_arg = " ".join(['"%s"' % f for f in waptfiles]) print setuphelpers.run(mywapt.upload_cmd % {'waptfile': waptfile_arg}) if mywapt.after_upload: print setuphelpers.run(mywapt.after_upload % {'waptfile': waptfile_arg}) elif action == 'search': if options.update_packages: print "Update package list" mywapt.update() result = mywapt.waptdb.packages_search(args[1:]) print ppdicttable(result, (('package', 30), ('version', 10), ('description', 80))) elif action == 'cleanup': result = mywapt.cleanup() print "Removed files : \n%s" % "\n".join( [" %s" % p for p in result]) elif action == 'inventory': print mywapt.inventory() elif action == 'setup-tasks': print mywapt.setup_tasks() elif action == 'list': def cb(fieldname, value): if value and fieldname == 'install_date': return value[0:16] else: return value print ppdicttable( mywapt.waptdb.installed_search(args[1:]).values(), (('package', 20), ('version', 15), ('install_status', 10), ('install_date', 16), ('description', 80)), callback=cb) else: print 'Unknown action %s' % action sys.exit(1) except Exception, e: print "FATAL ERROR : %s" % e if logger.level == logging.DEBUG: raise sys.exit(3)