Skip to content

Commit

Permalink
Merge pull request #7 from cloudify-cosmo/logger-fix
Browse files Browse the repository at this point in the history
changed module to package and now no longer overriding user's logger
  • Loading branch information
nir0s committed Oct 14, 2015
2 parents 21f000c + 7d60140 commit 5e92335
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 193 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
a42e364 (HEAD, origin/CFY-3709-add-module-exclusion, CFY-3709-add-module-exclusion) CFY-3709 added module exclusion, fixed a bug in validation and added showmeta cli func
c083124 (origin/master, origin/HEAD, master) Update README.md
21f000c (HEAD, tag: 0.2.1, origin/master, origin/HEAD, master, logger-fix) Update README.md
e8b78eb Update README.md
0a8a55d Update README.md
95b384b Merge pull request #6 from cloudify-cosmo/CFY-3709-add-module-exclusion
0adc2fa (origin/CFY-3709-add-module-exclusion, CFY-3709-add-module-exclusion) CFY-3709 added module exclusion, fixed a bug in validation and added showmeta cli func
c083124 Update README.md
6391892 Merge pull request #5 from cloudify-cosmo/refine-meta-properties
f9f5691 (origin/refine-meta-properties, refine-meta-properties) Added support for user provided python versions, ignoring the supported platform check and linux specific handling.
5fd3336 (tag: 0.2.0, tag: 0.1.2) Merge pull request #4 from cloudify-cosmo/add-installation-validation
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ files:
git log --oneline --decorate --color > CHANGELOG

test:
pip install tox==1.7.1
pip install tox
tox

docs:
Expand Down
60 changes: 30 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ wagon create --help
#### Examples

```shell
# create an archive by retrieving the source from PyPI and keep the downloaded wheels (kept under <cwd>/plugin) and exclude the cloudify-plugins-common and cloudify-rest-client modules from the archive.
# create an archive by retrieving the source from PyPI and keep the downloaded wheels (kept under <cwd>/plugin) and exclude the cloudify-plugins-common and cloudify-rest-client packages from the archive.
wagon create -s cloudify-script-plugin==1.2 --keep-wheels -v --exclude cloudify-plugins-common --exclude cloudify-rest-client
# create an archive by retrieving the source from a URL and creating wheels from requirement files found within the archive. Then, validation of the archive takes place.
wagon create -s http://github.com/cloudify-cosmo/cloudify-script-plugin/archive/1.2.tar.gz -r . --validate
# create an archive by retrieving the source from a local path and output the tar.gz file to /tmp/<MODULE>.tar.gz (defaults to <cwd>/<MODULE>.tar.gz) and provides explicit Python versions supported by the module (which usually defaults to the first two digits of the Python version used to create the archive.)
wagon create -s ~/modules/cloudify-script-plugin/ -o /tmp/ --pyver 33 --pyver 26 --pyver 27
# create an archive by retrieving the source from a local path and output the tar.gz file to /tmp/<PACKAGE>.tar.gz (defaults to <cwd>/<PACKAGE>.tar.gz) and provides explicit Python versions supported by the package (which usually defaults to the first two digits of the Python version used to create the archive.)
wagon create -s ~/packages/cloudify-script-plugin/ -o /tmp/ --pyver 33 --pyver 26 --pyver 27
```

Regarding exclusions, note that excluding modules can result in an archive being non-installable. The user will be warned about this but creation will succeed. Creation validation, though (i.e. using the `--validate` flag), will fail and show an error incase the archive cannot be installed.
Regarding exclusions, note that excluding packages can result in an archive being non-installable. The user will be warned about this but creation will succeed. Creation validation, though (i.e. using the `--validate` flag), will fail and show an error incase the archive cannot be installed.

Also note that Wagon doesn't currently provide a way for packaging modules that are in editable mode.
So, for instance, providing a dev-requirements file which contains a `-e DEPENDENCY` requirement will not be taken into consideration. This is not related to wagon but rather to the default `pip wheel` implementation stating that it will be "Skipping bdist_wheel for #MODULE#, due to being editable". We might allow processing editable provided dependencies in the future.
Also note that Wagon doesn't currently provide a way for packaging packages that are in editable mode.
So, for instance, providing a dev-requirements file which contains a `-e DEPENDENCY` requirement will not be taken into consideration. This is not related to wagon but rather to the default `pip wheel` implementation stating that it will be "Skipping bdist_wheel for #PACKAGE#, due to being editable". We might allow processing editable provided dependencies in the future.

