def __init__(self): self.file_crypt = FileCrypt() self.config = self.load_config() self.pyi_updater = PyiUpdater(self.config) self.key_handler = KeyHandler() self.package_handler = PackageHandler() self.uploader = Uploader() self.update_helpers(self.pyi_updater) helpers = { u'key_handler': self.key_handler, u'package_handler': self.package_handler, u'uploader': self.uploader, u'file_crypt': self.file_crypt, u'config': self.config, u'save': self.save_config, } self.keys_menu = keys.Keys(helpers) self.settings_menu = settings.Settings(helpers) self.sign_menu = sign.Sign(helpers) self.upload_menu = upload.Upload(helpers) header = u'Main Menu' options = [(u'Sign Updates', self.sign_menu), (u'Upload', self.upload_menu), (u'Keys', self.keys_menu), (u'Settings', self.settings_menu), (u'Quit', self.quit)] super(Worker, self).__init__(header, options)
def test_original_init(): config = TConfig() updater = PyiUpdater(config) client = Client(updater, test=True) assert client.app_name == u'jms' assert client.update_urls[0] == (u'https://s3-us-west-1.amazon' 'aws.com/pyi-test/')
def test_set_uploader_bad_settings(): config = TConfig() config.ACCESS_KEY_ID = None config.SECRET_ACCESS_KEY = u'Not an actual secret' config.BUCKET_NAME = u'Bucket Name' s_nst = PyiUpdater(config) uploader = Uploader(s_nst) uploader.set_uploader(u's3')
def setup_func(): global test_data_dir config = TConfig() updater = PyiUpdater(config) ph = PackageHandler(updater) kh = KeyHandler(updater) kh.test = True ph.setup() kh.make_keys()
def make_keys(): pyi = PyiUpdater(DefaultConfig()) key_handler = KeyHandler(pyi) # Making a new set of keys # Keys will be place in the keys # Directory, in the pyi-data folder # *** Should not be ran again after # you deploy your app!!!! *** # If you need to make new keys pass # overwrite=True to make_keys key_handler.make_keys()
def setup(): # Setting up Config object default_config = DefaultConfig() # Initilizing Main object and configuring # in one step pyi = PyiUpdater(default_config) # Can also update config later pyi.update_config(default_config) # Initializing Package Handler & Key Handler # with config info package_handler = PackageHandler(pyi) key_handler = KeyHandler(pyi) # Can also be Initilized without config package_handler = PackageHandler() key_handler = KeyHandler() # Then update handlers with config later package_handler.init_app(pyi) key_handler.init_app(pyi) # Setting up work directories # Only need to run once on a new project but it's # ok if ran multipule times package_handler.setup() # Now place new packages in the folder named # "new" in the pyi-data directory # Package Archive filename should be in the form # AppName-platform-version.zip raw_input('Place updates in new folder then press enter.') # This updates the version file with the # new packages & moves them to the deploy folder. package_handler.process_packages() # This signs the update manifest & copies it # to the deploy folder key_handler.sign_update()
def test_setup(): global test_data_dir config = TConfig() updater = PyiUpdater(config) ph = PackageHandler(updater) key_dir = os.path.join(ph.data_dir, u'keys') kh = KeyHandler(updater) kh.test = True assert os.path.exists(os.path.abspath(key_dir)) assert kh.private_key_name == u'jms.pem' assert kh.public_key_name == u'jms.pub'
def test_execution(): global test_data_dir config = TConfig() updater = PyiUpdater(config) ph = PackageHandler(updater) kh = KeyHandler(updater) ph.setup() kh.test = True kh.make_keys() # Make zipfile with ChDir(test_data_dir): os.mkdir(u'test-app') with ChDir(u'test-app'): with open(u'app.txt', u'w') as f: f.write(u'I am so happy' * 1000) shutil.make_archive(u'Test App-mac-0.2.0', u'zip', u'test-app') shutil.move(u'Test App-mac-0.2.0.zip', u'new') ph.process_packages() kh.sign_update()
class Worker(Menu, CommonLogic): def __init__(self): self.file_crypt = FileCrypt() self.config = self.load_config() self.pyi_updater = PyiUpdater(self.config) self.key_handler = KeyHandler() self.package_handler = PackageHandler() self.uploader = Uploader() self.update_helpers(self.pyi_updater) helpers = { u'key_handler': self.key_handler, u'package_handler': self.package_handler, u'uploader': self.uploader, u'file_crypt': self.file_crypt, u'config': self.config, u'save': self.save_config, } self.keys_menu = keys.Keys(helpers) self.settings_menu = settings.Settings(helpers) self.sign_menu = sign.Sign(helpers) self.upload_menu = upload.Upload(helpers) header = u'Main Menu' options = [(u'Sign Updates', self.sign_menu), (u'Upload', self.upload_menu), (u'Keys', self.keys_menu), (u'Settings', self.settings_menu), (u'Quit', self.quit)] super(Worker, self).__init__(header, options) # self.menu = Menu(header, options) def update_helpers(self, pyi_updater): self.file_crypt.init_app(pyi_updater) self.key_handler.init_app(pyi_updater) self.key_handler._add_filecrypt(self.file_crypt) self.package_handler.init_app(pyi_updater) self.uploader.init_app(pyi_updater) log.debug(u'Updated helpers') def start(self): while 1: dec_path = os.path.join(cwd, u'config.data') enc_path = os.path.join(cwd, u'config.data.enc') if not os.path.exists(dec_path) and not os.path.exists(enc_path): self.initial_setup() x = self.display() if len(x) == 2: next_ = x[1] next_() # We are dynamically generating upload options # from installed plugins. So the option selected # by the user needs a little extra processing else: name = x[0] func = x[1] func(name) def quit(self): lex_file = os.path.join(cwd, u'lextab.py') yac_file = os.path.join(cwd, u'yacctab.py') if os.path.exists(lex_file): os.remove(lex_file) if os.path.exists(yac_file): os.remove(yac_file) log.debug('Quitting') print('See Ya!') sys.exit() def initial_setup(self): log.debug(u'Starting initial setup') self.display_menu_header(u'Setup Assistant') self.display_msg(u'Let\'s begin...') self.config.APP_NAME = get_correct_answer(u'Please enter app name', required=True) self.config.COMPANY_NAME = get_correct_answer(u'Please enter your ' 'company or name', required=True) self.config.DEV_DATA_DIR = cwd url = get_correct_answer(u'Enter a url to ping for updates.', required=True) self.config.UPDATE_URLS = [url] while 1: answer = ask_yes_no(u'Would you like to add another ' 'url for backup?', default='no') if answer is True: url = get_correct_answer(u'Enter another url.', required=True) self.config.UPDATE_URLS.append(url) else: break self.config.UPDATE_PATCHES = ask_yes_no(u'Would you like to enable ' 'patch updates?', default='yes') answer1 = ask_yes_no(u'Would you like to add scp settings?', default='no') answer2 = ask_yes_no(u'Would you like to add S3 settings?', default='no') if answer1: self.config.REMOTE_DIR = get_correct_answer(u'Enter remote dir', required=True) self.config.HOST = get_correct_answer(u'Enter host', required=True) self.config.USERNAME = get_correct_answer(u'Enter usernmae', required=True) key_path = get_correct_answer(u'Enter path to ssh key', required=True) # Path to private key self.config.PASSWORD = _directory_fixer(key_path) if answer2: self.config.USERNAME = get_correct_answer(u'Enter access key ID', required=True) self.config.PASSWORD = get_correct_answer(u'Enter secret ' 'Access Key', required=True) self.config.REMOTE_DIR = get_correct_answer(u'Enter bucket name', required=True) password = verify_password(u'Enter password') self.file_crypt._update_timer() self.save_config(self.config, password) self.package_handler.setup() print(u'Making keys...') self.keys_menu.make_keys() self.display_menu_header(u'Setup Complete') self.display_msg(u'Now let\'s update some apps') time.sleep(3) def save_config(self, obj, password=None): self.pyi_updater.update_config(obj) self.update_helpers(self.pyi_updater) log.debug(u'Saving Config') filename = os.path.join(cwd, u'config.data') self.file_crypt.new_file(filename) # We do this here to keep from asking users # password again when we encrypt the file if password is not None: password = self.file_crypt._gen_password(password) self.file_crypt.password = password with open(filename, 'w') as f: f.write(str(pickle.dumps(obj))) self.file_crypt.encrypt() self.write_config_py(obj) def load_config(self): log.debug(u'Loading Config') filename = os.path.join(cwd, u'config.data') salt_file = os.path.join(cwd, u'pyi-data', u'keys', u'salt') self.file_crypt.salt_file = salt_file self.file_crypt.new_file(filename) try: self.file_crypt.decrypt() except FileCryptPasswordError: sys.exit(u'Failed password attempt') except Exception as e: log.error(str(e), exc_info=True) log.warning(u'No enc file. Will try to load plain config') try: with open(filename, 'r') as f: config_data = pickle.loads(f.read()) self.file_crypt.encrypt() except Exception as e: log.error(e, exc_info=True) config_data = SetupConfig() return config_data def write_config_py(self, obj): filename = os.path.join(cwd, u'client_config.py') attr_str_format = " {} = '{}'\n" attr_format = " {} = {}\n" with open(filename, u'w') as f: f.write('class ClientConfig(object):\n') if hasattr(obj, 'APP_NAME') and obj.APP_NAME is not None: f.write(attr_str_format.format('APP_NAME', obj.APP_NAME)) if hasattr(obj, 'COMPANY_NAME') and obj.COMPANY_NAME is not None: f.write(attr_str_format.format('COMPANY_NAME', obj.COMPANY_NAME)) if hasattr(obj, 'UPDATE_URLS') and obj.UPDATE_URLS is not None: f.write(attr_format.format('UPDATE_URLS', obj.UPDATE_URLS)) if hasattr(obj, 'PUBLIC_KEY') and obj.PUBLIC_KEY is not None: f.write(attr_str_format.format('PUBLIC_KEY', obj.PUBLIC_KEY))
def test_dev_dir_none(): updater = PyiUpdater(__name__) myconfig = TConfig() myconfig.APP_NAME = None updater.update_config(myconfig) assert updater.config[u'APP_NAME'] == u'PyiUpdater App'
import sys from nose.tools import raises, with_setup sys.path.insert( 0, os.path.join(os.path.dirname(os.path.dirname(__file__)), u'src')) from pyi_updater import PyiUpdater from pyi_updater.exceptions import UploaderError from pyi_updater.uploader import Uploader from tconfig import TConfig my_config = TConfig() updater = PyiUpdater(my_config) uploader = Uploader(updater) def setup_func(): if not os.path.exists(uploader.deploy_dir): os.makedirs(uploader.deploy_dir) def teardown_func(): if os.path.exists(uploader.deploy_dir): shutil.rmtree(os.path.dirname(uploader.deploy_dir)) @raises(UploaderError) def test_set_uploader_int_param():
class Worker(Menu, CommonLogic): def __init__(self): self.file_crypt = FileCrypt() self.config = self.load_config() self.pyi_updater = PyiUpdater(self.config) self.key_handler = KeyHandler() self.package_handler = PackageHandler() self.uploader = Uploader() self.update_helpers(self.pyi_updater) helpers = { u'key_handler': self.key_handler, u'package_handler': self.package_handler, u'uploader': self.uploader, u'file_crypt': self.file_crypt, u'config': self.config, u'save': self.save_config, } self.keys_menu = keys.Keys(helpers) self.settings_menu = settings.Settings(helpers) self.sign_menu = sign.Sign(helpers) self.upload_menu = upload.Upload(helpers) header = u'Main Menu' options = [(u'Sign Updates', self.sign_menu), (u'Upload', self.upload_menu), (u'Keys', self.keys_menu), (u'Settings', self.settings_menu), (u'Quit', self.quit)] super(Worker, self).__init__(header, options) # self.menu = Menu(header, options) def update_helpers(self, pyi_updater): self.file_crypt.init_app(pyi_updater) self.key_handler.init_app(pyi_updater) self.key_handler._add_filecrypt(self.file_crypt) self.package_handler.init_app(pyi_updater) self.uploader.init_app(pyi_updater) log.debug(u'Updated helpers') def start(self): while 1: dec_path = os.path.join(cwd, u'config.data') enc_path = os.path.join(cwd, u'config.data.enc') if not os.path.exists(dec_path) and not os.path.exists(enc_path): self.initial_setup() x = self.display() if len(x) == 2: next_ = x[1] next_() # We are dynamically generating upload options # from installed plugins. So the option selected # by the user needs a little extra processing else: name = x[0] func = x[1] func(name) def quit(self): lex_file = os.path.join(cwd, u'lextab.py') yac_file = os.path.join(cwd, u'yacctab.py') if os.path.exists(lex_file): os.remove(lex_file) if os.path.exists(yac_file): os.remove(yac_file) log.debug('Quitting') print('See Ya!') sys.exit() def initial_setup(self): log.debug(u'Starting initial setup') self.display_menu_header(u'Setup Assistant') self.display_msg(u'Let\'s begin...') self.config.APP_NAME = get_correct_answer(u'Please enter app name', required=True) self.config.COMPANY_NAME = get_correct_answer( u'Please enter your ' 'company or name', required=True) self.config.DEV_DATA_DIR = cwd url = get_correct_answer(u'Enter a url to ping for updates.', required=True) self.config.UPDATE_URLS = [url] while 1: answer = ask_yes_no( u'Would you like to add another ' 'url for backup?', default='no') if answer is True: url = get_correct_answer(u'Enter another url.', required=True) self.config.UPDATE_URLS.append(url) else: break self.config.UPDATE_PATCHES = ask_yes_no( u'Would you like to enable ' 'patch updates?', default='yes') answer1 = ask_yes_no(u'Would you like to add scp settings?', default='no') answer2 = ask_yes_no(u'Would you like to add S3 settings?', default='no') if answer1: self.config.REMOTE_DIR = get_correct_answer(u'Enter remote dir', required=True) self.config.HOST = get_correct_answer(u'Enter host', required=True) self.config.USERNAME = get_correct_answer(u'Enter usernmae', required=True) key_path = get_correct_answer(u'Enter path to ssh key', required=True) # Path to private key self.config.PASSWORD = _directory_fixer(key_path) if answer2: self.config.USERNAME = get_correct_answer(u'Enter access key ID', required=True) self.config.PASSWORD = get_correct_answer( u'Enter secret ' 'Access Key', required=True) self.config.REMOTE_DIR = get_correct_answer(u'Enter bucket name', required=True) password = verify_password(u'Enter password') self.file_crypt._update_timer() self.save_config(self.config, password) self.package_handler.setup() print(u'Making keys...') self.keys_menu.make_keys() self.display_menu_header(u'Setup Complete') self.display_msg(u'Now let\'s update some apps') time.sleep(3) def save_config(self, obj, password=None): self.pyi_updater.update_config(obj) self.update_helpers(self.pyi_updater) log.debug(u'Saving Config') filename = os.path.join(cwd, u'config.data') self.file_crypt.new_file(filename) # We do this here to keep from asking users # password again when we encrypt the file if password is not None: password = self.file_crypt._gen_password(password) self.file_crypt.password = password with open(filename, 'w') as f: f.write(str(pickle.dumps(obj))) self.file_crypt.encrypt() self.write_config_py(obj) def load_config(self): log.debug(u'Loading Config') filename = os.path.join(cwd, u'config.data') salt_file = os.path.join(cwd, u'pyi-data', u'keys', u'salt') self.file_crypt.salt_file = salt_file self.file_crypt.new_file(filename) try: self.file_crypt.decrypt() except FileCryptPasswordError: sys.exit(u'Failed password attempt') except Exception as e: log.error(str(e), exc_info=True) log.warning(u'No enc file. Will try to load plain config') try: with open(filename, 'r') as f: config_data = pickle.loads(f.read()) self.file_crypt.encrypt() except Exception as e: log.error(e, exc_info=True) config_data = SetupConfig() return config_data def write_config_py(self, obj): filename = os.path.join(cwd, u'client_config.py') attr_str_format = " {} = '{}'\n" attr_format = " {} = {}\n" with open(filename, u'w') as f: f.write('class ClientConfig(object):\n') if hasattr(obj, 'APP_NAME') and obj.APP_NAME is not None: f.write(attr_str_format.format('APP_NAME', obj.APP_NAME)) if hasattr(obj, 'COMPANY_NAME') and obj.COMPANY_NAME is not None: f.write( attr_str_format.format('COMPANY_NAME', obj.COMPANY_NAME)) if hasattr(obj, 'UPDATE_URLS') and obj.UPDATE_URLS is not None: f.write(attr_format.format('UPDATE_URLS', obj.UPDATE_URLS)) if hasattr(obj, 'PUBLIC_KEY') and obj.PUBLIC_KEY is not None: f.write(attr_str_format.format('PUBLIC_KEY', obj.PUBLIC_KEY))
def setup_func(): config = TConfig() updater = PyiUpdater(config) ph = PackageHandler(updater) ph.setup()
from nose import with_setup import shutil import sys from jms_utils.paths import ChDir sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from pyi_updater import PyiUpdater from pyi_updater.key_handler import KeyHandler from pyi_updater.package_handler import PackageHandler from pyi_updater.utils import remove_dot_files from tconfig import TConfig pyi_updater = PyiUpdater(TConfig()) kh = KeyHandler(pyi_updater) kh.test = True kh._add_filecrypt() ph = PackageHandler(pyi_updater) PYI_DATA = os.path.abspath(os.path.join(u'tests', u'pyi-data')) def setup_func(): ph.setup() kh.make_keys() test_data_dir = os.path.abspath( os.path.join(u'tests', u'test data', u'5.0')) with ChDir(test_data_dir): files = remove_dot_files(os.listdir(os.getcwd()))