Skip to content

Commit

Permalink
send errors and warnings to stderr
Browse files Browse the repository at this point in the history
This should help address linode#643,
although possibly only in part.
  • Loading branch information
jschauma committed Sep 13, 2024
1 parent c0a860c commit 199537c
Show file tree
Hide file tree
Showing 14 changed files with 73 additions and 83 deletions.
8 changes: 4 additions & 4 deletions linodecli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def main(): # pylint: disable=too-many-branches,too-many-statements
# handle a bake - this is used to parse a spec and bake it as a pickle
if parsed.command == "bake":
if parsed.action is None:
print("No spec provided, cannot bake")
print("No spec provided, cannot bake", file=sys.stderr)
sys.exit(ExitCodes.ARGUMENT_ERROR)
bake_command(cli, parsed.action)
sys.exit(ExitCodes.SUCCESS)
Expand All @@ -110,15 +110,15 @@ def main(): # pylint: disable=too-many-branches,too-many-statements

if parsed.command == "register-plugin":
if parsed.action is None:
print("register-plugin requires a module name!")
print("register-plugin requires a module name!", file=sys.stderr)
sys.exit(ExitCodes.ARGUMENT_ERROR)
msg, code = register_plugin(parsed.action, cli.config, cli.ops)
print(msg)
sys.exit(code)

if parsed.command == "remove-plugin":
if parsed.action is None:
print("remove-plugin requires a plugin name to remove!")
print("remove-plugin requires a plugin name to remove!", file=sys.stderr)
sys.exit(ExitCodes.ARGUMENT_ERROR)
msg, code = remove_plugin(parsed.action, cli.config)
print(msg)
Expand Down Expand Up @@ -215,7 +215,7 @@ def main(): # pylint: disable=too-many-branches,too-many-statements
and parsed.command not in plugins.available(cli.config)
and parsed.command not in HELP_TOPICS
):
print(f"Unrecognized command {parsed.command}")
print(f"Unrecognized command {parsed.command}", file=sys.stderr)
sys.exit(ExitCodes.UNRECOGNIZED_COMMAND)

# handle a help for a command - either --help or no action triggers this
Expand Down
4 changes: 2 additions & 2 deletions linodecli/arg_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def register_plugin(module, config, ops):

reregistering = False
if plugin_name in plugins.available(config):
print(f"WARNING: Plugin {plugin_name} is already registered.\n\n")
print(f"WARNING: Plugin {plugin_name} is already registered.\n\n", file=sys.stderr)
answer = input(f"Allow re-registration of {plugin_name}? [y/N] ")
if not answer or answer not in "yY":
return "Registration aborted.", 0
Expand Down Expand Up @@ -183,7 +183,7 @@ def bake_command(cli, spec_loc):
else:
raise RuntimeError(f"Request failed to {spec_loc}")
except Exception as e:
print(f"Could not load spec: {e}")
print(f"Could not load spec: {e}", file=sys.stderr)
sys.exit(ExitCodes.REQUEST_FAILED)

cli.bake(spec)
5 changes: 3 additions & 2 deletions linodecli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ def load_baked(self):
self.spec = self.ops.pop("_spec")
else:
print(
"No spec baked. Please bake by calling this script as follows:"
"No spec baked. Please bake by calling this script as follows:",
file=sys.stderr
)
print(" python3 gen_cli.py bake /path/to/spec")
print(" python3 gen_cli.py bake /path/to/spec", file=sys.stderr)
self.ops = None # this signals __init__.py to give up

