Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 66 additions & 28 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,83 @@
# How to contribute

Thank you in your interest in the podman-py project. We need your help to make it successful.
Thank you in your interest in the podman-py project. We need your help to make
it successful.

You may also want to look at:
- https://github.com/containers/libpod
- https://podman.readthedocs.io/en/latest/Reference.html


- [podman](https://github.com/containers/podman)
- [podman Reference](https://podman.readthedocs.io/en/latest/Reference.html)

## Reporting Issues
Before reporting an issue, check our backlog of open issues to see if someone else has already reported it. If so, feel free to add your scenario, or additional information, to the discussion. Or simply "subscribe" to it to be notified when it is updated.

If you find a new issue with the project we'd love to hear about it! The most important aspect of a bug report is that it includes enough information for us to reproduce it. So, please include as much detail as possible and try to remove the extra stuff that doesn't really relate to the issue itself. The easier it is for us to reproduce it, the faster it'll be fixed!
Before reporting an issue, check our backlog of open issues to see if someone
else has already reported it. If so, feel free to add your scenario, or
additional information, to the discussion. Or simply "subscribe" to it to be
notified when it is updated.

If you find a new issue with the project we'd love to hear about it! The most
important aspect of a bug report is that it includes enough information for us
to reproduce it. So, please include as much detail as possible and try to
remove the extra stuff that doesn't really relate to the issue itself. The
easier it is for us to reproduce it, the faster it'll be fixed!

Please don't include any private/sensitive information in your issue!

## Tools we use
- https://www.pylint.org/
- Python 3.6
- You may need to use virtualenv to support Python 3.6
- https://virtualenv.pypa.io/en/latest/


- Python 3.6
- [pylint](https://www.pylint.org/)
- [black](https://github.com/psf/black)
- [tox](https://tox.readthedocs.io/en/latest/)
- You may need to use [virtualenv](https://virtualenv.pypa.io/en/latest/) to
support Python 3.6

## Testing
Depending on the size of your PR we will expect at a minimum unit tests.
Integration tests would be required for large changes.
TBD (how to test)

Depending on the size of your PR we will expect at a minimum unit tests.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mwhahaha Thanks for this work.

Given your coverage work and we're in the high 80's on coverage. How about putting a number on the unit test/coverage results? Won't merge if PR coverage falls below 85%?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure we can raise that and document it

Code will not be merged if unit test coverage drops below 85%.
Integration tests would be required for large changes (TBD).

Run unit tests and get coverage report:

```
pip install tox
tox -e coverage
```

## Submitting changes
- Create a github pull request (PR)
- We expect a short summary followed by a longer description of why you are making these change(s).
- Include the header `Signed-off-by: Git Hub User <user@github.com>` in your PR description/commit message with your name.
- Setting `user.name` and `user.email` in your git configs allows you to then use `git commit -s`. Let git do the work of signing your commits.


- Create a github pull request (PR)
- We expect a short summary followed by a longer description of why you are
making these change(s).
- Include the header `Signed-off-by: Git Hub User <user@github.com>` in your PR
description/commit message with your name.
- Setting `user.name` and `user.email` in your git configs allows you to then
use `git commit -s`. Let git do the work of signing your commits.

## Where to find other contributors
- For general questions and discussion, please use the IRC #podman channel on irc.freenode.net.
- For discussions around issues/bugs and features, you can use the GitHub [issues](https://github.com/containers/podman-py/issues) and [PRs](https://github.com/containers/podman-py/pulls) tracking system.


- For general questions and discussion, please use the IRC #podman channel on
irc.freenode.net.
- For discussions around issues/bugs and features, you can use the
GitHub [issues](https://github.com/containers/podman-py/issues) and
[PRs](https://github.com/containers/podman-py/pulls) tracking system.

## Coding conventions
- Pass pylint
- exceptions are possible but you will need to make a good argument
- use spaces not tabs for indentation
- This is open source software. Consider the people who will read your code, and make it look nice for them. It's sort of like driving a car: Perhaps you love doing donuts when you're alone, but with passengers the goal is to make the ride as smooth as possible.

Again thank you for your interest and participation. Jhon Honce <jhonce at redhat dot com>
- Use [black](https://github.com/psf/black) code formatter. If you have tox
installed, run `tox -e black` to see what changes will be made. You can use
`tox -e black-format` to update the code formatting prior to committing.
- Pass pylint
- exceptions are possible but you will need to make a good argument
- use spaces not tabs for indentation
- This is open source software. Consider the people who will read your code,
and make it look nice for them. It's sort of like driving a car: Perhaps
you love doing donuts when you're alone, but with passengers the goal is to
make the ride as smooth as possible.

Again thank you for your interest and participation.
Jhon Honce `<jhonce at redhat dot com>`

Thanks to Carl Tashian, Participatory Politics Foundation for his fine CONTRIBUTING.md example.
Thanks to Carl Tashian, Participatory Politics Foundation for his fine
CONTRIBUTING.md example.
35 changes: 9 additions & 26 deletions podman/api_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ class ApiConnection(HTTPConnection, AbstractContextManager):
"""ApiConnection provides a specialized HTTPConnection
to a Podman service."""

def __init__(
self, url, base="/v1.24/libpod", *args, **kwargs
): # pylint: disable-msg=W1113
def __init__(self, url, base="/v1.24/libpod", *args, **kwargs): # pylint: disable-msg=W1113
if url is None or not url:
raise ValueError("url is required for service connection.")

Expand All @@ -28,9 +26,7 @@ def __init__(
uri = urllib.parse.urlparse(url)
if uri.scheme not in ("unix", "ssh"):
raise ValueError(
"The scheme '{}' is not supported, only {}".format(
uri.scheme, supported_schemes
)
"The scheme '{}' is not supported, only {}".format(uri.scheme, supported_schemes)
)
self.uri = uri
self.base = base
Expand All @@ -42,9 +38,7 @@ def connect(self):
sock.connect(self.uri.path)
self.sock = sock
else:
raise NotImplementedError(
"Scheme {} not yet implemented".format(self.uri.scheme)
)
raise NotImplementedError("Scheme {} not yet implemented".format(self.uri.scheme))

def delete(self, path, params=None):
"""Basic DELETE wrapper for requests
Expand Down Expand Up @@ -88,27 +82,18 @@ def post(self, path, params=None, headers=None, encode=False):
headers = {}

if encode:
if (
"content-type" not in set(key.lower() for key in headers)
and params
):
if "content-type" not in set(key.lower() for key in headers) and params:
headers["content-type"] = "application/x-www-form-urlencoded"
data = urllib.parse.urlencode(params)

return self.request(
"POST", self.join(path), body=data, headers=headers
)
return self.request("POST", self.join(path), body=data, headers=headers)

def request(
self, method, url, body=None, headers=None, *, encode_chunked=False
):
def request(self, method, url, body=None, headers=None, *, encode_chunked=False):
"""Make request to Podman service."""
if headers is None:
headers = {}

super().request(
method, url, body, headers, encode_chunked=encode_chunked
)
super().request(method, url, body, headers, encode_chunked=encode_chunked)
response = super().getresponse()

# Errors are mapped to exceptions
Expand All @@ -119,8 +104,7 @@ def request(
"Request {}:{} failed: {}".format(
method,
url,
HTTPStatus.NOT_FOUND.description
or HTTPStatus.NOT_FOUND.phrase,
HTTPStatus.NOT_FOUND.description or HTTPStatus.NOT_FOUND.phrase,
),
response,
)
Expand All @@ -132,8 +116,7 @@ def request(
"Request {}:{} failed: {}".format(
method,
url,
response.reason
or "Response Status Code {}".format(response.status),
response.reason or "Response Status Code {}".format(response.status),
),
response,
)
Expand Down
6 changes: 3 additions & 3 deletions podman/errors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def __init__(self, message, response=None):

class ImageNotFound(NotFoundError):
"""HTTP request returned a http.HTTPStatus.NOT_FOUND.
Specialized for Image not found.
Specialized for Image not found.
"""


Expand All @@ -22,13 +22,13 @@ class NetworkNotFound(NotFoundError):

class ContainerNotFound(NotFoundError):
"""HTTP request returned a http.HTTPStatus.NOT_FOUND.
Specialized for Container not found.
Specialized for Container not found.
"""


class PodNotFound(NotFoundError):
"""HTTP request returned a http.HTTPStatus.NOT_FOUND.
Specialized for Pod not found.
Specialized for Pod not found.
"""


Expand Down
4 changes: 1 addition & 3 deletions podman/networks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ def create(api, name, network):
else:
data = network
path = '/networks/create?name={}'.format(api.quote(name))
response = api.post(path,
params=data,
headers={'content-type': 'application/json'})
response = api.post(path, params=data, headers={'content-type': 'application/json'})
return json.loads(str(response.read(), 'utf-8'))


Expand Down
8 changes: 2 additions & 6 deletions podman/tests/unit/images/test_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,7 @@ def test_remove_missing(self):
mock_raise.side_effect = podman.errors.ImageNotFound("yikes")
self.api.raise_not_found = mock_raise
self.request.side_effect = podman.errors.NotFoundError("nope")
self.assertRaises(
podman.errors.ImageNotFound, podman.images.remove, self.api, "foo"
)
self.assertRaises(podman.errors.ImageNotFound, podman.images.remove, self.api, "foo")

def test_tag_image(self):
"""test tag image"""
Expand Down Expand Up @@ -138,6 +136,4 @@ def test_history_missing_image(self):
mock_raise.side_effect = podman.errors.ImageNotFound("yikes")
self.api.raise_image_not_found = mock_raise
self.request.side_effect = podman.errors.NotFoundError("nope")
self.assertRaises(
podman.errors.ImageNotFound, podman.images.history, self.api, "foo"
)
self.assertRaises(podman.errors.ImageNotFound, podman.images.history, self.api, "foo")
37 changes: 18 additions & 19 deletions podman/tests/unit/networks/test_networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def test_create(self):
self.request.assert_called_once_with(
'/networks/create?name=test',
headers={'content-type': 'application/json'},
params='{"DisableDNS": false}')
params='{"DisableDNS": false}',
)

def test_create_with_string(self):
"""test create call with string"""
Expand All @@ -65,19 +66,23 @@ def test_create_with_string(self):
self.request.assert_called_once_with(
'/networks/create?name=test',
headers={'content-type': 'application/json'},
params='{"DisableDNS": false}')
params='{"DisableDNS": false}',
)

def test_create_fail(self):
"""test create call with an error"""
network = {
'DisableDNS': False,
}
self.response.status = 400
self.request.side_effect = podman.errors.RequestError('meh',
self.response)
self.assertRaises(podman.errors.RequestError,
podman.networks.create,
self.api, 'test', json.dumps(network))
self.request.side_effect = podman.errors.RequestError('meh', self.response)
self.assertRaises(
podman.errors.RequestError,
podman.networks.create,
self.api,
'test',
json.dumps(network),
)

def test_inspect(self):
"""test inspect call"""
Expand All @@ -94,10 +99,9 @@ def test_inspect_missing(self):
mock_raise = mock.MagicMock()
mock_raise.side_effect = podman.errors.NetworkNotFound('yikes')
self.api.raise_not_found = mock_raise
self.assertRaises(podman.errors.NetworkNotFound,
podman.networks.inspect,
self.api,
'podman')
self.assertRaises(
podman.errors.NetworkNotFound, podman.networks.inspect, self.api, 'podman'
)

def test_list_networks(self):
"""test networks list call"""
Expand All @@ -115,8 +119,7 @@ def test_list_networks_filter(self):
self.response.read = mock_read
ret = podman.networks.list_networks(self.api, 'name=podman')
self.assertEqual(ret, [{'Name': 'podman'}])
self.request.assert_called_once_with('/networks/json',
{'filter': 'name=podman'})
self.request.assert_called_once_with('/networks/json', {'filter': 'name=podman'})

def test_remove(self):
"""test remove call"""
Expand All @@ -138,16 +141,12 @@ def test_remove_force(self):
expected = [{'deleted': 'str', 'untagged': ['str']}]
ret = podman.networks.remove(self.api, 'foo', True)
self.assertEqual(ret, expected)
self.api.delete.assert_called_once_with('/networks/foo',
{'force': True})
self.api.delete.assert_called_once_with('/networks/foo', {'force': True})

def test_remove_missing(self):
"""test remove call with missing network"""
mock_raise = mock.MagicMock()
mock_raise.side_effect = podman.errors.NetworkNotFound('yikes')
self.api.raise_not_found = mock_raise
self.request.side_effect = podman.errors.NotFoundError('nope')
self.assertRaises(podman.errors.NetworkNotFound,
podman.networks.remove,
self.api,
'foo')
self.assertRaises(podman.errors.NetworkNotFound, podman.networks.remove, self.api, 'foo')
8 changes: 2 additions & 6 deletions podman/tests/unit/system/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ def test_get_info_fail(self):
mock_raise = mock.MagicMock()
mock_raise.side_effect = podman.errors.ImageNotFound('yikes')
self.api.raise_not_found = mock_raise
self.assertRaises(podman.errors.ImageNotFound,
podman.system.get_info,
self.api)
self.assertRaises(podman.errors.ImageNotFound, podman.system.get_info, self.api)

def test_show_disk_usage(self):
"""test df call"""
Expand All @@ -83,6 +81,4 @@ def test_show_disk_usage_fail(self):
mock_raise = mock.MagicMock()
mock_raise.side_effect = podman.errors.ImageNotFound('yikes')
self.api.raise_not_found = mock_raise
self.assertRaises(podman.errors.ImageNotFound,
podman.system.show_disk_usage,
self.api)
self.assertRaises(podman.errors.ImageNotFound, podman.system.show_disk_usage, self.api)
Loading