-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a simple command that knows how to download the dcos client. #1166
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple comments. You also need to address the pylint errors. You can use 'scripts/lintall' locally to see the results before you open your PR since the CI can be slow. I would recommend @derekbekoe take a look at the PR as well, since it deals with installing things.
install_location = '/usr/local/bin/dcos' | ||
file_url = 'https://downloads.dcos.io/binaries/cli/darwin/x86-64/dcos-1.8/dcos' | ||
else: | ||
logger.error('unknown system: %s' % system) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably raise a CLIError. Otherwise it will attempt to install to "".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like raise CLIError("Unknown system type '{}'".format(system))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
logger.error('unknown system: %s' % system) | ||
|
||
user_location = input('dcos binary install location [%s]:' % install_location) | ||
if len(user_location) == 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if not len(user_location): ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main comments are about the use of install_location
.
It should be a command line argument (not interactive) and you can use the _params.py
file to set the defaults for the user when the command line argument is registered in the CLI.
install_location = '/usr/local/bin/dcos' | ||
file_url = 'https://downloads.dcos.io/binaries/cli/darwin/x86-64/dcos-1.8/dcos' | ||
else: | ||
logger.error('unknown system: %s' % system) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like raise CLIError("Unknown system type '{}'".format(system))
@@ -59,6 +61,33 @@ def dcos_browse(name, resource_group_name): | |||
|
|||
return | |||
|
|||
def dcos_install(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
install_location
should be an optional argument to this function so it can be specified on the command line with acs dcos install --install-location ...
i.e.
def dcos_install(install_location=None):
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can the acs/_params.py file to define what install_location should be.
This means that when this method is called, the right install_location will be passed in.
So for example, you can remove the install locations that have been defined here and add the following lines to the acs/_params.py
file:
import platform
def _get_default_install_location():
system = platform.system()
if system == 'Windows':
return 'C:\Program Files\dcos.exe'
if system == 'Linux':
return '/usr/local/bin/dcos'
if system == 'Darwin':
return '/usr/local/bin/dcos'
else:
return None
register_cli_argument('acs dcos install', 'install_location', options_list=('--install-location',),
default=_get_default_install_location())
This means when the user runs az acs dcos install -h
, they'll see:
Arguments
--install-location : Default: /usr/local/bin/dcos.
with the default being computed automatically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
else: | ||
logger.error('unknown system: %s' % system) | ||
|
||
user_location = input('dcos binary install location [%s]:' % install_location) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our convention is to not take user input interactively like this.
It makes it difficult to set the install_location with a script.
I'd suggest removing this and adding an optional argument install_location
like I've described above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
user_location = install_location | ||
|
||
logger.info("Downloading client to %s\n" % user_location) | ||
urllib.request.urlretrieve(file_url, user_location) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should wrap this in a try/except as it can raise an IOError
if the connection cannot be made (https://docs.python.org/2/library/urllib.html#urllib.urlopen).
e.g.
try:
urllib.request.urlretrieve(file_url, user_location)
except IOError:
raise CLIError('Connection error attempting to download client')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
if len(user_location) == 0: | ||
user_location = install_location | ||
|
||
logger.info("Downloading client to %s\n" % user_location) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't need the '\n' in the log message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
cli_command('acs dcos browse', dcos_browse) | ||
cli_command('acs dcos install', dcos_install) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing new line that pylint was complaining about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
@brendandburns As an FYI, to prevent the 'cla-required' label from being applied, visit aka.ms/azuregithub to link your GitHub account. |
Also, why is the command |
dacae41
to
39973d4
Compare
@derekbekoe thanks for the fast review. addressed all coments, pylint is clean now. Changed to Please take another look. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making those changes.
I've added a few more comments with a suggestion for how to fix the CI error.
from azure.cli.core.commands import register_cli_argument | ||
from azure.cli.core.commands.parameters import ( | ||
name_type, | ||
resource_group_name_type) | ||
from azure.cli.core._util import CLIError | ||
|
||
def _get_default_install_location(exeName): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
python convention is snake casing so exe_name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
elif system == 'Linux' or system == 'Darwin': | ||
install_location = '/usr/local/bin/{}'.format(exeName) | ||
else: | ||
raise CLIError('Proxy server ({}) does not exist on the cluster.'.format(system)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, should just set install_location=None
.
It would be too soon to raise a CLIError at this stage as it'll cause the 'acs' module to not load.
Then, in the dcos_install_cli()
method, you'd have a check for:
def dcos_install_cli(install_location=None):
if not install_location:
raise CLIError("No install location specified and it could not be determined from the current platform '{}'".format(system))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
from azure.cli.core.commands import register_cli_argument | ||
from azure.cli.core.commands.parameters import ( | ||
name_type, | ||
resource_group_name_type) | ||
from azure.cli.core._util import CLIError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After making my other suggested change, this import would be unused so can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
import random | ||
import string | ||
import urllib.request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CI build is failing because of this.
urllib.request
is defined in Python 3 but not Python 2.
This should fix this:
from six.moves.urllib.request import urlretrieve
from: https://pythonhosted.org/six/#module-six.moves.urllib.request
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
def _get_default_install_location(exeName): | ||
system = platform.system() | ||
if system == 'Windows': | ||
install_location = 'C:\\Program Files\\{}.exe'.format(exeName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use os.environ['ProgramFiles']
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x64 vs x86? And please verify behavior with both 64bit/32bit python on windows...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, os.environ.get('ProgramFiles')
instead as then you don't get a KeyError from the dict and can check for None on the result and not set install location if you get none back from the call to os.environ.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
file_url = '' | ||
system = platform.system() | ||
if system == 'Windows': | ||
file_url = 'https://downloads.dcos.io/binaries/cli/windows/x86-64/dcos-1.8/dcos.exe' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest to add a command help to call out the version of 1.8
, or expose the version as parameter people can pick; otherwise people will be surprised that we don't install newer stable one after some period.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
Comments addressed, please re-check. Thanks! |
@brendandburns, to merge the PR, you will need to suppress the pylint error of "E: 9, 0: Unable to import 'six.moves.urllib.request' (import-error)". I assume you favor this lib over the |
@yugangw-msft do I need to worry about adding that to a dependency list somewhere? THanks |
@brendandburns, |
@brendandburns: As @yugangw-msft mentioned, add |
20efcbe
to
06ed02b
Compare
Done, please take another look. Thanks! |
import random | ||
import string | ||
#pylint: disable=import-error | ||
from six.moves.urllib.request import urlretrieve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably should add the suppression at the same line ; otherwise the suppression will apply on all the imports in the rest of the file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
06ed02b
to
3d30ae0
Compare
Comments addressed, please take another look. Thanks! |
@rgardler @ahowe
This is my first PR to the Azure CLI, please advise if I'm doing it wrong...