### Install Packages

Expand All @@ -53,9 +53,9 @@ wagon install --help
#### Examples

```shell
# install a module from a local archive tar file and upgrade if already installed. Also, ignore the platform check which would force a module (whether it is or isn't compiled for a specific platform) to be installed.
# install a package from a local archive tar file and upgrade if already installed. Also, ignore the platform check which would force a package (whether it is or isn't compiled for a specific platform) to be installed.
wagon install -s ~/tars/cloudify_script_plugin-1.2-py27-none-any.tar.gz --upgrade --ignore-platform
# install a module from a url into an existing virtualenv.
# install a package from a url into an existing virtualenv.
wagon install -s http://me.com/cloudify_script_plugin-1.2-py27-none-any-none-none.tar.gz --virtualenv my_venv -v
```

Expand All @@ -64,7 +64,7 @@ Note that `--pre` is appended to the installation command to enable installation

#### Installing Manually

While wagon provides a generic way of installing wagon created archives, you might not want to use the installer as you might not wish to install wagon on your application servers. Installing the module manually via pip is as easy as running (for example):
While wagon provides a generic way of installing wagon created archives, you might not want to use the installer as you might not wish to install wagon on your application servers. Installing the package manually via pip is as easy as running (for example):

```shell
tar -xzvf http://me.com/cloudify_script_plugin-1.2-py27-none-any-none-none.tar.gz
Expand All @@ -78,7 +78,7 @@ pip install --no-index --find-links cloudify-script-plugin/wheels cloudify-scrip
wagon validate --help
```

The `validate` function provides shallow validation of a Wagon archive. Basically, it checks that some keys in the metadata are found, that all required wheels for a module are present and that the module is installable. It obviously does not check for a module's functionality.
The `validate` function provides shallow validation of a Wagon archive. Basically, it checks that some keys in the metadata are found, that all required wheels for a package are present and that the package is installable. It obviously does not check for a package's functionality.

This shallow validation should, at the very least, allow a user to be sure that a Wagon archive is not corrupted.

Expand Down Expand Up @@ -113,7 +113,7 @@ wagon showmeta -s http://me.com/cloudify_script_plugin-1.2-py27-none-any-none-no
## Naming and Versioning

### Source: PyPI
When providing a PyPI source, it must be supplied as MODULE_NAME==MODULE_VERSION. wagon then applies the correct name and version to the archive according to the two parameters.
When providing a PyPI source, it must be supplied as PACKAGE_NAME==PACKAGE_VERSION. wagon then applies the correct name and version to the archive according to the two parameters.

