diff --git a/CHANGELOG.md b/CHANGELOG.md index 16925ca..82fd679 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## [Unreleased] +## [v1.16.2] -* b984048 - Add requirements_tests.txt to VersionEye +* Add requirements_tests.txt to VersionEye +* Remove cnh and dotcloudng scripts ## [v1.16.1] @@ -94,8 +95,3 @@ This project adheres to [Semantic Versioning](http://semver.org/). * 078051c - Automate new version release via Jenkins * c257751 - Update win32 install documentation - - -[unreleased]: https://github.com/cloudControl/cctrl/compare/v1.16.1...HEAD -[v1.16.1]: https://github.com/cloudControl/cctrl/compare/v1.16.0...v1.16.1 -[v1.16.0]: https://github.com/cloudControl/cctrl/compare/v1.15.2...v1.16.0 diff --git a/cctrl/output.py b/cctrl/output.py index 9bae5d6..a32cf58 100644 --- a/cctrl/output.py +++ b/cctrl/output.py @@ -20,31 +20,18 @@ import json import pipes -if sys.version_info < (2, 6): - has_str_format = False -else: - has_str_format = True - def print_list_apps(apps): """ Print a nice table of apps. """ print 'Apps' - if has_str_format: - print " {0:3} {1:30} {2:6}".format('Nr', 'Name', 'Type') - for i, app in enumerate(apps): - print " {0:3} {1:30} {2:6}".format( - i + 1, - app['name'], - app['type']['name']) - else: - print " %-3ls %-30ls %-6ls" % ('Nr', 'Name', 'Type') - for i, app in enumerate(apps): - print " %-3ls %-30ls %-6ls" % ( - i + 1, - app['name'], - app['type']['name']) + print " {0:3} {1:30} {2:6}".format('Nr', 'Name', 'Type') + for i, app in enumerate(apps): + print " {0:3} {1:30} {2:6}".format( + i + 1, + app['name'], + app['type']['name']) def print_app_details(app, public_key): @@ -52,47 +39,27 @@ def print_app_details(app, public_key): Print app details. """ print 'App' - if has_str_format: - print " Name: {0:30} Type: {1:10} Owner: {2:20}".format( - app['name'], - app['type']['name'], - app['owner']['username']) - if app['type']['name'] == 'custom': - print ' Buildpack URL: {0}\n'.format(app['buildpack_url']) - print ' Repository: {0}'.format(app['repository']) - print '\n Public Key: {0}'.format(public_key) - - print '\n Users' - print " {0:15} {1:35} {2:10} {3:10}".format('Name', 'Email', 'Role', 'Deployment') - for user in app['users']: - print " {0:15} {1:35} {2:10} {3:10}".format( - user['username'], - user['email'], - user['role'] if 'role' in user else '', - user['deployment'] if 'deployment' in user else '(app)' - ) - print '\n Deployments' - for deployment in app['deployments']: - print " {0:60}".format(deployment['name']) - else: - print " Name: %-30ls Type: %-10ls Owner: %-20ls" % ( - app['name'], - app['type']['name'], - app['owner']['username']) - print ' Repository: %s' % (app['repository']) - print '\n Public Key: %s' % public_key - print '\n Users' - print " %-15ls %-35ls %-10ls %-10ls" % ('Name', 'Email', 'Role', 'Deployment') - for user in app['users']: - if 'deployment' not in user: - user['deployment'] = '(app)' - if 'role' not in user: - user['role'] = '' - - print " %(username)-15ls %(email)-35ls %(role)-10ls %(deployment)-10ls" % (user) - print '\n Deployments' - for deployment in app['deployments']: - print " %(name)-60ls" % (deployment) + print " Name: {0:30} Type: {1:10} Owner: {2:20}".format( + app['name'], + app['type']['name'], + app['owner']['username']) + if app['type']['name'] == 'custom': + print ' Buildpack URL: {0}\n'.format(app['buildpack_url']) + print ' Repository: {0}'.format(app['repository']) + print '\n Public Key: {0}'.format(public_key) + + print '\n Users' + print " {0:15} {1:35} {2:10} {3:10}".format('Name', 'Email', 'Role', 'Deployment') + for user in app['users']: + print " {0:15} {1:35} {2:10} {3:10}".format( + user['username'], + user['email'], + user['role'] if 'role' in user else '', + user['deployment'] if 'deployment' in user else '(app)' + ) + print '\n Deployments' + for deployment in app['deployments']: + print " {0:60}".format(deployment['name']) def print_deployment_details(deployment): @@ -107,154 +74,84 @@ def print_deployment_details(deployment): else: stack = None print 'Deployment' - if has_str_format: - print ' name: {0}'.format(deployment['name']) - print ' stack: {0}'.format(stack) - print ' URL: {0}'.format(url) - print ' branch: {0}'.format(deployment['branch']) - print ' last modified: {0}'.format(deployment['date_modified']) - print ' current version: {0}'.format(deployment['version']) - print ' current state: {0}'.format(deployment['state']) - print ' containers: {0}'.format(deployment['min_boxes']) - print ' memory: {0}MB'.format(deployment['max_boxes'] * 128) - - if 'users' in deployment and deployment['users']: - print '\n Users' - print " {0:15} {1:35} {2:10} {3:10}".format('Name', 'Email', 'Role', 'Deployment') - for user in deployment['users']: - print " {0:15} {1:35} {2:10} {3:10}".format( - user['username'], - user['email'], - user['role'], - '(app)' if 'app' in user else deployment['name'], - ) - - else: - print ' name: %(name)s' % (deployment) - print ' stack: %s' % (stack) - print ' URL: %s' % (url) - print ' branch: %(branch)s' % (deployment) - print ' last modified: %(date_modified)s' % (deployment) - print ' current version: %(version)s' % (deployment) - print ' current state: %(state)s' % (deployment) - print ' containers: %(min_boxes)s' % (deployment) - print ' memory: %(min_boxes)sMB' % (deployment) * 128 - - if 'users' in deployment and deployment['users']: - print '\n Users' - print " %-15ls %-35ls %-10ls %-10ls" % ('Name', 'Email', 'Role', 'Deployment') - for user in deployment['users']: - user['deployment'] = '(app)' if 'app' in user else deployment['name'] - print " %(username)-15ls %(email)-35ls %(role)-10ls %(deployment)-10ls" % (user) - - -def print_user_list_app(app): - print 'Users' - if has_str_format: + print ' name: {0}'.format(deployment['name']) + print ' stack: {0}'.format(stack) + print ' URL: {0}'.format(url) + print ' branch: {0}'.format(deployment['branch']) + print ' last modified: {0}'.format(deployment['date_modified']) + print ' current version: {0}'.format(deployment['version']) + print ' current state: {0}'.format(deployment['state']) + print ' containers: {0}'.format(deployment['min_boxes']) + print ' memory: {0}MB'.format(deployment['max_boxes'] * 128) + + if 'users' in deployment and deployment['users']: + print '\n Users' print " {0:15} {1:35} {2:10} {3:10}".format('Name', 'Email', 'Role', 'Deployment') - for user in app['users']: + for user in deployment['users']: print " {0:15} {1:35} {2:10} {3:10}".format( user['username'], user['email'], - user['role'] if 'role' in user else '', - user['deployment'] if 'deployment' in user else '(app)' + user['role'], + '(app)' if 'app' in user else deployment['name'], ) - else: - print " %-15ls %-35ls %-10ls %-10ls" % ('Name', 'Email', 'Role', 'Deployment') - for user in app['users']: - if 'deployment' not in user: - user['deployment'] = '(app)' - if 'role' not in user: - user['role'] = '' - print " %(username)-15ls %(email)-35ls %(role)-10ls %(deployment)-10ls" % (user) + +def print_user_list_app(app): + print 'Users' + print " {0:15} {1:35} {2:10} {3:10}".format('Name', 'Email', 'Role', 'Deployment') + for user in app['users']: + print " {0:15} {1:35} {2:10} {3:10}".format( + user['username'], + user['email'], + user['role'] if 'role' in user else '', + user['deployment'] if 'deployment' in user else '(app)' + ) def print_user_list_deployment(deployment): print 'Users' - if has_str_format: - print " {0:15} {1:35} {2:10} {3:10}".format('Name', 'Email', 'Role', 'Deployment') - for user in deployment['users']: - print " {0:15} {1:35} {2:10} {3:10}".format( - user['username'], - user['email'], - user['role'], - '(app)' if 'app' in user else deployment['name'], - ) - else: - print '\n Users' - print " %-15ls %-35ls %-10ls %-10ls" % ('Name', 'Email', 'Role', 'Deployment') - for user in deployment['users']: - user['deployment'] = '(app)' if 'app' in user else deployment['name'] - print " %(username)-15ls %(email)-35ls %(role)-10ls %(deployment)-10ls" % (user) + print " {0:15} {1:35} {2:10} {3:10}".format('Name', 'Email', 'Role', 'Deployment') + for user in deployment['users']: + print " {0:15} {1:35} {2:10} {3:10}".format( + user['username'], + user['email'], + user['role'], + '(app)' if 'app' in user else deployment['name'], + ) def print_alias_list(aliases): - """ - Print a list of aliases - """ - if has_str_format: - print 'Aliases' - print ' {0:60} {1:8} {2:8}'.format('name', 'default', 'verified') - for alias in aliases: - print ' {0:60} {1:8} {2:8}'.format( - alias['name'], - alias['is_default'], - alias['is_verified']) - else: - print 'Aliases' - print ' %-60ls %-8ls %-8ls' % ('name', 'default', 'verified') - for alias in aliases: - print ' %(name)-60ls %(is_default)-8ls %(is_verified)-8ls' % ( - alias) + """Print a list of aliases""" + print 'Aliases' + print ' {0:60} {1:8} {2:8}'.format('name', 'default', 'verified') + for alias in aliases: + print ' {0:60} {1:8} {2:8}'.format( + alias['name'], + alias['is_default'], + alias['is_verified']) def print_alias_details(alias): - """ - Print alias details. - """ - if has_str_format: - print '{0:28}: {1}'.format('Alias', alias['name']) - print ' {0:25}: {1}'.format( - 'is_default', - str(alias['is_default'])) - print ' {0:25}: {1}'.format( - 'is_verified', - str(alias['is_verified'])) - print ' {0:25}: {1}'.format( - 'verification_errors', - alias['verification_errors']) - print ' {0:25}: {1}'.format( - 'verification_code', - alias['verification_code']) - print ' {0:25}: {1}'.format( - 'date_created', - alias['date_created']) - print ' {0:25}: {1}'.format( - 'date_modified', - alias['date_modified']) - else: - print '%-28ls: %s' % ( - 'Alias', - alias['name']) - print ' %-25ls: %s' % ( - 'is_default', - str(alias['is_default'])) - print ' %-25ls: %s' % ( - 'is_verified', - str(alias['is_verified'])) - print ' %-25ls: %s' % ( - 'verification_errors', - alias['verification_errors']) - print ' %-25ls: %s' % ( - 'verification_code', - alias['verification_code']) - print ' %-25ls: %s' % ( - 'date_created', - alias['date_created']) - print ' %-25ls: %s' % ( - 'date_modified', - alias['date_modified']) + """Print alias details.""" + print '{0:28}: {1}'.format('Alias', alias['name']) + print ' {0:25}: {1}'.format( + 'is_default', + str(alias['is_default'])) + print ' {0:25}: {1}'.format( + 'is_verified', + str(alias['is_verified'])) + print ' {0:25}: {1}'.format( + 'verification_errors', + alias['verification_errors']) + print ' {0:25}: {1}'.format( + 'verification_code', + alias['verification_code']) + print ' {0:25}: {1}'.format( + 'date_created', + alias['date_created']) + print ' {0:25}: {1}'.format( + 'date_modified', + alias['date_modified']) def print_log_entries(logEntries, apache_type): @@ -264,129 +161,67 @@ def print_log_entries(logEntries, apache_type): Either access or error. """ if apache_type == 'access': - if has_str_format: - for entry in logEntries: - dt = datetime.fromtimestamp(float(entry["time"])) - entry["time"] = dt.strftime('[%d/%b/%Y:%H:%M:%S +0000]') - try: - print r'{0} {1} {2} {3} "{4}" {5} {6} "{7}" "{8}"'.format( - entry["remote_host"], - entry["remote_logname"], - entry["remote_user"], - entry["time"], - entry["first_request_line"], - entry["status"], - entry["response_size_CLF"], - entry["referer"], - entry["user_agent"]) - except KeyError: - pass - else: - for entry in logEntries: - dt = datetime.fromtimestamp(float(entry["time"])) - entry["time"] = dt.strftime('[%d/%b/%Y:%H:%M:%S +0000]') - try: - print r'%s %s %s %s "%s" %s %s "%s" "%s"' % ( - entry["remote_host"], - entry["remote_logname"], - entry["remote_user"], - entry["time"], - entry["first_request_line"], - entry["status"], - entry["response_size_CLF"], - entry["referer"], - entry["user_agent"]) - except KeyError: - pass - elif apache_type == 'error': - if has_str_format: - for entry in logEntries: - dt = datetime.fromtimestamp(float(entry["time"])) - entry["time"] = dt.strftime('[%a %b %d %H:%M:%S %Y]') - print r'{0} {1} {2}'.format( + for entry in logEntries: + dt = datetime.fromtimestamp(float(entry["time"])) + entry["time"] = dt.strftime('[%d/%b/%Y:%H:%M:%S +0000]') + try: + print r'{0} {1} {2} {3} "{4}" {5} {6} "{7}" "{8}"'.format( + entry["remote_host"], + entry["remote_logname"], + entry["remote_user"], entry["time"], - entry["type"], - entry["message"].encode('utf-8')) - else: - for entry in logEntries: - dt = datetime.fromtimestamp(float(entry["time"])) - entry["time"] = dt.strftime('[%a %b %d %H:%M:%S %Y]') - print r'%s %s %s' % ( - entry["time"], - entry["type"], - entry["message"].encode('utf-8')) + entry["first_request_line"], + entry["status"], + entry["response_size_CLF"], + entry["referer"], + entry["user_agent"]) + except KeyError: + pass + elif apache_type == 'error': + for entry in logEntries: + dt = datetime.fromtimestamp(float(entry["time"])) + entry["time"] = dt.strftime('[%a %b %d %H:%M:%S %Y]') + print r'{0} {1} {2}'.format( + entry["time"], + entry["type"], + entry["message"].encode('utf-8')) elif apache_type == 'worker': - if has_str_format: - for entry in logEntries: - dt = datetime.fromtimestamp(float(entry["time"])) - entry["time"] = dt.strftime('[%a %b %d %H:%M:%S %Y]') - print r'{0} {1} {2}'.format( - entry["time"], - entry["wrk_id"], - entry["message"].encode('utf-8')) - else: - for entry in logEntries: - dt = datetime.fromtimestamp(float(entry["time"])) - entry["time"] = dt.strftime('[%a %b %d %H:%M:%S %Y]') - print r'%s %s %s' % ( - entry["time"], - entry["wrk_id"], - entry["message"].encode('utf-8')) + for entry in logEntries: + dt = datetime.fromtimestamp(float(entry["time"])) + entry["time"] = dt.strftime('[%a %b %d %H:%M:%S %Y]') + print r'{0} {1} {2}'.format( + entry["time"], + entry["wrk_id"], + entry["message"].encode('utf-8')) elif apache_type == 'deploy': - if has_str_format: - for entry in logEntries: - dt = datetime.fromtimestamp(float(entry["time"])) - entry["time"] = dt.strftime('[%a %b %d %H:%M:%S %Y]') - print r'{0} {1} {2} {3}'.format( - entry["time"], - entry['hostname'], - entry["level"], - entry["message"].encode('utf-8')) - else: - for entry in logEntries: - dt = datetime.fromtimestamp(float(entry["time"])) - entry["time"] = dt.strftime('[%a %b %d %H:%M:%S %Y]') - print r'%s %s %s %s' % ( - entry["time"], - entry['hostname'], - entry["level"], - entry["message"].encode('utf-8')) + for entry in logEntries: + dt = datetime.fromtimestamp(float(entry["time"])) + entry["time"] = dt.strftime('[%a %b %d %H:%M:%S %Y]') + print r'{0} {1} {2} {3}'.format( + entry["time"], + entry['hostname'], + entry["level"], + entry["message"].encode('utf-8')) def print_keys(keys): - """ - Print a list of keys. - """ + """Print a list of keys.""" print 'Keys' - if has_str_format: - for key in keys: - print ' {0:15}'.format(key['key_id']) - else: - for key in keys: - print ' %(key_id)-15ls' % (key) + for key in keys: + print ' {0:15}'.format(key['key_id']) def print_key(key): - """ - Print a users public key. - """ + """Print a users public key.""" print key["key"] def print_addons(addons): - """ - Print all available addons. - """ - if has_str_format: - for addon in addons: - print '\nAddon: {0}'.format(addon['name']) - for option in addon['options']: - print ' {0}'.format(option['name']) - else: - for addon in addons: - print '\nAddon: %s' % (addon['name']) - for option in addon['options']: - print ' %s' % option['name'] + """Print all available addons.""" + for addon in addons: + print '\nAddon: {0}'.format(addon['name']) + for option in addon['options']: + print ' {0}'.format(option['name']) def print_addon_creds(addons): @@ -399,102 +234,61 @@ def print_addon_creds(addons): def print_addon_list(addons): - """ - Print a list of addon details - """ + """Print a list of addon details""" for addon in addons: print_addon_details(addon) print '\n' def print_addon_details(addon): - """ - Print addon details. - """ - if has_str_format: - print '{0:25}: {1}'.format('Addon', addon['addon_option']['name']) - if len(addon['settings']) > 0: - print ' \n Settings' - for key, value in addon['settings'].items(): - print ' {0:25}: {1}'.format(key, value) - else: - print '%-25ls: %s' % ('Addon', addon['addon_option']['name']) - if len(addon['settings']) > 0: - print ' \n Settings' - for key, value in addon['settings'].items(): - print ' %-25ls: %s' % (key, value) + """Print addon details.""" + print '{0:25}: {1}'.format('Addon', addon['addon_option']['name']) + if len(addon['settings']) > 0: + print ' \n Settings' + for key, value in addon['settings'].items(): + print ' {0:25}: {1}'.format(key, value) def print_worker_list(workers): print 'Workers' - if has_str_format: - print ' {0:3} {1:11} {2}'.format('nr.', 'wrk_id', 'command') - for count, worker in enumerate(workers): - print ' {0:3} {1:11} {2}'.format(count + 1, worker['wrk_id'], worker['command']) - else: - print ' %-3ls %-11ls %s' % ('nr.', 'wrk_id', 'command') - for count, worker in enumerate(workers): - print ' %-3ls %-11ls %s' % (count + 1, worker['wrk_id'], worker['command']) + print ' {0:3} {1:11} {2}'.format('nr.', 'wrk_id', 'command') + for count, worker in enumerate(workers): + print ' {0:3} {1:11} {2}'.format(count + 1, worker['wrk_id'], worker['command']) def print_worker_details(worker): print 'Worker' - if has_str_format: - print ' {0:9}: {1}'.format('wrk_id', worker['wrk_id']) - try: - print ' {0:9}: {1}'.format('command', worker['command'].encode('utf-8')) - except UnicodeDecodeError: - print ' {0:9}: {1}'.format('command', worker['command']) - print ' {0:9}: {1}'.format('params', worker['params']) - print ' {0:9}: {1}'.format('size', worker['size']) - print ' {0:9}: {1}'.format('created', worker['date_created']) - else: - print ' %-9ls: %s' % ('wrk_id', worker['wrk_id']) - print ' %-9ls: %s' % ('command', worker['command']) - print ' %-9ls: %s' % ('params', worker['params']) - print ' %-9ls: %s' % ('size', worker['size']) - print ' %-9ls: %s' % ('created', worker['date_created']) + print ' {0:9}: {1}'.format('wrk_id', worker['wrk_id']) + try: + print ' {0:9}: {1}'.format('command', worker['command'].encode('utf-8')) + except UnicodeDecodeError: + print ' {0:9}: {1}'.format('command', worker['command']) + print ' {0:9}: {1}'.format('params', worker['params']) + print ' {0:9}: {1}'.format('size', worker['size']) + print ' {0:9}: {1}'.format('created', worker['date_created']) def print_cronjob_list(cronjobs): print 'Cronjobs' - if has_str_format: - print ' {0:3} {1:11}'.format('nr.', 'job_id') - for count, cronjob in enumerate(cronjobs): - print ' {0:3} {1:11}'.format(count + 1, cronjob['job_id']) - else: - print ' %-3ls %-11ls' % ('nr.', 'job_id') - for count, cronjob in enumerate(cronjobs): - job_id = cronjob['wrk_id'] - print ' %-3ls %-11ls' % (count + 1, job_id) + print ' {0:3} {1:11}'.format('nr.', 'job_id') + for count, cronjob in enumerate(cronjobs): + print ' {0:3} {1:11}'.format(count + 1, cronjob['job_id']) def print_cronjob_details(cronjob): print 'Cronjob' - if has_str_format: - print ' {0:9}: {1}'.format('job_id', cronjob['job_id']) - print ' {0:9}: {1}'.format('url', cronjob['url']) - print ' {0:9}: {1}'.format('next_run', cronjob['next_run']) - print ' {0:9}: {1}'.format('created', cronjob['date_created']) - print ' {0:9}: {1}'.format('modified', cronjob['date_modified']) - else: - print ' %-9ls: %s' % ('job_id', cronjob['job_id']) - print ' %-9ls: %s' % ('url', cronjob['url']) - print ' %-9ls: %s' % ('next_run', cronjob['next_run']) - print ' %-9ls: %s' % ('created', cronjob['date_created']) - print ' %-9ls: %s' % ('modified', cronjob['date_modified']) + print ' {0:9}: {1}'.format('job_id', cronjob['job_id']) + print ' {0:9}: {1}'.format('url', cronjob['url']) + print ' {0:9}: {1}'.format('next_run', cronjob['next_run']) + print ' {0:9}: {1}'.format('created', cronjob['date_created']) + print ' {0:9}: {1}'.format('modified', cronjob['date_modified']) def get_version(cctrlversion, cclibversion): - """ - Prepare the version string - """ - if has_str_format: - return '%(prog)s {0} using pycclib {1}'.format( - cctrlversion, - cclibversion) - else: - return '%%(prog)s %s using pycclib %s' % (cctrlversion, cclibversion) + """Prepare the version string""" + return '%(prog)s {0} using pycclib {1}'.format( + cctrlversion, + cclibversion) def print_config(config, key=None): diff --git a/cctrl/version.py b/cctrl/version.py index 186d8bc..b14f5f9 100644 --- a/cctrl/version.py +++ b/cctrl/version.py @@ -1,2 +1,2 @@ # -*- coding: utf-8 -*- -__version__ = '1.16.1' +__version__ = '1.16.2' diff --git a/requirements.txt b/requirements.txt index 8bc6b6e..75c45fb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,6 @@ -pycclib>=1.6.0 -argparse==1.3.0 -paramiko>=1.15.2 +certifi==2016.2.28 +ecdsa==0.13 +httplib2==0.9.2 +paramiko==1.17.0 +pycclib==1.6.2 +pycrypto==2.6.1 diff --git a/setup-py2exe.py b/setup-py2exe.py new file mode 100644 index 0000000..829e6bb --- /dev/null +++ b/setup-py2exe.py @@ -0,0 +1,18 @@ +import os.path +from distutils.core import setup + +import py2exe + +execfile(os.path.join(os.path.dirname(__file__), 'cctrl', 'version.py')) + +setup( + name="cctrl", + version=__version__, + description="cloudControl command line utilities", + author="cloudControl Team", + author_email="info@cloucontrol.de", + license="Apache 2.0", + console=["cctrl/cctrlapp", "cctrl/cctrluser", + "cctrl/exoapp", "cctrl/exouser"], + data_files=[("", ["cctrl/cacerts.txt"])] +) diff --git a/setup.py b/setup.py index 35e6455..1f899e3 100644 --- a/setup.py +++ b/setup.py @@ -1,68 +1,17 @@ -# -*- coding: utf-8 -*- -""" - setup script for cloudControl command line utilities - - usage: sudo python setup.py install -""" - import os import sys -from setuptools import setup, find_packages -from cctrl.version import __version__ - - -execfile(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'cctrl', 'version.py')) +from setuptools import setup -if sys.version_info < (2, 6): - required = ['simplejson'] -else: - required = [] -required.append('pycclib>=1.6.0') -required.append('argparse>=1.1') -required.append('paramiko>=1.15.2') +execfile(os.path.join(os.path.dirname(__file__), 'cctrl', 'version.py')) -srcscripts = ['cctrl/cctrlapp', 'cctrl/cctrluser', 'cctrl/exoapp', 'cctrl/exouser', 'cctrl/dcapp', 'cctrl/dcuser', 'cctrl/cnhapp', 'cctrl/cnhuser'] +required = [ + 'pycclib>=1.6.0', + 'paramiko>=1.15.2,<2', +] -if sys.platform == 'win32': - import py2exe - - required.append('paramiko') - required.append('ecdsa') - extra_options = dict( - setup_requires=['py2exe'], - console=srcscripts, - zipfile=None, - data_files=[("", ["cctrl/cacerts.txt", ])], - options={ - "py2exe": { - "compressed": True, - "optimize": 2, - "excludes": [ - '_scproxy', - 'hexdump', - 'isapi', - 'pythoncom', - 'pywintypes', - 'simplejson', - 'socks', - 'win32com', - 'win32com.client', - 'doctest', - 'pickle', - 'difflib', - 'unittest'], - "includes": ["argparse", "pycclib", "paramiko", "Crypto", "ecdsa"], - "packages": find_packages() - } - } - ) -else: - extra_options = dict( - scripts=srcscripts, - package_data={"cctrl": ["cacerts.txt"]}, - packages=find_packages() - ) +if sys.version_info < (2, 7): + required.append('argparse') setup( name="cctrl", @@ -88,59 +37,8 @@ install_requires=required, tests_require=['mock'], test_suite='tests', - **extra_options -) - -setup( - name="dotcloudng", - version=__version__, - description='dotcloud command line utilities', - author='dotcloud Team', - author_email='info@dotcloud.com', - url='https://www.dotcloud.com', - license='Apache 2.0', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Programming Language :: Python', - 'Topic :: Internet' - ], - install_requires=required, - tests_require=['mock'], - test_suite='tests', - **extra_options -) - -setup( - name="cnh", - version=__version__, - description='cloud&heat command line utilities', - author='cloudControl Team', - author_email='info@cloudcontrol.com', - url='https://www.cloudcontrol.com', - license='Apache 2.0', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Programming Language :: Python', - 'Topic :: Internet' - ], - install_requires=required, - tests_require=['mock'], - test_suite='tests', - **extra_options + scripts=["cctrl/cctrlapp", "cctrl/cctrluser", + "cctrl/exoapp", "cctrl/exouser"], + package_data={"cctrl": ["cacerts.txt"]}, + packages=['cctrl'] ) diff --git a/win32/.gitattributes b/win32/.gitattributes new file mode 100644 index 0000000..04e0085 --- /dev/null +++ b/win32/.gitattributes @@ -0,0 +1 @@ +*.iss text eol=crlf diff --git a/win32/README.md b/win32/README.md index 75df571..e7f2ce9 100644 --- a/win32/README.md +++ b/win32/README.md @@ -1,26 +1,24 @@ Building cloudControl CLI Windows installer ============================ -### PRE-INSTALLATION STEPS - -1. Install python 2.7.6 via msi installer: [http://www.python.org/download/releases/2.7.6/](http://www.python.org/download/releases/2.7.6/) -2. Install setuptools: [https://bitbucket.org/pypa/setuptools#rst-header-windows](https://bitbucket.org/pypa/setuptools#rst-header-windows) -3. Install pycrypto for python 2.7: [http://www.voidspace.org.uk/python/modules.shtml#pycrypto](http://www.voidspace.org.uk/python/modules.shtml#pycrypto) -4. Install p2exe: [http://sourceforge.net/projects/py2exe](http://sourceforge.net/projects/py2exe) -5. Install Inno Setup: [http://www.jrsoftware.org/isdl.php#stable](http://www.jrsoftware.org/isdl.php#stable) -6. Install git bash: [http://msysgit.github.io/](http://msysgit.github.io/) - -### BUILDING CLI FOR SPECIFIC ENVIRONMENT +### PRE-INSTALLATION STEPS + +1. Install https://www.python.org/ftp/python/2.7.11/python-2.7.11.msi +2. Install [Microsoft Visual C++ Compiler for Python 2.7 +](https://www.microsoft.com/en-us/download/details.aspx?id=44266) +3. Install py2exe: [http://sourceforge.net/projects/py2exe](http://sourceforge.net/projects/py2exe) +4. Install Inno Setup: [http://www.jrsoftware.org/isdl.php#stable](http://www.jrsoftware.org/isdl.php#stable) +5. Install git bash: [http://msysgit.github.io/](http://msysgit.github.io/) + +### BUILDING * To start build, simply execute (use git bash): ~~~bash - $ win32/build_installer.sh ENV PATH_TO_CCTRL_DIR + $ win32/build_installer.sh ~~~ where: - - - `ENV` is `[cctrl|dotcloudng]` - `PATH_TO_CCTRL_DIR` is an optional parameter specifying path to cctrl source directory. If not specified build script will clone master version. -Optionally, you can specify locations of `Python` and `ISCC` home directories by setting these env variables: `PYTHON_HOME` and `ISCC_HOME`. After successful build, executable file is located in `win32setup` directory. \ No newline at end of file +Optionally, you can specify locations of `Python` and `ISCC` home directories by setting these env variables: `PYTHON_HOME` and `ISCC_HOME`. After successful build, executable file is located in `win32setup` directory. diff --git a/win32/build_installer.sh b/win32/build_installer.sh index a2cb805..f9d1144 100644 --- a/win32/build_installer.sh +++ b/win32/build_installer.sh @@ -1,55 +1,10 @@ -#!/bin/bash - -set -e - -echo "[INFO] Checking env..." -ENV=$1 - -if [ ! -f "$PYTHON_HOME" ]; then - PYTHON_HOME=c:/Python27 -fi - -if [ ! -f "$ISCC_HOME" ]; then - ISCC_HOME="C:/Program Files/Inno Setup 5" -fi - -log_dir=$(pwd) - -function handle_log() { - cat 2>>$log_dir/build.log 1>&2 -} - -echo "[INFO] Installing paramiko..." -git clone https://github.com/paramiko/paramiko 2>&1 | handle_log -pushd paramiko > /dev/null -"$PYTHON_HOME/python.exe" setup.py install_lib 2>&1 | handle_log -popd > /dev/null - -echo "[INFO] Installing certifi..." -git clone https://github.com/certifi/python-certifi 2>&1 | handle_log -pushd python-certifi > /dev/null -"$PYTHON_HOME/python.exe" setup.py install_lib 2>&1 | handle_log -popd > /dev/null - -echo "[INFO] Installing pycclib..." -git clone https://github.com/cloudControl/pycclib 2>&1 | handle_log -pushd pycclib > /dev/null -"$PYTHON_HOME/python.exe" setup.py install_lib 2>&1 | handle_log -popd > /dev/null - -echo "[INFO] Installing cctrl..." -if [ ! -d "$2" ]; then - git clone https://github.com/cloudControl/cctrl 2>&1 | handle_log - cctrl_dir=cctrl -else - cctrl_dir="$2" -fi - -pushd "$cctrl_dir" > /dev/null -"$PYTHON_HOME/python.exe" setup.py py2exe 2>&1 | handle_log -pushd win32 > /dev/null -echo "[INFO] Building executable..." -"$ISCC_HOME/ISCC.exe" wininstaller_$ENV.iss 2>&1 | handle_log -popd > /dev/null -popd > /dev/null -echo "[INFO] Build successful :-)" +#!/bin/bash +set -e +"${PYTHON_HOME:-c:/Python27}/python.exe" -m pip install -U pip +"${PYTHON_HOME:-c:/Python27}/python.exe" -m pip install -r requirements.txt +"${PYTHON_HOME:-c:/Python27}/python.exe" setup-py2exe.py py2exe +pushd win32 > /dev/null +echo "[INFO] Building executable..." +"${ISCC_HOME:-C:/Program Files (x86)/Inno Setup 5}/ISCC.exe" wininstaller_cctrl.iss +popd > /dev/null +echo "[INFO] Build successful :-)" diff --git a/win32/readme_cnh.txt b/win32/readme_cnh.txt deleted file mode 100644 index 94e5cc9..0000000 --- a/win32/readme_cnh.txt +++ /dev/null @@ -1,2 +0,0 @@ -For further information see the documentation and tutorial on the website. -https://www.cloudandheat.com/ diff --git a/win32/readme_dotcloudng.txt b/win32/readme_dotcloudng.txt deleted file mode 100644 index 05293d4..0000000 --- a/win32/readme_dotcloudng.txt +++ /dev/null @@ -1,2 +0,0 @@ -For further information see the documentation and tutorial on the website. -https://www.cloudcontrol.com/documentation/ diff --git a/win32/wininstaller_cctrl.iss b/win32/wininstaller_cctrl.iss index 1584d89..5d1e9b6 100644 --- a/win32/wininstaller_cctrl.iss +++ b/win32/wininstaller_cctrl.iss @@ -1,259 +1,259 @@ -; Script generated by the Inno Setup Script Wizard. -; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! - -[Setup] -; NOTE: The value of AppId uniquely identifies this application. -; Do not use the same AppId value in installers for other applications. -; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) -AppId={{86DDE49A-CB27-4B64-A816-887A13C06D58} -AppName=cctrl -AppVerName=cctrl-1.16.1 -AppPublisher=cloudControl GmbH -AppPublisherURL=https://www.cloudcontrol.com -AppSupportURL=https://www.cloudcontrol.com -AppUpdatesURL=https://www.cloudcontrol.com -DefaultDirName={pf}\cloudControl -DefaultGroupName=cloudControl -AllowNoIcons=yes -SourceDir=..\ -OutputDir=win32setup -OutputBaseFilename=cctrl-1.16.1-setup -Compression=lzma -SolidCompression=yes -ChangesEnvironment=yes -InfoAfterFile=win32\readme_cctrl.txt - -[Tasks] -Name: modifypath; Description: &Add application directory to your system path; - -[Languages] -Name: "english"; MessagesFile: "compiler:Default.isl" - -[Files] -Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs -; NOTE: Don't use "Flags: ignoreversion" on any shared system files - -[Icons] -Name: "{group}\{cm:ProgramOnTheWeb,cctrl}"; Filename: "https://www.cloudcontrol.com" -Name: "{group}\{cm:UninstallProgram,cctrl}"; Filename: "{uninstallexe}" - -[Code] -function ModPathDir(): TArrayOfString; -var - Dir: TArrayOfString; -begin - setArrayLength(Dir, 1) - Dir[0] := ExpandConstant('{app}'); - Result := Dir; -end; - -// ---------------------------------------------------------------------------- -// -// Inno Setup Ver: 5.3.9 -// Script Version: 1.3.2 -// Author: Jared Breland -// Homepage: http://www.legroom.net/software -// -// Script Function: -// Enable modification of system path directly from Inno Setup installers -// -// Instructions: -// Copy modpath.iss to the same directory as your setup script -// -// Add this statement to your [Setup] section -// ChangesEnvironment=yes -// -// Add this statement to your [Tasks] section -// You can change the Description or Flags, but the Name must be modifypath -// Name: modifypath; Description: &Add application directory to your system path; Flags: unchecked -// -// Add the following to the end of your [Code] section -// setArrayLength must specify the total number of dirs to be added -// Dir[0] contains first directory, Dir[1] contains second, etc. -// function ModPathDir(): TArrayOfString; -// var -// Dir: TArrayOfString; -// begin -// setArrayLength(Dir, 1) -// Dir[0] := ExpandConstant('{app}'); -// Result := Dir; -// end; -// #include "modpath.iss" -// ---------------------------------------------------------------------------- - -procedure ModPath(); -var - oldpath: String; - newpath: String; - pathArr: TArrayOfString; - aExecFile: String; - aExecArr: TArrayOfString; - i, d: Integer; - pathdir: TArrayOfString; -begin - - // Get array of new directories and act on each individually - pathdir := ModPathDir(); - for d := 0 to GetArrayLength(pathdir)-1 do begin - - // Modify WinNT path - if UsingWinNT() = true then begin - - // Get current path, split into an array - RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', oldpath); - oldpath := oldpath + ';'; - i := 0; - while (Pos(';', oldpath) > 0) do begin - SetArrayLength(pathArr, i+1); - pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1); - oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath)); - i := i + 1; - - // Check if current directory matches app dir - if pathdir[d] = pathArr[i-1] then begin - // if uninstalling, remove dir from path - if IsUninstaller() = true then begin - continue; - // if installing, abort because dir was already in path - end else begin - abort; - end; - end; - - // Add current directory to new path - if i = 1 then begin - newpath := pathArr[i-1]; - end else begin - newpath := newpath + ';' + pathArr[i-1]; - end; - end; - - // Append app dir to path if not already included - if IsUninstaller() = false then - newpath := newpath + ';' + pathdir[d]; - - // Write new path - RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', newpath); - - // Modify Win9x path - end else begin - - // Convert to shortened dirname - pathdir[d] := GetShortName(pathdir[d]); - - // If autoexec.bat exists, check if app dir already exists in path - aExecFile := 'C:\AUTOEXEC.BAT'; - if FileExists(aExecFile) then begin - LoadStringsFromFile(aExecFile, aExecArr); - for i := 0 to GetArrayLength(aExecArr)-1 do begin - if IsUninstaller() = false then begin - // If app dir already exists while installing, abort add - if (Pos(pathdir[d], aExecArr[i]) > 0) then - abort; - end else begin - // If app dir exists and = what we originally set, then delete at uninstall - if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then - aExecArr[i] := ''; - end; - end; - end; - - // If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path - if IsUninstaller() = false then begin - SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True); - - // If uninstalling, write the full autoexec out - end else begin - SaveStringsToFile(aExecFile, aExecArr, False); - end; - end; - - // Write file to flag modifypath was selected - // Workaround since IsTaskSelected() cannot be called at uninstall and AppName and AppId cannot be "read" in Code section - if IsUninstaller() = false then - SaveStringToFile(ExpandConstant('{app}') + '\uninsTasks.txt', WizardSelectedTasks(False), False); - end; -end; - -///////////////////////////////////////////////////////////////////// -function GetUninstallString(): String; -var - sUnInstPath: String; - sUnInstallString: String; -begin - sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{{86DDE49A-CB27-4B64-A816-887A13C06D58}_is1'); - sUnInstallString := ''; - if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then - RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); - Result := sUnInstallString; -end; - -///////////////////////////////////////////////////////////////////// -function UnInstallOldVersion(): Integer; -var - sUnInstallString: String; - iResultCode: Integer; -begin -// Return Values: -// 1 - uninstall string is empty -// 2 - error executing the UnInstallString -// 3 - successfully executed the UnInstallString - - // default return value - Result := 0; - - // get the uninstall string of the old app - sUnInstallString := GetUninstallString(); - if sUnInstallString <> '' then begin - sUnInstallString := RemoveQuotes(sUnInstallString); - if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then -// if Exec(sUnInstallString, '/NORESTART','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then - Result := 3 - else - Result := 2; - end else - Result := 1; -end; - - -///////////////////////////////////////////////////////////////////// -function IsUpgrade(): Boolean; -begin - Result := (GetUninstallString() <> ''); -end; - - -procedure CurStepChanged(CurStep: TSetupStep); -begin - if CurStep = ssInstall then - if IsUpgrade() then - UnInstallOldVersion(); - if CurStep = ssPostInstall then - if IsTaskSelected('modifypath') then - ModPath(); -end; - -procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); -var - appdir: String; - aSelectedTasks: TArrayOfString; - i: Integer; -begin - appdir := ExpandConstant('{app}') - if CurUninstallStep = usUninstall then begin - if LoadStringsFromFile(appdir + '\uninsTasks.txt', aSelectedTasks) then - for i := 0 to GetArrayLength(aSelectedTasks)-1 do - if aSelectedTasks[i] = 'modifypath' then - ModPath(); - DeleteFile(appdir + '\uninsTasks.txt') - end; -end; - -function NeedRestart(): Boolean; -begin - if IsTaskSelected('modifypath') and not UsingWinNT() then begin - Result := True; - end else begin - Result := False; - end; -end; +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{86DDE49A-CB27-4B64-A816-887A13C06D58} +AppName=cctrl +AppVerName=cctrl-1.16.2 +AppPublisher=cloudControl GmbH +AppPublisherURL=https://www.cloudcontrol.com +AppSupportURL=https://www.cloudcontrol.com +AppUpdatesURL=https://www.cloudcontrol.com +DefaultDirName={pf}\cloudControl +DefaultGroupName=cloudControl +AllowNoIcons=yes +SourceDir=..\ +OutputDir=win32setup +OutputBaseFilename=cctrl-1.16.2-setup +Compression=lzma +SolidCompression=yes +ChangesEnvironment=yes +InfoAfterFile=win32\readme_cctrl.txt + +[Tasks] +Name: modifypath; Description: &Add application directory to your system path; + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Files] +Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{group}\{cm:ProgramOnTheWeb,cctrl}"; Filename: "https://www.cloudcontrol.com" +Name: "{group}\{cm:UninstallProgram,cctrl}"; Filename: "{uninstallexe}" + +[Code] +function ModPathDir(): TArrayOfString; +var + Dir: TArrayOfString; +begin + setArrayLength(Dir, 1) + Dir[0] := ExpandConstant('{app}'); + Result := Dir; +end; + +// ---------------------------------------------------------------------------- +// +// Inno Setup Ver: 5.3.9 +// Script Version: 1.3.2 +// Author: Jared Breland +// Homepage: http://www.legroom.net/software +// +// Script Function: +// Enable modification of system path directly from Inno Setup installers +// +// Instructions: +// Copy modpath.iss to the same directory as your setup script +// +// Add this statement to your [Setup] section +// ChangesEnvironment=yes +// +// Add this statement to your [Tasks] section +// You can change the Description or Flags, but the Name must be modifypath +// Name: modifypath; Description: &Add application directory to your system path; Flags: unchecked +// +// Add the following to the end of your [Code] section +// setArrayLength must specify the total number of dirs to be added +// Dir[0] contains first directory, Dir[1] contains second, etc. +// function ModPathDir(): TArrayOfString; +// var +// Dir: TArrayOfString; +// begin +// setArrayLength(Dir, 1) +// Dir[0] := ExpandConstant('{app}'); +// Result := Dir; +// end; +// #include "modpath.iss" +// ---------------------------------------------------------------------------- + +procedure ModPath(); +var + oldpath: String; + newpath: String; + pathArr: TArrayOfString; + aExecFile: String; + aExecArr: TArrayOfString; + i, d: Integer; + pathdir: TArrayOfString; +begin + + // Get array of new directories and act on each individually + pathdir := ModPathDir(); + for d := 0 to GetArrayLength(pathdir)-1 do begin + + // Modify WinNT path + if UsingWinNT() = true then begin + + // Get current path, split into an array + RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', oldpath); + oldpath := oldpath + ';'; + i := 0; + while (Pos(';', oldpath) > 0) do begin + SetArrayLength(pathArr, i+1); + pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1); + oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath)); + i := i + 1; + + // Check if current directory matches app dir + if pathdir[d] = pathArr[i-1] then begin + // if uninstalling, remove dir from path + if IsUninstaller() = true then begin + continue; + // if installing, abort because dir was already in path + end else begin + abort; + end; + end; + + // Add current directory to new path + if i = 1 then begin + newpath := pathArr[i-1]; + end else begin + newpath := newpath + ';' + pathArr[i-1]; + end; + end; + + // Append app dir to path if not already included + if IsUninstaller() = false then + newpath := newpath + ';' + pathdir[d]; + + // Write new path + RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', newpath); + + // Modify Win9x path + end else begin + + // Convert to shortened dirname + pathdir[d] := GetShortName(pathdir[d]); + + // If autoexec.bat exists, check if app dir already exists in path + aExecFile := 'C:\AUTOEXEC.BAT'; + if FileExists(aExecFile) then begin + LoadStringsFromFile(aExecFile, aExecArr); + for i := 0 to GetArrayLength(aExecArr)-1 do begin + if IsUninstaller() = false then begin + // If app dir already exists while installing, abort add + if (Pos(pathdir[d], aExecArr[i]) > 0) then + abort; + end else begin + // If app dir exists and = what we originally set, then delete at uninstall + if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then + aExecArr[i] := ''; + end; + end; + end; + + // If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path + if IsUninstaller() = false then begin + SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True); + + // If uninstalling, write the full autoexec out + end else begin + SaveStringsToFile(aExecFile, aExecArr, False); + end; + end; + + // Write file to flag modifypath was selected + // Workaround since IsTaskSelected() cannot be called at uninstall and AppName and AppId cannot be "read" in Code section + if IsUninstaller() = false then + SaveStringToFile(ExpandConstant('{app}') + '\uninsTasks.txt', WizardSelectedTasks(False), False); + end; +end; + +///////////////////////////////////////////////////////////////////// +function GetUninstallString(): String; +var + sUnInstPath: String; + sUnInstallString: String; +begin + sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{{86DDE49A-CB27-4B64-A816-887A13C06D58}_is1'); + sUnInstallString := ''; + if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then + RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); + Result := sUnInstallString; +end; + +///////////////////////////////////////////////////////////////////// +function UnInstallOldVersion(): Integer; +var + sUnInstallString: String; + iResultCode: Integer; +begin +// Return Values: +// 1 - uninstall string is empty +// 2 - error executing the UnInstallString +// 3 - successfully executed the UnInstallString + + // default return value + Result := 0; + + // get the uninstall string of the old app + sUnInstallString := GetUninstallString(); + if sUnInstallString <> '' then begin + sUnInstallString := RemoveQuotes(sUnInstallString); + if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then +// if Exec(sUnInstallString, '/NORESTART','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then + Result := 3 + else + Result := 2; + end else + Result := 1; +end; + + +///////////////////////////////////////////////////////////////////// +function IsUpgrade(): Boolean; +begin + Result := (GetUninstallString() <> ''); +end; + + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if CurStep = ssInstall then + if IsUpgrade() then + UnInstallOldVersion(); + if CurStep = ssPostInstall then + if IsTaskSelected('modifypath') then + ModPath(); +end; + +procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); +var + appdir: String; + aSelectedTasks: TArrayOfString; + i: Integer; +begin + appdir := ExpandConstant('{app}') + if CurUninstallStep = usUninstall then begin + if LoadStringsFromFile(appdir + '\uninsTasks.txt', aSelectedTasks) then + for i := 0 to GetArrayLength(aSelectedTasks)-1 do + if aSelectedTasks[i] = 'modifypath' then + ModPath(); + DeleteFile(appdir + '\uninsTasks.txt') + end; +end; + +function NeedRestart(): Boolean; +begin + if IsTaskSelected('modifypath') and not UsingWinNT() then begin + Result := True; + end else begin + Result := False; + end; +end; diff --git a/win32/wininstaller_cnh.iss b/win32/wininstaller_cnh.iss deleted file mode 100644 index 62b86f3..0000000 --- a/win32/wininstaller_cnh.iss +++ /dev/null @@ -1,259 +0,0 @@ -; Script generated by the Inno Setup Script Wizard. -; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! - -[Setup] -; NOTE: The value of AppId uniquely identifies this application. -; Do not use the same AppId value in installers for other applications. -; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) -AppId={{86DDE49A-CB27-4B64-A816-887A13C06D58} -AppName=cnh -AppVerName=cnh-1.16.1 -AppPublisher=cloudControl GmbH -AppPublisherURL=https://www.cloudcontrol.com -AppSupportURL=https://www.cloudandheat.com -AppUpdatesURL=https://www.cloudandheat.com -DefaultDirName={pf}\cnh -DefaultGroupName=cloudandheat -AllowNoIcons=yes -SourceDir=..\ -OutputDir=win32setup -OutputBaseFilename=cnh-1.16.1-setup -Compression=lzma -SolidCompression=yes -ChangesEnvironment=yes -InfoAfterFile=win32\readme_cnh.txt - -[Tasks] -Name: modifypath; Description: &Add application directory to your system path; - -[Languages] -Name: "english"; MessagesFile: "compiler:Default.isl" - -[Files] -Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs -; NOTE: Don't use "Flags: ignoreversion" on any shared system files - -[Icons] -Name: "{group}\{cm:ProgramOnTheWeb,cnh}"; Filename: "https://www.cloudandheat.com" -Name: "{group}\{cm:UninstallProgram,cnh}"; Filename: "{uninstallexe}" - -[Code] -function ModPathDir(): TArrayOfString; -var - Dir: TArrayOfString; -begin - setArrayLength(Dir, 1) - Dir[0] := ExpandConstant('{app}'); - Result := Dir; -end; - -// ---------------------------------------------------------------------------- -// -// Inno Setup Ver: 5.3.9 -// Script Version: 1.3.2 -// Author: Jared Breland -// Homepage: http://www.legroom.net/software -// -// Script Function: -// Enable modification of system path directly from Inno Setup installers -// -// Instructions: -// Copy modpath.iss to the same directory as your setup script -// -// Add this statement to your [Setup] section -// ChangesEnvironment=yes -// -// Add this statement to your [Tasks] section -// You can change the Description or Flags, but the Name must be modifypath -// Name: modifypath; Description: &Add application directory to your system path; Flags: unchecked -// -// Add the following to the end of your [Code] section -// setArrayLength must specify the total number of dirs to be added -// Dir[0] contains first directory, Dir[1] contains second, etc. -// function ModPathDir(): TArrayOfString; -// var -// Dir: TArrayOfString; -// begin -// setArrayLength(Dir, 1) -// Dir[0] := ExpandConstant('{app}'); -// Result := Dir; -// end; -// #include "modpath.iss" -// ---------------------------------------------------------------------------- - -procedure ModPath(); -var - oldpath: String; - newpath: String; - pathArr: TArrayOfString; - aExecFile: String; - aExecArr: TArrayOfString; - i, d: Integer; - pathdir: TArrayOfString; -begin - - // Get array of new directories and act on each individually - pathdir := ModPathDir(); - for d := 0 to GetArrayLength(pathdir)-1 do begin - - // Modify WinNT path - if UsingWinNT() = true then begin - - // Get current path, split into an array - RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', oldpath); - oldpath := oldpath + ';'; - i := 0; - while (Pos(';', oldpath) > 0) do begin - SetArrayLength(pathArr, i+1); - pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1); - oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath)); - i := i + 1; - - // Check if current directory matches app dir - if pathdir[d] = pathArr[i-1] then begin - // if uninstalling, remove dir from path - if IsUninstaller() = true then begin - continue; - // if installing, abort because dir was already in path - end else begin - abort; - end; - end; - - // Add current directory to new path - if i = 1 then begin - newpath := pathArr[i-1]; - end else begin - newpath := newpath + ';' + pathArr[i-1]; - end; - end; - - // Append app dir to path if not already included - if IsUninstaller() = false then - newpath := newpath + ';' + pathdir[d]; - - // Write new path - RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', newpath); - - // Modify Win9x path - end else begin - - // Convert to shortened dirname - pathdir[d] := GetShortName(pathdir[d]); - - // If autoexec.bat exists, check if app dir already exists in path - aExecFile := 'C:\AUTOEXEC.BAT'; - if FileExists(aExecFile) then begin - LoadStringsFromFile(aExecFile, aExecArr); - for i := 0 to GetArrayLength(aExecArr)-1 do begin - if IsUninstaller() = false then begin - // If app dir already exists while installing, abort add - if (Pos(pathdir[d], aExecArr[i]) > 0) then - abort; - end else begin - // If app dir exists and = what we originally set, then delete at uninstall - if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then - aExecArr[i] := ''; - end; - end; - end; - - // If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path - if IsUninstaller() = false then begin - SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True); - - // If uninstalling, write the full autoexec out - end else begin - SaveStringsToFile(aExecFile, aExecArr, False); - end; - end; - - // Write file to flag modifypath was selected - // Workaround since IsTaskSelected() cannot be called at uninstall and AppName and AppId cannot be "read" in Code section - if IsUninstaller() = false then - SaveStringToFile(ExpandConstant('{app}') + '\uninsTasks.txt', WizardSelectedTasks(False), False); - end; -end; - -///////////////////////////////////////////////////////////////////// -function GetUninstallString(): String; -var - sUnInstPath: String; - sUnInstallString: String; -begin - sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{{86DDE49A-CB27-4B64-A816-887A13C06D58}_is1'); - sUnInstallString := ''; - if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then - RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); - Result := sUnInstallString; -end; - -///////////////////////////////////////////////////////////////////// -function UnInstallOldVersion(): Integer; -var - sUnInstallString: String; - iResultCode: Integer; -begin -// Return Values: -// 1 - uninstall string is empty -// 2 - error executing the UnInstallString -// 3 - successfully executed the UnInstallString - - // default return value - Result := 0; - - // get the uninstall string of the old app - sUnInstallString := GetUninstallString(); - if sUnInstallString <> '' then begin - sUnInstallString := RemoveQuotes(sUnInstallString); - if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then -// if Exec(sUnInstallString, '/NORESTART','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then - Result := 3 - else - Result := 2; - end else - Result := 1; -end; - - -///////////////////////////////////////////////////////////////////// -function IsUpgrade(): Boolean; -begin - Result := (GetUninstallString() <> ''); -end; - - -procedure CurStepChanged(CurStep: TSetupStep); -begin - if CurStep = ssInstall then - if IsUpgrade() then - UnInstallOldVersion(); - if CurStep = ssPostInstall then - if IsTaskSelected('modifypath') then - ModPath(); -end; - -procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); -var - appdir: String; - aSelectedTasks: TArrayOfString; - i: Integer; -begin - appdir := ExpandConstant('{app}') - if CurUninstallStep = usUninstall then begin - if LoadStringsFromFile(appdir + '\uninsTasks.txt', aSelectedTasks) then - for i := 0 to GetArrayLength(aSelectedTasks)-1 do - if aSelectedTasks[i] = 'modifypath' then - ModPath(); - DeleteFile(appdir + '\uninsTasks.txt') - end; -end; - -function NeedRestart(): Boolean; -begin - if IsTaskSelected('modifypath') and not UsingWinNT() then begin - Result := True; - end else begin - Result := False; - end; -end; diff --git a/win32/wininstaller_dotcloudng.iss b/win32/wininstaller_dotcloudng.iss deleted file mode 100644 index 90338e1..0000000 --- a/win32/wininstaller_dotcloudng.iss +++ /dev/null @@ -1,259 +0,0 @@ -; Script generated by the Inno Setup Script Wizard. -; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! - -[Setup] -; NOTE: The value of AppId uniquely identifies this application. -; Do not use the same AppId value in installers for other applications. -; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) -AppId={{86DDE49A-CB27-4B64-A816-887A13C06D58} -AppName=dotcloudng -AppVerName=dotcloudng-1.16.1 -AppPublisher=cloudControl Inc. -AppPublisherURL=https://www.dotcloud.com -AppSupportURL=https://www.dotcloud.com -AppUpdatesURL=https://www.dotcloud.com -DefaultDirName={pf}\dotcloud -DefaultGroupName=dotcloud -AllowNoIcons=yes -SourceDir=..\ -OutputDir=win32setup -OutputBaseFilename=dotcloudng-1.16.1-setup -Compression=lzma -SolidCompression=yes -ChangesEnvironment=yes -InfoAfterFile=win32\readme_dotcloudng.txt - -[Tasks] -Name: modifypath; Description: &Add application directory to your system path; - -[Languages] -Name: "english"; MessagesFile: "compiler:Default.isl" - -[Files] -Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs -; NOTE: Don't use "Flags: ignoreversion" on any shared system files - -[Icons] -Name: "{group}\{cm:ProgramOnTheWeb,dotcloudng}"; Filename: "https://www.dotcloud.com" -Name: "{group}\{cm:UninstallProgram,dotcloudng}"; Filename: "{uninstallexe}" - -[Code] -function ModPathDir(): TArrayOfString; -var - Dir: TArrayOfString; -begin - setArrayLength(Dir, 1) - Dir[0] := ExpandConstant('{app}'); - Result := Dir; -end; - -// ---------------------------------------------------------------------------- -// -// Inno Setup Ver: 5.3.9 -// Script Version: 1.3.2 -// Author: Jared Breland -// Homepage: http://www.legroom.net/software -// -// Script Function: -// Enable modification of system path directly from Inno Setup installers -// -// Instructions: -// Copy modpath.iss to the same directory as your setup script -// -// Add this statement to your [Setup] section -// ChangesEnvironment=yes -// -// Add this statement to your [Tasks] section -// You can change the Description or Flags, but the Name must be modifypath -// Name: modifypath; Description: &Add application directory to your system path; Flags: unchecked -// -// Add the following to the end of your [Code] section -// setArrayLength must specify the total number of dirs to be added -// Dir[0] contains first directory, Dir[1] contains second, etc. -// function ModPathDir(): TArrayOfString; -// var -// Dir: TArrayOfString; -// begin -// setArrayLength(Dir, 1) -// Dir[0] := ExpandConstant('{app}'); -// Result := Dir; -// end; -// #include "modpath.iss" -// ---------------------------------------------------------------------------- - -procedure ModPath(); -var - oldpath: String; - newpath: String; - pathArr: TArrayOfString; - aExecFile: String; - aExecArr: TArrayOfString; - i, d: Integer; - pathdir: TArrayOfString; -begin - - // Get array of new directories and act on each individually - pathdir := ModPathDir(); - for d := 0 to GetArrayLength(pathdir)-1 do begin - - // Modify WinNT path - if UsingWinNT() = true then begin - - // Get current path, split into an array - RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', oldpath); - oldpath := oldpath + ';'; - i := 0; - while (Pos(';', oldpath) > 0) do begin - SetArrayLength(pathArr, i+1); - pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1); - oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath)); - i := i + 1; - - // Check if current directory matches app dir - if pathdir[d] = pathArr[i-1] then begin - // if uninstalling, remove dir from path - if IsUninstaller() = true then begin - continue; - // if installing, abort because dir was already in path - end else begin - abort; - end; - end; - - // Add current directory to new path - if i = 1 then begin - newpath := pathArr[i-1]; - end else begin - newpath := newpath + ';' + pathArr[i-1]; - end; - end; - - // Append app dir to path if not already included - if IsUninstaller() = false then - newpath := newpath + ';' + pathdir[d]; - - // Write new path - RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', newpath); - - // Modify Win9x path - end else begin - - // Convert to shortened dirname - pathdir[d] := GetShortName(pathdir[d]); - - // If autoexec.bat exists, check if app dir already exists in path - aExecFile := 'C:\AUTOEXEC.BAT'; - if FileExists(aExecFile) then begin - LoadStringsFromFile(aExecFile, aExecArr); - for i := 0 to GetArrayLength(aExecArr)-1 do begin - if IsUninstaller() = false then begin - // If app dir already exists while installing, abort add - if (Pos(pathdir[d], aExecArr[i]) > 0) then - abort; - end else begin - // If app dir exists and = what we originally set, then delete at uninstall - if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then - aExecArr[i] := ''; - end; - end; - end; - - // If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path - if IsUninstaller() = false then begin - SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True); - - // If uninstalling, write the full autoexec out - end else begin - SaveStringsToFile(aExecFile, aExecArr, False); - end; - end; - - // Write file to flag modifypath was selected - // Workaround since IsTaskSelected() cannot be called at uninstall and AppName and AppId cannot be "read" in Code section - if IsUninstaller() = false then - SaveStringToFile(ExpandConstant('{app}') + '\uninsTasks.txt', WizardSelectedTasks(False), False); - end; -end; - -///////////////////////////////////////////////////////////////////// -function GetUninstallString(): String; -var - sUnInstPath: String; - sUnInstallString: String; -begin - sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{{86DDE49A-CB27-4B64-A816-887A13C06D58}_is1'); - sUnInstallString := ''; - if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then - RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); - Result := sUnInstallString; -end; - -///////////////////////////////////////////////////////////////////// -function UnInstallOldVersion(): Integer; -var - sUnInstallString: String; - iResultCode: Integer; -begin -// Return Values: -// 1 - uninstall string is empty -// 2 - error executing the UnInstallString -// 3 - successfully executed the UnInstallString - - // default return value - Result := 0; - - // get the uninstall string of the old app - sUnInstallString := GetUninstallString(); - if sUnInstallString <> '' then begin - sUnInstallString := RemoveQuotes(sUnInstallString); - if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then -// if Exec(sUnInstallString, '/NORESTART','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then - Result := 3 - else - Result := 2; - end else - Result := 1; -end; - - -///////////////////////////////////////////////////////////////////// -function IsUpgrade(): Boolean; -begin - Result := (GetUninstallString() <> ''); -end; - - -procedure CurStepChanged(CurStep: TSetupStep); -begin - if CurStep = ssInstall then - if IsUpgrade() then - UnInstallOldVersion(); - if CurStep = ssPostInstall then - if IsTaskSelected('modifypath') then - ModPath(); -end; - -procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); -var - appdir: String; - aSelectedTasks: TArrayOfString; - i: Integer; -begin - appdir := ExpandConstant('{app}') - if CurUninstallStep = usUninstall then begin - if LoadStringsFromFile(appdir + '\uninsTasks.txt', aSelectedTasks) then - for i := 0 to GetArrayLength(aSelectedTasks)-1 do - if aSelectedTasks[i] = 'modifypath' then - ModPath(); - DeleteFile(appdir + '\uninsTasks.txt') - end; -end; - -function NeedRestart(): Boolean; -begin - if IsTaskSelected('modifypath') and not UsingWinNT() then begin - Result := True; - end else begin - Result := False; - end; -end;