Skip to content

Commit

Permalink
Added support for migrating an old connections file.
Browse files Browse the repository at this point in the history
Details:

* In _load_connections_file(), added support for migrating an old default
  connections file to the new name: If pywbemcli is invoked with the default
  connections file and it does not exist, but the old default connections
  file exists, it is renamed to the new default name and a message is
  issued about this.

* This required also performing this migration in the file_exists()
  method, which now calls _load_connections_file().

* Improved the message reporting connections file not found.

Signed-off-by: Andreas Maier <andreas.r.maier@gmx.de>
  • Loading branch information
andy-maier committed Aug 15, 2020
1 parent d3de926 commit e00f0d0
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 16 deletions.
1 change: 1 addition & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Released: not yet
* Renamed the default connections file in the user's home directory from
`pywbemcli_connection_definitions.yaml` to `.pywbemcli_connections.yaml`,
because it is really an internal file not meant for being edited.
An existing file with the old name is migrated automatically.
(See issue #716)

**Known issues:**
Expand Down
59 changes: 46 additions & 13 deletions pywbemtools/pywbemcli/_connection_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,30 @@
# with the use of the base file name in several other .rst and .py files.

# Base file name of the connections file
# The B08_* file name was used before pywbemcli 0.8.
CONNECTIONS_FILENAME = '.pywbemcli_connections.yaml'
B08_CONNECTIONS_FILENAME = 'pywbemcli_connection_definitions.yaml'

# Path name of default connections file directory.
DEFAULT_CONNECTIONS_DIR = os.path.expanduser("~")

# Path name of default connections file
# The B08_* path name was used before pywbemcli 0.8.
DEFAULT_CONNECTIONS_FILE = os.path.join(DEFAULT_CONNECTIONS_DIR,
CONNECTIONS_FILENAME)
B08_DEFAULT_CONNECTIONS_FILE = os.path.join(DEFAULT_CONNECTIONS_DIR,
B08_CONNECTIONS_FILENAME)

BAK_FILE_SUFFIX = 'bak'


class ConnectionsFileNotFoundError(Exception):
"""
Exception indicating that the connections file was not found.
"""
pass


class ConnectionRepository(object):
# pylint: disable=useless-object-inheritance
"""
Expand Down Expand Up @@ -125,22 +137,29 @@ def default_connection_name(self):

def file_exists(self):
"""
Test if the connection file exists
Test if the connection file exists.
An old connections file is migrated, if needed.
The connections file is loaded as part of the test.
Returns:
(:class:`py:bool`) True if the connections_file exists and False if
it does not exist
"""
return os.path.isfile(self.connections_file)
try:
self._load_connections_file()
return True
except ConnectionsFileNotFoundError:
return False

def __str__(self):
"""
Return a string containing connections file name and count of items in
connections file
"""
if self.file_exists():
# Has loaded the file
status = 'exists'
self._load_connections_file()
length = len(self)
else:
status = "does not exist"
Expand Down Expand Up @@ -210,17 +229,32 @@ def iterkeys(self):

def _load_connections_file(self):
"""
If there is a file, read it in and install into the dictionary.
This file is read only once.
If the connections file exists, read it in and install into the
dictionary.
Raises:
IOError: repository does not exist
An old connections file is migrated, if needed.
Repeated calls to this method will load the file only once.
ValueError: Error in reading repository
Raises:
ConnectionsFileNotFoundError: Connections file not found
IOError: Cannot rename old connections file
ValueError,KeyError,TypeError: Error in connections file
"""
if self._loaded:
return

# Migrate an old connections file
if self._connections_file == DEFAULT_CONNECTIONS_FILE and \
not os.path.isfile(self._connections_file) and \
os.path.isfile(B08_DEFAULT_CONNECTIONS_FILE):

# May raise IOError:
os.rename(B08_DEFAULT_CONNECTIONS_FILE, DEFAULT_CONNECTIONS_FILE)

click.echo("Migrated old connections file {!r} to {!r}".
format(B08_DEFAULT_CONNECTIONS_FILE,
DEFAULT_CONNECTIONS_FILE))

if os.path.isfile(self._connections_file):
with self._open_file(self._connections_file, 'r') as _fp:
try:
Expand Down Expand Up @@ -252,11 +286,10 @@ def _load_connections_file(self):
raise ValueError("Invalid YAML in connections file {0}. "
"Exception {1}".format
(self._connections_file, ve))
# Apply IO error for non-existent file
# TODO. IOError can also mean disk full in general
else:
raise IOError("Connections file {} does not exist.".
format(self.connections_file))
raise ConnectionsFileNotFoundError(
"Connections file does not exist: {0}".
format(self.connections_file))

def add(self, name, svr_definition):
"""
Expand Down Expand Up @@ -440,6 +473,6 @@ def get_default_connection_name(self):
"""
if self.file_exists():
self._load_connections_file()
# Has loaded the file
return self.default_connection_name
return None
2 changes: 1 addition & 1 deletion pywbemtools/pywbemcli/pywbemcli.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def validate_connections_file(connections_repo):
Abort click if file does not exist
"""
if not connections_repo.file_exists():
click.echo('Connections file: "{}" does not exist.'.format(
click.echo('Connections file does not exist: {}'.format(
connections_repo.connections_file), err=True)
raise click.Abort()

Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_general_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ class Command group for CIM classes.
'./filenotfound.yaml'],
'cmdgrp': 'connection',
'args': ['show']},
{'stderr': ['Connections file: "./filenotfound.yaml" does not exist.',
{'stderr': ['Connections file does not exist: ./filenotfound.yaml',
'Aborted!'],
'rc': 1,
'test': 'innows'},
Expand All @@ -485,7 +485,7 @@ class Command group for CIM classes.
'./filenotfound.yaml'],
'cmdgrp': 'connection',
'args': ['show']},
{'stderr': ['Connections file: "./filenotfound.yaml" does not exist.',
{'stderr': ['Connections file does not exist: ./filenotfound.yaml',
'Aborted!'],
'rc': 1,
'test': 'innows'},
Expand Down

0 comments on commit e00f0d0

Please sign in to comment.