### Source: Else
For local path and URL sources, the name and version are automatically extracted from the setup.py file.
Expand All @@ -135,23 +135,23 @@ A Metadata file is generated for the archive and looks somewhat like this:
"distribution_release": "trusty",
"distribution_version": "14.04"
},
"module_name": "cloudify-script-plugin",
"module_source": "cloudify-script-plugin==1.2",
"module_version": "1.2",
"package_name": "cloudify-script-plugin",
"package_source": "cloudify-script-plugin==1.2",
"package_version": "1.2",
"supported_platform": "any",
"supported_python_versions": [
"py26",
"py27"
],
"wheels": [
"proxy_tools-0.1.0-py2-none-any.whl",
"pyzmq-14.7.0-cp27-none-linux_x86_64.whl",
"bottle-0.12.7-py2-none-any.whl",
"networkx-1.8.1-py2-none-any.whl",
"requests-2.5.1-py2.py3-none-any.whl",
"PyYAML-3.10-cp27-none-linux_x86_64.whl",
"pika-0.9.13-py2-none-any.whl",
"jsonschema-2.3.0-py2.py3-none-any.whl",
"proxy_tools-0.1.0-py2-none-any.whl",
"pyzmq-14.7.0-cp27-none-linux_x86_64.whl",
"bottle-0.12.7-py2-none-any.whl",
"networkx-1.8.1-py2-none-any.whl",
"requests-2.5.1-py2.py3-none-any.whl",
"PyYAML-3.10-cp27-none-linux_x86_64.whl",
"pika-0.9.13-py2-none-any.whl",
"jsonschema-2.3.0-py2.py3-none-any.whl",
"cloudify_dsl_parser-3.2-py2-none-any.whl",
"cloudify_rest_client-3.2-py2-none-any.whl",
"cloudify_script_plugin-1.2-py2-none-any.whl"
Expand All @@ -163,9 +163,9 @@ A Metadata file is generated for the archive and looks somewhat like this:
```

* The wheels to be installed reside in the tar.gz file under 'wheels/*.whl'.
* The Metadata file resides in the tar.gz file under 'module.json'.
* The installer uses the metadata file to check that the platform fits the machine the module is being installed on.
* OS Properties only appear when creating compiled Linux modules (see Linux Distributions section). In case of a non-linux platform (e.g. win32, any), null values will be supplied for OS properties.
* The Metadata file resides in the tar.gz file under 'package.json'.
* The installer uses the metadata file to check that the platform fits the machine the package is being installed on.
* OS Properties only appear when creating compiled Linux packages (see Linux Distributions section). In case of a non-linux platform (e.g. win32, any), null values will be supplied for OS properties.


## Archive naming convention and Platform
Expand All @@ -174,8 +174,8 @@ The archive is named according to the Wheel naming convention described in [PEP0

Example Output Archive: `cloudify_fabric_plugin-1.2.1-py27-none-any-none-none.tar.gz`

* `{python tag}`: The Python version is set by the Python running the packaging process. That means that while a module might run on both py27 and py33 (for example), since the packaging process took place using Python 2.7, only py27 will be appended to the name. A user can also explicitly provide the supported Python versions for the module via the `pyver` flag.
* `{platform tag}`: The platform (e.g. `linux_x86_64`, `win32`) is set each specific wheel. To know which platform the module with its dependencies can be installed on, all wheels are checked. If a specific wheel has a platform property other than `any`, that platform will be used as the platform of the package. Of course, we assume that there can't be wheels downloaded or created on a specific machine platform that belongs to two different platforms.
* `{python tag}`: The Python version is set by the Python running the packaging process. That means that while a package might run on both py27 and py33 (for example), since the packaging process took place using Python 2.7, only py27 will be appended to the name. A user can also explicitly provide the supported Python versions for the package via the `pyver` flag.
* `{platform tag}`: The platform (e.g. `linux_x86_64`, `win32`) is set each specific wheel. To know which platform the package with its dependencies can be installed on, all wheels are checked. If a specific wheel has a platform property other than `any`, that platform will be used as the platform of the package. Of course, we assume that there can't be wheels downloaded or created on a specific machine platform that belongs to two different platforms.
* `{abi tag}`: Note that the ABI tag is currently ignored and will always be `none`. This might be changed in the future to support providing an ABI tag.
* For Linux (see below), two additional tags are added: `{distribution tag}` and `{release tag}`. Note that these tags are NOT a part of the PEP.

Expand All @@ -186,11 +186,11 @@ Example Output Archive: `cloudify_fabric_plugin-1.2.1-py27-none-linux_x86_64-ubu

Wheels which require compilation of C extensions and are compiled on Linux are not uploaded to PyPI due to variations between compilation environments on different distributions and links to varying system libraries.

To overcome that (partially), if running Wagon on Linux and the module requires compilation, the metadata and archive name both provide the distribution and release of the OS that the archive was created on (via platform.linux_distribution()). Statistically speaking, this should provide the user with the information they need to know which OS the module can be installed on. Obviously, this is not true for cases where non-generic compilation methods are used on the creating OS but otherwise should work, and should specifically always work when both compilation environment and Python version are similar on the creating and installing OS - which, we generally recommend.
To overcome that (partially), if running Wagon on Linux and the package requires compilation, the metadata and archive name both provide the distribution and release of the OS that the archive was created on (via platform.linux_distribution()). Statistically speaking, this should provide the user with the information they need to know which OS the package can be installed on. Obviously, this is not true for cases where non-generic compilation methods are used on the creating OS but otherwise should work, and should specifically always work when both compilation environment and Python version are similar on the creating and installing OS - which, we generally recommend.

What this practically means, is that in most cases, using the metadata to compare the distro, release and the Python version under which the module is installed would allow a user to use Wagon rather safely. Of course, Wagon provides no guarantee whatsoever as to whether this will actually work or not and users must test their archives.
What this practically means, is that in most cases, using the metadata to compare the distro, release and the Python version under which the package is installed would allow a user to use Wagon rather safely. Of course, Wagon provides no guarantee whatsoever as to whether this will actually work or not and users must test their archives.

That being said, Wagon is completely safe for creating and installing Pure Python module archives for any platform, and, due to the nature of Wheels, modules compiled for OS X or Windows.
That being said, Wagon is completely safe for creating and installing Pure Python package archives for any platform, and, due to the nature of Wheels, packages compiled for OS X or Windows.


## Testing
Expand Down
10 changes: 4 additions & 6 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
- wagon/wagon.py:290: # TODO: maybe we don't want to be that explicit and allow using >=
- wagon/wagon.py:291: # TODO: or just a module name...
- wagon/wagon.py:366: # TODO: Let the user provide supported Python versions.
- wagon/wagon.py:367: # TODO: Let the user provide supported Architectures.
- wagon/logger.py:60: # TODO: (IMPRV) only perform file related actions if file handler is
- wagon/logger.py:61: # TODO: (IMPRV) defined.
- wagon/wagon.py:360: # TODO: maybe we don't want to be that explicit and allow using >=
- wagon/wagon.py:361: # TODO: or just a package name...
- wagon/wagon.py:436: # TODO: Let the user provide supported Python versions.
- wagon/wagon.py:437: # TODO: Let the user provide supported Architectures.
- wagon/utils.py:48: # TODO: implement using sh
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def read(*parts):

setup(
name='wagon',
version='0.2.1',
version='0.2.2',
url='https://github.com/cloudify-cosmo/wagon',
author='Gigaspaces',
author_email='cosmo-admin@gigaspaces.com',
Expand Down
2 changes: 1 addition & 1 deletion wagon/codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
'failed_to_wheel': 207,
'could_not_install_module': 208,
'failed_to_create_virtualenv': 209,
'cannot_exclude_main_module': 210
'cannot_exclude_main_package': 210
}
50 changes: 21 additions & 29 deletions wagon/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,41 +40,33 @@


def init(base_level=DEFAULT_BASE_LOGGING_LEVEL,
verbose_level=DEFAULT_VERBOSE_LOGGING_LEVEL,
logging_config=None):
"""initializes a base logger
verbose_level=DEFAULT_VERBOSE_LOGGING_LEVEL):
"""Initializes a base logger
"""
lgr = logging.getLogger('user')
lgr.setLevel(base_level)
return lgr

you can use this to init a logger in any of your files.
this will use config.py's LOGGER param and logging.dictConfig to configure
the logger for you.

:param int|logging.LEVEL base_level: desired base logging level
:param int|logging.LEVEL verbose_level: desired verbose logging level
:param dict logging_dict: dictConfig based configuration.
used to override the default configuration from config.py
:rtype: `python logger`
def configure():
"""Configures the logger using the default configuration.
"""
if logging_config is None:
logging_config = {}
logging_config = logging_config or LOGGER
# TODO: (IMPRV) only perform file related actions if file handler is
# TODO: (IMPRV) defined.

log_file = LOGGER['handlers']['file']['filename']
try:
log_file = LOGGER['handlers']['file']['filename']
except KeyError as ex:
sys.exit('Failed retrieving log file path ({0}).'.format(str(ex)))
log_dir = os.path.dirname(os.path.expanduser(log_file))
if os.path.isfile(log_dir):
sys.exit('file {0} exists - log directory cannot be created '
'there. please remove the file and try again.'
.format(log_dir))
sys.exit('File {0} exists - log directory cannot be created '
'there. please remove the file and try again.'.format(
log_dir))
try:
if not os.path.exists(log_dir) and not len(log_dir) == 0:
os.makedirs(log_dir)
dictconfig.dictConfig(logging_config)
lgr = logging.getLogger('user')
lgr.setLevel(base_level)
return lgr
except ValueError as e:
sys.exit('could not initialize logger.'
dictconfig.dictConfig(LOGGER)

except ValueError as ex:
sys.exit('Could not configure logger.'
' verify your logger config'
' and permissions to write to {0} ({1})'
.format(log_file, e))
' and permissions to write to {0} ({1})'.format(
log_file, str(ex)))
Loading

0 comments on commit 5e92335

Please sign in to comment.