def _get_data_file(self):
Expand Down
12 changes: 7 additions & 5 deletions linodecli/configuration/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ def _handle_response_status(
if 199 < response.status_code < 300:
return

print(f"Could not contact {response.url} - Error: {response.status_code}")
print(f"Could not contact {response.url} - Error: {response.status_code}",
file=sys.stderr)
if exit_on_error:
sys.exit(ExitCodes.REQUEST_FAILED)

Expand Down Expand Up @@ -194,7 +195,7 @@ def _username_for_token(base_url: str, token: str) -> str:
u = _do_get_request(base_url, "/profile", token=token, exit_on_error=False)
if "errors" in u:
reasons = ",".join([c["reason"] for c in u["errors"]])
print(f"That token didn't work: {reasons}")
print(f"That token didn't work: {reasons}", file=sys.stderr)
return None

return u["username"]
Expand Down Expand Up @@ -243,7 +244,7 @@ def _get_token_web(base_url: str) -> Tuple[str, str]:
username = _username_for_token(base_url, temp_token)

if username is None:
print("OAuth failed. Please try again of use a token for auth.")
print("OAuth failed. Please try again of use a token for auth.", file=sys.stderr)
sys.exit(ExitCodes.OAUTH_ERROR)

# the token returned via public oauth will expire in 2 hours, which
Expand Down Expand Up @@ -340,11 +341,12 @@ def log_message(self, form, *args): # pylint: disable=arguments-differ
# serve requests one at a time until we get a token or are interrupted
serv.handle_request()
except KeyboardInterrupt:
print()
print(file=sys.stderr)
print(
"Giving up. If you couldn't get web authentication to work, please "
"try token using a token by invoking with `linode-cli configure --token`, "
"and open an issue at https://github.com/linode/linode-cli"
"and open an issue at https://github.com/linode/linode-cli",
file=sys.stderr
)
sys.exit(ExitCodes.OAUTH_ERROR)

Expand Down
39 changes: 7 additions & 32 deletions linodecli/configuration/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def set_user(self, username: str):
:type username: str
"""
if not self.config.has_section(username):
print(f"User {username} is not configured!")
print(f"User {username} is not configured!", file=sys.stderr)
sys.exit(ExitCodes.USERNAME_ERROR)

self.username = username
Expand All @@ -112,7 +112,8 @@ def remove_user(self, username: str):
if self.default_username() == username:
print(
f"Cannot remove {username} as they are the default user! You can "
"change the default user with: `linode-cli set-user USERNAME`"
"change the default user with: `linode-cli set-user USERNAME`",
file=sys.stderr
)
sys.exit(ExitCodes.USERNAME_ERROR)

Expand All @@ -138,7 +139,7 @@ def set_default_user(self, username: str):
Sets the default user. If that user isn't in the config, exits with error
"""
if not self.config.has_section(username):
print(f"User {username} is not configured!")
print(f"User {username} is not configured!", file=sys.stderr)
sys.exit(ExitCodes.USERNAME_ERROR)

self.config.set("DEFAULT", "default-user", username)
Expand Down Expand Up @@ -186,30 +187,6 @@ def get_value(self, key: str) -> Optional[Any]:

return self.config.get(username, key)

def get_bool(self, key: str) -> bool:
"""
Retrieves and returns an existing config boolean for the current user. This
is intended for plugins to use instead of having to deal with figuring out
who the current user is when accessing their config.
.. warning::
Plugins _MUST NOT_ set values for the user's config except through
``plugin_set_value`` below.
:param key: The key to look up.
:type key: str
:returns: The boolean for that key, or False if the key doesn't exist for the
current user.
:rtype: any
"""
username = self.username or self.default_username()

if not self.config.has_option(username, key):
return False

return self.config.getboolean(username, key)

# plugin methods - these are intended for plugins to utilize to store their
# own persistent config information
def plugin_set_value(self, key: str, value: Any):
Expand Down Expand Up @@ -288,7 +265,7 @@ def update(
if not self.config.has_option(username, "token") and not os.environ.get(
ENV_TOKEN_NAME, None
):
print(f"User {username} is not configured.")
print(f"User {username} is not configured.", file=sys.stderr)
sys.exit(ExitCodes.USERNAME_ERROR)
if not self.config.has_section(username) or allowed_defaults is None:
return namespace
Expand Down Expand Up @@ -325,7 +302,8 @@ def update(
):
print(
f"Using default values: {warn_dict}; "
"use the --no-defaults flag to disable defaults"
"use the --no-defaults flag to disable defaults",
file=sys.stderr
)
return argparse.Namespace(**ns_dict)

Expand Down Expand Up @@ -473,9 +451,6 @@ def configure(
if _bool_input("Configure a custom API target?", default=False):
self._configure_api_target(config)

if _bool_input("Suppress API Version Warnings?", default=False):
config["suppress-version-warning"] = "true"

# save off the new configuration
if username != "DEFAULT" and not self.config.has_section(username):
self.config.add_section(username)
Expand Down
12 changes: 6 additions & 6 deletions linodecli/plugins/firewall-editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def input(input_text: str, validator: Callable[[str], None]):
try:
validator(value)
except ValueError as err:
print(f"Invalid Input: {'; '.join(err.args)}")
print(f"Invalid Input: {'; '.join(err.args)}", file=sys.stderr)
continue

return value
Expand Down Expand Up @@ -204,15 +204,15 @@ def _get_firewall(firewall_id, client):
)

if code != 200:
print(f"Error retrieving firewall: {code}")
print(f"Error retrieving firewall: {code}", file=sys.stderr)
sys.exit(ExitCodes.FIREWALL_ERROR)

code, rules = client.call_operation(
"firewalls", "rules-list", args=[firewall_id]
)

if code != 200:
print(f"Error retrieving firewall rules: {code}")
print(f"Error retrieving firewall rules: {code}", file=sys.stderr)
sys.exit(ExitCodes.FIREWALL_ERROR)

return firewall, rules
Expand Down Expand Up @@ -449,7 +449,7 @@ def remove_rule(rules):
change = InputValidation.input_io(rules)

if len(change) < 1:
print("No entires to remove")
print("No entires to remove", file=sys.stderr)
return False

ind_str = InputValidation.input(
Expand Down Expand Up @@ -614,9 +614,9 @@ def call(args, context):
if code == 200:
print("Rules updated successfully!")
break
print(f"Error editing rules: {code}: {errors}")
print(f"Error editing rules: {code}: {errors}", file=sys.stderr)
# block to see the error, then re-enter the editor
sys.stdin.read(1)
else:
print("Aborted.")
print("Aborted.", file=sys.stderr)
break
21 changes: 13 additions & 8 deletions linodecli/plugins/image-upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,30 +121,33 @@ def call(args, context):
results = glob.glob(filepath, recursive=True)

if len(results) < 1:
print(f"No file found matching pattern {filepath}")
print(f"No file found matching pattern {filepath}", file=sys.stderr)
sys.exit(ExitCodes.FILE_ERROR)

if len(results) > 1:
print(
f"warn: Found multiple files matching pattern {filepath}, using {results[0]}"
f"warn: Found multiple files matching pattern {filepath}, using {results[0]}",
file=sys.stderr
)

filepath = results[0]

if not os.path.isfile(filepath):
print(f"No file at {filepath}; must be a path to a valid file.")
print(f"No file at {filepath}; must be a path to a valid file.", file=sys.stderr)
sys.exit(ExitCodes.FILE_ERROR)

# make sure it's not larger than the max upload size
if os.path.getsize(filepath) > MAX_UPLOAD_SIZE:
print(
f"File {filepath} is too large; compressed size must be less than 5GB"
f"File {filepath} is too large; compressed size must be less than 5GB",
file=sys.stderr
)
sys.exit(ExitCodes.FILE_ERROR)

if not parsed.region:
print(
"No region provided. Please set a default region or use --region"
"No region provided. Please set a default region or use --region",
file=sys.stderr
)
sys.exit(ExitCodes.ARGUMENT_ERROR)

Expand All @@ -165,17 +168,19 @@ def call(args, context):
print(
"Your token was not authorized to use this endpoint. Please "
"reconfigure the CLI with `linode-cli configure` to ensure you "
"can make this request."
"can make this request.",
file=sys.stderr
)
sys.exit(ExitCodes.REQUEST_FAILED)
if status == 404:
print(
"It looks like you are not in the Machine Images Beta, and therefore "
"cannot upload images yet. Please stay tuned, or open a support ticket "
"to request access."
"to request access.",
file=sys.stderr
)
sys.exit(ExitCodes.REQUEST_FAILED)
print(f"Upload failed with status {status}; response was {resp}")
print(f"Upload failed with status {status}; response was {resp}", file=sys.stderr)
sys.exit(ExitCodes.REQUEST_FAILED)

# grab the upload URL and image data
Expand Down
Loading

0 comments on commit 199537c

Please sign in to comment.