You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by an...@apache.org on 2016/01/20 04:43:49 UTC
[01/50] libcloud git commit: Added entry path for dedicated docker
doc link
Repository: libcloud
Updated Branches:
refs/heads/trunk 99d6bce74 -> a313623d5
Added entry path for dedicated docker doc link
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/fe7ba5c2
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/fe7ba5c2
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/fe7ba5c2
Branch: refs/heads/trunk
Commit: fe7ba5c222c2ed3cac8f4ec7ec655ddf415145fc
Parents: e982273
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Dec 23 14:51:48 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Dec 23 14:51:48 2015 +1100
----------------------------------------------------------------------
docs/container/_supported_providers.rst | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/fe7ba5c2/docs/container/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_providers.rst b/docs/container/_supported_providers.rst
index 4829fb7..f7743b1 100644
--- a/docs/container/_supported_providers.rst
+++ b/docs/container/_supported_providers.rst
@@ -1,9 +1,9 @@
.. NOTE: This file has been generated automatically using generate_provider_feature_matrix_table.py script, don't manually edit it
-========= ============= ================= ======================================== ==============================
-Provider Documentation Provider constant Module Class Name
-========= ============= ================= ======================================== ==============================
-`Docker`_ DOCKER :mod:`libcloud.container.drivers.docker` :class:`DockerContainerDriver`
-========= ============= ================= ======================================== ==============================
+========= ======================================== ================= ======================================== ==============================
+Provider Documentation Provider constant Module Class Name
+========= ======================================== ================= ======================================== ==============================
+`Docker`_ :doc:`Click </container/drivers/docker>` DOCKER :mod:`libcloud.container.drivers.docker` :class:`DockerContainerDriver`
+========= ======================================== ================= ======================================== ==============================
.. _`Docker`: http://docker.io
[47/50] libcloud git commit: Extended the Kubernetes driver to
support deploying containers as single-container pods. also added destroying
containers (pods) via the API.
Posted by an...@apache.org.
Extended the Kubernetes driver to support deploying containers as single-container pods. also added destroying containers (pods) via the API.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/0b875888
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0b875888
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0b875888
Branch: refs/heads/trunk
Commit: 0b8758881942fbac1963f30363fd49cef9adfcb4
Parents: 936fe42
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Jan 13 16:15:56 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Jan 13 16:15:56 2016 +1100
----------------------------------------------------------------------
libcloud/container/drivers/kubernetes.py | 138 +++++++++++++++++--
.../_api_v1_namespaces_default_pods_POST.json | 47 +++++++
.../fixtures/kubernetes/_api_v1_pods.json | 94 +++++++++++++
libcloud/test/container/test_kubernetes.py | 41 ++++--
4 files changed, 302 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0b875888/libcloud/container/drivers/kubernetes.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/kubernetes.py b/libcloud/container/drivers/kubernetes.py
index a947fd2..13f2a51 100644
--- a/libcloud/container/drivers/kubernetes.py
+++ b/libcloud/container/drivers/kubernetes.py
@@ -28,7 +28,7 @@ from libcloud.common.base import JsonResponse, ConnectionUserAndKey
from libcloud.common.types import InvalidCredsError
from libcloud.container.base import (Container, ContainerDriver,
- ContainerCluster)
+ ContainerImage, ContainerCluster)
from libcloud.container.providers import Provider
from libcloud.container.types import ContainerState
@@ -85,6 +85,16 @@ class KubernetesConnection(ConnectionUserAndKey):
return headers
+class KubernetesPod(object):
+ def __init__(self, name, containers, namespace):
+ """
+ A Kubernetes pod
+ """
+ self.name = name
+ self.containers = containers
+ self.namespace = namespace
+
+
class KubernetesContainerDriver(ContainerDriver):
type = Provider.KUBERNETES
name = 'Kubernetes'
@@ -169,7 +179,7 @@ class KubernetesContainerDriver(ContainerDriver):
"""
try:
result = self.connection.request(
- ROOT_URL + "v1/nodes/").object
+ ROOT_URL + "v1/pods").object
except Exception as exc:
if hasattr(exc, 'errno') and exc.errno == 111:
raise KubernetesException(
@@ -178,7 +188,10 @@ class KubernetesContainerDriver(ContainerDriver):
'and the API port is correct')
raise
- containers = [self._to_container(value) for value in result['items']]
+ pods = [self._to_pod(value) for value in result['items']]
+ containers = []
+ for pod in pods:
+ containers.extend(pod.containers)
return containers
def get_container(self, id):
@@ -265,19 +278,124 @@ class KubernetesContainerDriver(ContainerDriver):
data=json.dumps(request)).object
return self._to_cluster(result)
- def _to_container(self, data):
+ def deploy_container(self, name, image, cluster=None,
+ parameters=None, start=True):
+ """
+ Deploy an installed container image.
+ In kubernetes this deploys a single container Pod.
+ https://cloud.google.com/container-engine/docs/pods/single-container
+
+ :param name: The name of the new container
+ :type name: ``str``
+
+ :param image: The container image to deploy
+ :type image: :class:`.ContainerImage`
+
+ :param cluster: The cluster to deploy to, None is default
+ :type cluster: :class:`.ContainerCluster`
+
+ :param parameters: Container Image parameters
+ :type parameters: ``str``
+
+ :param start: Start the container on deployment
+ :type start: ``bool``
+
+ :rtype: :class:`.Container`
+ """
+ if cluster is None:
+ namespace = 'default'
+ else:
+ namespace = cluster.id
+ request = {
+ "metadata": {
+ "name": name
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": name,
+ "image": image.name
+ }
+ ]
+ }
+ }
+ result = self.connection.request(ROOT_URL + "v1/namespaces/%s/pods"
+ % namespace,
+ method='POST',
+ data=json.dumps(request)).object
+ return self._to_cluster(result)
+
+ def destroy_container(self, container):
+ """
+ Destroy a deployed container. Because the containers are single
+ container pods, this will delete the pod.
+
+ :param container: The container to destroy
+ :type container: :class:`.Container`
+
+ :rtype: ``bool``
+ """
+ return self.ex_delete_pod(container.extra['namespace'],
+ container.extra['pod'])
+
+ def ex_list_pods(self):
+ """
+ List available Pods
+
+ :rtype: ``list`` of :class:`.KubernetesPod`
+ """
+ result = self.connection.request(ROOT_URL + "v1/pods").object
+ return [self._to_pod(value) for value in result['items']]
+
+ def ex_destroy_pod(self, namespace, pod_name):
+ """
+ Delete a pod and the containers within it.
+ """
+ self.connection.request(
+ ROOT_URL + "v1/namespaces/%s/pods/%s" % (
+ namespace, pod_name),
+ method='DELETE').object
+ return True
+
+ def _to_pod(self, data):
+ """
+ Convert an API response to a Pod object
+ """
+ container_statuses = data['status']['containerStatuses']
+ containers = []
+ # response contains the status of the containers in a separate field
+ for container in data['spec']['containers']:
+ spec = list(filter(lambda i: i['name'] == container['name'],
+ container_statuses))[0]
+ containers.append(
+ self._to_container(container, spec, data)
+ )
+ return KubernetesPod(
+ name=data['metadata']['name'],
+ namespace=data['metadata']['namespace'],
+ containers=containers)
+
+ def _to_container(self, data, container_status, pod_data):
"""
Convert container in Container instances
"""
- metadata = data['metadata']
return Container(
- id=data['spec']['externalID'],
- name=metadata['name'],
- image=None,
- ip_addresses="ips",
+ id=container_status['containerID'],
+ name=data['name'],
+ image=ContainerImage(
+ id=container_status['imageID'],
+ name=data['image'],
+ path=None,
+ version=None,
+ driver=self.connection.driver
+ ),
+ ip_addresses=None,
state=ContainerState.RUNNING,
driver=self.connection.driver,
- extra=None)
+ extra={
+ 'pod': pod_data['metadata']['name'],
+ 'namespace': pod_data['metadata']['namespace']
+ })
def _to_cluster(self, data):
"""
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0b875888/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default_pods_POST.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default_pods_POST.json b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default_pods_POST.json
new file mode 100644
index 0000000..49387d1
--- /dev/null
+++ b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default_pods_POST.json
@@ -0,0 +1,47 @@
+{
+ "kind": "Pod",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "hello-world",
+ "namespace": "default",
+ "selfLink": "/api/v1/namespaces/default/pods/hello-world",
+ "uid": "1fad5411-b9af-11e5-8701-0050568157ec",
+ "resourceVersion": "32",
+ "creationTimestamp": "2016-01-13T04:35:50Z"
+ },
+ "spec": {
+ "volumes": [
+ {
+ "name": "default-token-dpyh0",
+ "secret": {
+ "secretName": "default-token-dpyh0"
+ }
+ }
+ ],
+ "containers": [
+ {
+ "name": "hello-world",
+ "image": "ubuntu:14.04",
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "default-token-dpyh0",
+ "readOnly": true,
+ "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent"
+ }
+ ],
+ "restartPolicy": "Always",
+ "terminationGracePeriodSeconds": 30,
+ "dnsPolicy": "ClusterFirst",
+ "serviceAccountName": "default",
+ "serviceAccount": "default",
+ "securityContext": {}
+ },
+ "status": {
+ "phase": "Pending"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0b875888/libcloud/test/container/fixtures/kubernetes/_api_v1_pods.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/kubernetes/_api_v1_pods.json b/libcloud/test/container/fixtures/kubernetes/_api_v1_pods.json
new file mode 100644
index 0000000..f29ffdc
--- /dev/null
+++ b/libcloud/test/container/fixtures/kubernetes/_api_v1_pods.json
@@ -0,0 +1,94 @@
+{
+ "kind": "PodList",
+ "apiVersion": "v1",
+ "metadata": {
+ "selfLink": "/api/v1/pods",
+ "resourceVersion": "63"
+ },
+ "items": [
+ {
+ "metadata": {
+ "name": "hello-world",
+ "namespace": "default",
+ "selfLink": "/api/v1/namespaces/default/pods/hello-world",
+ "uid": "1fad5411-b9af-11e5-8701-0050568157ec",
+ "resourceVersion": "62",
+ "creationTimestamp": "2016-01-13T04:35:50Z"
+ },
+ "spec": {
+ "volumes": [
+ {
+ "name": "default-token-dpyh0",
+ "secret": {
+ "secretName": "default-token-dpyh0"
+ }
+ }
+ ],
+ "containers": [
+ {
+ "name": "hello-world",
+ "image": "ubuntu:14.04",
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "default-token-dpyh0",
+ "readOnly": true,
+ "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent"
+ }
+ ],
+ "restartPolicy": "Always",
+ "terminationGracePeriodSeconds": 30,
+ "dnsPolicy": "ClusterFirst",
+ "serviceAccountName": "default",
+ "serviceAccount": "default",
+ "nodeName": "127.0.0.1",
+ "securityContext": {}
+ },
+ "status": {
+ "phase": "Running",
+ "conditions": [
+ {
+ "type": "Ready",
+ "status": "False",
+ "lastProbeTime": null,
+ "lastTransitionTime": "2016-01-13T04:37:09Z",
+ "reason": "ContainersNotReady",
+ "message": "containers with unready status: [hello-world]"
+ }
+ ],
+ "hostIP": "127.0.0.1",
+ "podIP": "172.17.0.2",
+ "startTime": "2016-01-13T04:35:50Z",
+ "containerStatuses": [
+ {
+ "name": "hello-world",
+ "state": {
+ "waiting": {
+ "reason": "CrashLoopBackOff",
+ "message": "Back-off 20s restarting failed container=hello-world pod=hello-world_default(1fad5411-b9af-11e5-8701-0050568157ec)"
+ }
+ },
+ "lastState": {
+ "terminated": {
+ "exitCode": 0,
+ "reason": "Completed",
+ "startedAt": "2016-01-13T04:37:07Z",
+ "finishedAt": "2016-01-13T04:37:07Z",
+ "containerID": "docker://3c48b5cda79bce4c8866f02a3b96a024edb8f660d10e7d1755e9ced49ef47b36"
+ }
+ },
+ "ready": false,
+ "restartCount": 2,
+ "image": "ubuntu:14.04",
+ "imageID": "docker://c4bea91afef3764163fd506f5c1090be1d34a9b63ece81867cb863455937048e",
+ "containerID": "docker://3c48b5cda79bce4c8866f02a3b96a024edb8f660d10e7d1755e9ced49ef47b36"
+ }
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0b875888/libcloud/test/container/test_kubernetes.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_kubernetes.py b/libcloud/test/container/test_kubernetes.py
index 2e8da4e..b60a648 100644
--- a/libcloud/test/container/test_kubernetes.py
+++ b/libcloud/test/container/test_kubernetes.py
@@ -17,6 +17,8 @@ import sys
from libcloud.test import unittest
+from libcloud.container.base import ContainerImage
+
from libcloud.container.drivers.kubernetes import KubernetesContainerDriver
from libcloud.utils.py3 import httplib
@@ -38,14 +40,8 @@ class KubernetesContainerDriverTestCase(unittest.TestCase):
containers = self.driver.list_containers()
self.assertEqual(len(containers), 1)
self.assertEqual(containers[0].id,
- '127.0.0.1')
- self.assertEqual(containers[0].name, '127.0.0.1')
-
- def test_get_container(self):
- container = self.driver.get_container('127.0.0.1')
- self.assertEqual(container.id,
- '127.0.0.1')
- self.assertEqual(container.name, '127.0.0.1')
+ 'docker://3c48b5cda79bce4c8866f02a3b96a024edb8f660d10e7d1755e9ced49ef47b36')
+ self.assertEqual(containers[0].name, 'hello-world')
def test_list_clusters(self):
clusters = self.driver.list_clusters()
@@ -71,6 +67,17 @@ class KubernetesContainerDriverTestCase(unittest.TestCase):
result = self.driver.destroy_cluster(cluster)
self.assertTrue(result)
+ def test_deploy_container(self):
+ image = ContainerImage(
+ id=None,
+ name='hello-world',
+ path=None,
+ driver=self.driver,
+ version=None
+ )
+ container = self.driver.deploy_container('hello-world', image=image)
+ self.assertEqual(container.name, 'hello-world')
+
class KubernetesMockHttp(MockHttp):
fixtures = ContainerFileFixtures('kubernetes')
@@ -83,6 +90,14 @@ class KubernetesMockHttp(MockHttp):
raise AssertionError('Unsupported method')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _api_v1_pods(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('_api_v1_pods.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _api_v1_nodes(
self, method, url, body, headers):
if method == 'GET':
@@ -121,5 +136,15 @@ class KubernetesMockHttp(MockHttp):
raise AssertionError('Unsupported method')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _api_v1_namespaces_default_pods(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('_api_v1_namespaces_default_pods.json')
+ elif method == 'POST':
+ body = self.fixtures.load('_api_v1_namespaces_default_pods_POST.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
if __name__ == '__main__':
sys.exit(unittest.main())
[44/50] libcloud git commit: __repr__ for images shows path instead
of driver name, fix doc reference output
Posted by an...@apache.org.
__repr__ for images shows path instead of driver name, fix doc reference output
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/8537731e
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/8537731e
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/8537731e
Branch: refs/heads/trunk
Commit: 8537731e0d7639e1d39fd2fb693fd7bf07aaea1f
Parents: a3ed405
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Jan 11 16:04:55 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Jan 11 16:04:55 2016 +1100
----------------------------------------------------------------------
docs/examples/container/ecs/container_registry.py | 2 +-
libcloud/container/base.py | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8537731e/docs/examples/container/ecs/container_registry.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/ecs/container_registry.py b/docs/examples/container/ecs/container_registry.py
index 2003d5b..9df770f 100644
--- a/docs/examples/container/ecs/container_registry.py
+++ b/docs/examples/container/ecs/container_registry.py
@@ -19,7 +19,7 @@ for image in client.list_images('my-image'):
image = client.get_image('my-image', '14.04')
print(image.path)
-# >> 647433528374.dkr.ecr.region.amazonaws.com/my-images:14.04
+# >> 647433528374.dkr.ecr.region.amazonaws.com/my-image:14.04
# Deploy that image
cluster = conn.list_clusters()[0]
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8537731e/libcloud/container/base.py
----------------------------------------------------------------------
diff --git a/libcloud/container/base.py b/libcloud/container/base.py
index 7abe664..a03ea91 100644
--- a/libcloud/container/base.py
+++ b/libcloud/container/base.py
@@ -123,8 +123,8 @@ class ContainerImage(object):
**kwargs)
def __repr__(self):
- return ('<ContainerImage: id=%s, name=%s, provider=%s ...>' %
- (self.id, self.name, self.driver.name))
+ return ('<ContainerImage: id=%s, name=%s, path=%s ...>' %
+ (self.id, self.name, self.path))
class ContainerCluster(object):
[05/50] libcloud git commit: Added APi docs for Joyent triton driver.
Posted by an...@apache.org.
Added APi docs for Joyent triton driver.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/6d83dc03
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/6d83dc03
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/6d83dc03
Branch: refs/heads/trunk
Commit: 6d83dc03908b09c941e08ab4cfcb1d081de0d620
Parents: 2450063
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Dec 23 15:50:52 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Dec 23 15:50:52 2015 +1100
----------------------------------------------------------------------
docs/container/drivers/joyent.rst | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/6d83dc03/docs/container/drivers/joyent.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/joyent.rst b/docs/container/drivers/joyent.rst
index f6feb5f..fc43916 100644
--- a/docs/container/drivers/joyent.rst
+++ b/docs/container/drivers/joyent.rst
@@ -14,7 +14,7 @@ Mix Docker containers with container-native Linux to extend the benefits of cont
Instantiating the driver
-------------------------------------
-Download the script:
+Download the script::
curl -O https://raw.githubusercontent.com/joyent/sdc-docker/master/tools/sdc-docker-setup.sh
@@ -53,5 +53,13 @@ This should output something similar to the following::
.. literalinclude:: /examples/container/joyent/instantiate_driver.py
:language: python
+API Docs
+--------
+
+.. autoclass:: libcloud.container.drivers.joyent.JoyentContainerDriver
+ :members:
+ :inherited-members:
+
+
.. _`Joyent Triton`: https://www.joyent.com/blog/understanding-triton-containers
.. _`Joyent`: https://www.joyent.com/
\ No newline at end of file
[20/50] libcloud git commit: Updated doc warnings,
updated AWS request signer to support POST.
Posted by an...@apache.org.
Updated doc warnings, updated AWS request signer to support POST.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/9507a634
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/9507a634
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/9507a634
Branch: refs/heads/trunk
Commit: 9507a634d0453bac7227a362b1d972dd81abc260
Parents: 0999e52
Author: anthony-shaw <an...@gmail.com>
Authored: Sun Jan 3 20:42:07 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sun Jan 3 20:42:07 2016 +1100
----------------------------------------------------------------------
docs/container/api.rst | 2 +-
docs/container/drivers/docker.rst | 4 +--
docs/container/drivers/ecs.rst | 6 +++-
docs/container/drivers/index.rst | 2 +-
docs/container/drivers/joyent.rst | 4 +--
libcloud/common/aws.py | 59 +++++++++++++++++++++++-----------
libcloud/common/base.py | 1 +
libcloud/container/drivers/ecs.py | 40 +++++++++++++----------
8 files changed, 76 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/9507a634/docs/container/api.rst
----------------------------------------------------------------------
diff --git a/docs/container/api.rst b/docs/container/api.rst
index a3ee225..f9f7dd4 100644
--- a/docs/container/api.rst
+++ b/docs/container/api.rst
@@ -1,7 +1,7 @@
:orphan:
Container Base API
-============
+==================
.. autoclass:: libcloud.container.base.ContainerDriver
:members:
http://git-wip-us.apache.org/repos/asf/libcloud/blob/9507a634/docs/container/drivers/docker.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/docker.rst b/docs/container/drivers/docker.rst
index 7bb729c..32cbd2c 100644
--- a/docs/container/drivers/docker.rst
+++ b/docs/container/drivers/docker.rst
@@ -1,5 +1,5 @@
Docker Container Driver Documentation
-==================================
+=====================================
`Docker`_ containers wrap up a piece of software in a complete filesystem that contains everything it needs to run:
code, runtime, system tools, system libraries – anything you can install on a server. This guarantees that it will always run the same,
@@ -11,7 +11,7 @@ regardless of the environment it is running in.
:target: http://docker.io/
Instantiating the driver
--------------------------------------
+------------------------
.. literalinclude:: /examples/container/docker/instantiate_driver.py
:language: python
http://git-wip-us.apache.org/repos/asf/libcloud/blob/9507a634/docs/container/drivers/ecs.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/ecs.rst b/docs/container/drivers/ecs.rst
index 45cc2f8..089fae6 100644
--- a/docs/container/drivers/ecs.rst
+++ b/docs/container/drivers/ecs.rst
@@ -8,8 +8,12 @@ Elastic Container Service is a container-as-a-service feature of `AWS`_.
:width: 300
:target: http://aws.amazon.com/
+To provide API key access, you should apply one of the roles:
+* AmazonEC2ContainerServiceFullAccess
+* AmazonEC2ContainerServiceReadOnlyAccess
+
Instantiating the driver
--------------------------------------
+------------------------
.. literalinclude:: /examples/container/ecs/instantiate_driver.py
:language: python
http://git-wip-us.apache.org/repos/asf/libcloud/blob/9507a634/docs/container/drivers/index.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/index.rst b/docs/container/drivers/index.rst
index be5db22..fd1145e 100644
--- a/docs/container/drivers/index.rst
+++ b/docs/container/drivers/index.rst
@@ -1,7 +1,7 @@
:orphan:
Container Drivers Documentation
-============================
+===============================
This chapter includes links to driver (provider) specific documentation pages.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/9507a634/docs/container/drivers/joyent.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/joyent.rst b/docs/container/drivers/joyent.rst
index fc43916..f0e3da7 100644
--- a/docs/container/drivers/joyent.rst
+++ b/docs/container/drivers/joyent.rst
@@ -1,5 +1,5 @@
Joyent Triton Container Driver Documentation
-==================================
+============================================
`Joyent Triton`_ is a Docker hosting service, provided by service provider `Joyent`_.
Docker-native tools and elastic hosts make deploying on Triton as easy as running Docker on your laptop.
@@ -12,7 +12,7 @@ Mix Docker containers with container-native Linux to extend the benefits of cont
:target: http://joyent.com/
Instantiating the driver
--------------------------------------
+------------------------
Download the script::
http://git-wip-us.apache.org/repos/asf/libcloud/blob/9507a634/libcloud/common/aws.py
----------------------------------------------------------------------
diff --git a/libcloud/common/aws.py b/libcloud/common/aws.py
index 4d7523e..b7153e3 100644
--- a/libcloud/common/aws.py
+++ b/libcloud/common/aws.py
@@ -21,6 +21,11 @@ import time
from hashlib import sha256
try:
+ import simplejson as json
+except ImportError:
+ import json
+
+try:
from lxml import etree as ET
except ImportError:
from xml.etree import ElementTree as ET
@@ -180,7 +185,8 @@ class AWSRequestSigner(object):
def get_request_params(self, params, method='GET', path='/'):
return params
- def get_request_headers(self, params, headers, method='GET', path='/'):
+ def get_request_headers(self, params, headers, method='GET', path='/',
+ data=None):
return params, headers
@@ -237,27 +243,32 @@ class AWSRequestSignerAlgorithmV2(AWSRequestSigner):
class AWSRequestSignerAlgorithmV4(AWSRequestSigner):
def get_request_params(self, params, method='GET', path='/'):
- params['Version'] = self.version
+ if method == 'GET':
+ params['Version'] = self.version
return params
- def get_request_headers(self, params, headers, method='GET', path='/'):
+ def get_request_headers(self, params, headers, method='GET', path='/',
+ data=None):
now = datetime.utcnow()
headers['X-AMZ-Date'] = now.strftime('%Y%m%dT%H%M%SZ')
headers['Authorization'] = \
self._get_authorization_v4_header(params=params, headers=headers,
- dt=now, method=method, path=path)
+ dt=now, method=method, path=path,
+ data=data)
return params, headers
def _get_authorization_v4_header(self, params, headers, dt, method='GET',
- path='/'):
- assert method in ['GET', 'POST'], 'AWS Signature V4 not implemented for ' \
- 'other methods than GET and POST'
+ path='/', data=None):
+ assert method in ['GET', 'POST'], 'AWS Signature V4 ' \
+ 'not implemented for ' \
+ 'other methods than GET and POST'
credentials_scope = self._get_credential_scope(dt=dt)
signed_headers = self._get_signed_headers(headers=headers)
signature = self._get_signature(params=params, headers=headers,
- dt=dt, method=method, path=path)
+ dt=dt, method=method, path=path,
+ data=data)
return 'AWS4-HMAC-SHA256 Credential=%(u)s/%(c)s, ' \
'SignedHeaders=%(sh)s, Signature=%(s)s' % {
@@ -267,11 +278,12 @@ class AWSRequestSignerAlgorithmV4(AWSRequestSigner):
's': signature
}
- def _get_signature(self, params, headers, dt, method, path):
+ def _get_signature(self, params, headers, dt, method, path, data):
key = self._get_key_to_sign_with(dt)
string_to_sign = self._get_string_to_sign(params=params,
headers=headers, dt=dt,
- method=method, path=path)
+ method=method, path=path,
+ data=data)
return _sign(key=key, msg=string_to_sign, hex=True)
def _get_key_to_sign_with(self, dt):
@@ -284,11 +296,12 @@ class AWSRequestSignerAlgorithmV4(AWSRequestSigner):
self.connection.service_name),
'aws4_request')
- def _get_string_to_sign(self, params, headers, dt, method, path):
+ def _get_string_to_sign(self, params, headers, dt, method, path, data):
canonical_request = self._get_canonical_request(params=params,
headers=headers,
method=method,
- path=path)
+ path=path,
+ data=data)
return '\n'.join(['AWS4-HMAC-SHA256',
dt.strftime('%Y%m%dT%H%M%SZ'),
@@ -308,8 +321,11 @@ class AWSRequestSignerAlgorithmV4(AWSRequestSigner):
return '\n'.join([':'.join([k.lower(), v.strip()])
for k, v in sorted(headers.items())]) + '\n'
- def _get_payload_hash(self):
- return _hash('')
+ def _get_payload_hash(self, method, data=None):
+ if method == 'GET':
+ return _hash('')
+ elif method == 'POST':
+ return _hash(data)
def _get_request_params(self, params):
# For self.method == GET
@@ -317,14 +333,14 @@ class AWSRequestSignerAlgorithmV4(AWSRequestSigner):
(urlquote(k, safe=''), urlquote(str(v), safe='~'))
for k, v in sorted(params.items())])
- def _get_canonical_request(self, params, headers, method, path):
+ def _get_canonical_request(self, params, headers, method, path, data):
return '\n'.join([
method,
path,
self._get_request_params(params),
self._get_canonical_headers(headers),
self._get_signed_headers(headers),
- self._get_payload_hash()
+ self._get_payload_hash(method, data)
])
@@ -365,7 +381,8 @@ class SignedAWSConnection(AWSTokenConnection):
params, headers = self.signer.get_request_headers(params=params,
headers=headers,
method=self.method,
- path=self.action)
+ path=self.action,
+ data=self.data)
return params, headers
@@ -374,7 +391,13 @@ class AWSJsonResponse(JsonResponse):
Amazon ECS response class.
ECS API uses JSON unlike the s3, elb drivers
"""
-
+ def parse_error(self):
+ response = json.loads(self.body)
+ code = response['__type']
+ message = response['Message']
+
+ return ('%s: %s' % (code, message))
+
def _sign(key, msg, hex=False):
if hex:
http://git-wip-us.apache.org/repos/asf/libcloud/blob/9507a634/libcloud/common/base.py
----------------------------------------------------------------------
diff --git a/libcloud/common/base.py b/libcloud/common/base.py
index d457e24..a25dcfc 100644
--- a/libcloud/common/base.py
+++ b/libcloud/common/base.py
@@ -709,6 +709,7 @@ class Connection(object):
action = self.morph_action_hook(action)
self.action = action
self.method = method
+ self.data = data
# Extend default parameters
params = self.add_default_params(params)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/9507a634/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index 1485027..746c176 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -13,16 +13,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-__all__ = [
- 'ElasticContainerDriver'
-]
-
+try:
+ import simplejson as json
+except ImportError:
+ import json
from libcloud.container.base import (ContainerDriver, Container,
ContainerCluster, ContainerImage)
from libcloud.container.types import ContainerState
from libcloud.common.aws import SignedAWSConnection, AWSJsonResponse
+__all__ = [
+ 'ElasticContainerDriver'
+]
+
+
VERSION = '2014-11-13'
HOST = 'ecs.%s.amazonaws.com'
ROOT = '/'
@@ -67,6 +72,7 @@ class ElasticContainerDriver(ContainerDriver):
data = self.connection.request(
ROOT,
method='POST',
+ data=json.dumps({}),
headers=self._get_headers(params['Action'])
).object
return self._to_clusters(data)
@@ -87,7 +93,7 @@ class ElasticContainerDriver(ContainerDriver):
response = self.connection.request(
ROOT,
method='POST',
- data=request,
+ data=json.dumps(request),
headers=self._get_headers('CreateCluster')
).object
return self._to_cluster(response['cluster'])
@@ -103,7 +109,7 @@ class ElasticContainerDriver(ContainerDriver):
data = self.connection.request(
ROOT,
method='POST',
- data=request,
+ data=json.dumps(request),
headers=self._get_headers('DeleteCluster')
).object
return data['cluster']['status'] == 'INACTIVE'
@@ -142,15 +148,15 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: ``list`` of :class:`Container`
"""
- request = None
+ request = {'cluster': 'default'}
if cluster is not None:
- request = {'cluster': cluster.id}
+ request['cluster'] = cluster.id
if image is not None:
request['family'] = image.name
list_response = self.connection.request(
ROOT,
method='POST',
- data=request,
+ data=json.dumps(request),
headers=self._get_headers('ListTasks')
).object
containers = self.ex_list_containers_for_task(
@@ -204,7 +210,7 @@ class ElasticContainerDriver(ContainerDriver):
response = self.connection.request(
ROOT,
method='POST',
- data=data,
+ data=json.dumps(data),
headers=self._get_headers('RegisterTaskDefinition')
).object
if start:
@@ -263,7 +269,7 @@ class ElasticContainerDriver(ContainerDriver):
response = self.connection.request(
ROOT,
method='POST',
- data=request,
+ data=json.dumps(request),
headers=self._get_headers('StopTask')
).object
containers = []
@@ -313,7 +319,7 @@ class ElasticContainerDriver(ContainerDriver):
response = self.connection.request(
ROOT,
method='POST',
- data=request,
+ data=json.dumps(request),
headers=self._get_headers('RunTask')
).object
containers = []
@@ -334,7 +340,7 @@ class ElasticContainerDriver(ContainerDriver):
descripe_response = self.connection.request(
ROOT,
method='POST',
- data=describe_request,
+ data=json.dumps(describe_request),
headers=self._get_headers('DescribeTasks')
).object
containers = []
@@ -375,7 +381,7 @@ class ElasticContainerDriver(ContainerDriver):
response = self.connection.request(
ROOT,
method='POST',
- data=request,
+ data=json.dumps(request),
headers=self._get_headers('CreateService')
).object
return response
@@ -395,7 +401,7 @@ class ElasticContainerDriver(ContainerDriver):
response = self.connection.request(
ROOT,
method='POST',
- data=request,
+ data=json.dumps(request),
headers=self._get_headers('ListServices')
).object
return response['serviceArns']
@@ -419,7 +425,7 @@ class ElasticContainerDriver(ContainerDriver):
response = self.connection.request(
ROOT,
method='POST',
- data=request,
+ data=json.dumps(request),
headers=self._get_headers('DescribeServices')
).object
return response['services'][0]
@@ -440,7 +446,7 @@ class ElasticContainerDriver(ContainerDriver):
response = self.connection.request(
ROOT,
method='POST',
- data=request,
+ data=json.dumps(request),
headers=self._get_headers('DeleteService')
).object
return response
[12/50] libcloud git commit: Updated all delete methods to destroy to
fit with convention of other drivers
Posted by an...@apache.org.
Updated all delete methods to destroy to fit with convention of other drivers
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/7c27da60
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/7c27da60
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/7c27da60
Branch: refs/heads/trunk
Commit: 7c27da603392794de86302db6ef4458f2574f931
Parents: 69cd184
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Dec 28 21:23:15 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Dec 28 21:23:15 2015 +1100
----------------------------------------------------------------------
libcloud/container/base.py | 7 +++++--
libcloud/test/container/test_docker.py | 2 +-
2 files changed, 6 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/7c27da60/libcloud/container/base.py
----------------------------------------------------------------------
diff --git a/libcloud/container/base.py b/libcloud/container/base.py
index b70f1bd..b9750d4 100644
--- a/libcloud/container/base.py
+++ b/libcloud/container/base.py
@@ -72,8 +72,8 @@ class Container(object):
def restart(self):
return self.driver.restart_container(container=self)
- def delete(self):
- return self.driver.delete_container(container=self)
+ def destroy(self):
+ return self.driver.destroy_container(container=self)
def __repr__(self):
return ('<Container: id=%s, name=%s, provider=%s '
@@ -153,6 +153,9 @@ class ContainerCluster(object):
def list_containers(self):
return self.driver.list_containers(cluster=self)
+ def destroy(self):
+ return self.driver.destroy_cluster(cluster=self)
+
def __repr__(self):
return ('<ContainerCluster: id=%s, name=%s, provider=%s ...>' %
(self.id, self.name, self.driver.name))
http://git-wip-us.apache.org/repos/asf/libcloud/blob/7c27da60/libcloud/test/container/test_docker.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_docker.py b/libcloud/test/container/test_docker.py
index 00af5c8..a1978f7 100644
--- a/libcloud/test/container/test_docker.py
+++ b/libcloud/test/container/test_docker.py
@@ -82,7 +82,7 @@ class DockerContainerDriverTestCase(unittest.TestCase):
def test_delete_container(self):
container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303')
- container.delete()
+ container.destroy()
def test_ex_rename_container(self):
container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303')
[06/50] libcloud git commit: Added clusters to the specification,
for ACS, and Google container services,
others based on Kubernetes type deployments may follow. Updated feature table
Posted by an...@apache.org.
Added clusters to the specification, for ACS, and Google container services, others based on Kubernetes type deployments may follow. Updated feature table
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/8e749b5c
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/8e749b5c
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/8e749b5c
Branch: refs/heads/trunk
Commit: 8e749b5cd385b3e04ba3987c21ac217c0ff1e1ce
Parents: 6d83dc0
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Dec 23 17:26:29 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Dec 23 17:26:29 2015 +1100
----------------------------------------------------------------------
.../generate_provider_feature_matrix_table.py | 11 +-
docs/container/_supported_methods.rst | 12 +-
libcloud/container/base.py | 135 ++++++++++++++++++-
libcloud/container/drivers/docker.py | 65 ++++-----
libcloud/container/drivers/dummy.py | 1 +
libcloud/container/drivers/joyent.py | 1 +
6 files changed, 175 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8e749b5c/contrib/generate_provider_feature_matrix_table.py
----------------------------------------------------------------------
diff --git a/contrib/generate_provider_feature_matrix_table.py b/contrib/generate_provider_feature_matrix_table.py
index 58d571f..3995eb2 100755
--- a/contrib/generate_provider_feature_matrix_table.py
+++ b/contrib/generate_provider_feature_matrix_table.py
@@ -96,7 +96,9 @@ BASE_API_METHODS = {
'delete_zone', 'delete_record'],
'container': ['install_image', 'list_images', 'deploy_container',
'get_container', 'start_container', 'stop_container',
- 'restart_container', 'delete_container']
+ 'restart_container', 'delete_container', 'list_containers',
+ 'list_locations', 'create_cluster', 'delete_cluster',
+ 'list_clusters']
}
FRIENDLY_METHODS_NAMES = {
@@ -173,10 +175,15 @@ FRIENDLY_METHODS_NAMES = {
'list_images': 'list images',
'deploy_container': 'deploy container',
'get_container': 'get container',
+ 'list_containers': 'list containers',
'start_container': 'start container',
'stop_container': 'stop container',
'restart_container': 'restart container',
- 'delete_container': 'delete container'
+ 'delete_container': 'delete container',
+ 'list_locations': 'list locations',
+ 'create_cluster': 'create cluster',
+ 'delete_cluster': 'delete cluster',
+ 'list_clusters': 'list clusters'
}
}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8e749b5c/docs/container/_supported_methods.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_methods.rst b/docs/container/_supported_methods.rst
index daceb3e..1a8c963 100644
--- a/docs/container/_supported_methods.rst
+++ b/docs/container/_supported_methods.rst
@@ -1,11 +1,11 @@
.. NOTE: This file has been generated automatically using generate_provider_feature_matrix_table.py script, don't manually edit it
-========= ============= =========== ================ ============= =============== ============== ================= ================
-Provider install image list images deploy container get container start container stop container restart container delete container
-========= ============= =========== ================ ============= =============== ============== ================= ================
-`Docker`_ yes yes yes yes yes yes yes yes
-`Joyent`_ yes yes yes yes yes yes yes yes
-========= ============= =========== ================ ============= =============== ============== ================= ================
+========= ============= =========== ================ ============= =============== ============== ================= ================ =============== ============== ============== ============== =============
+Provider install image list images deploy container get container start container stop container restart container delete container list containers list locations create cluster delete cluster list clusters
+========= ============= =========== ================ ============= =============== ============== ================= ================ =============== ============== ============== ============== =============
+`Docker`_ yes yes yes yes yes yes yes yes yes no no no no
+`Joyent`_ yes yes yes yes yes yes yes yes yes no no no no
+========= ============= =========== ================ ============= =============== ============== ================= ================ =============== ============== ============== ============== =============
.. _`Docker`: http://docker.io
.. _`Joyent`: http://joyent.com
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8e749b5c/libcloud/container/base.py
----------------------------------------------------------------------
diff --git a/libcloud/container/base.py b/libcloud/container/base.py
index 0d26035..ec28308 100644
--- a/libcloud/container/base.py
+++ b/libcloud/container/base.py
@@ -21,6 +21,7 @@ from libcloud.common.base import ConnectionUserAndKey, BaseDriver
__all__ = [
'Container',
'ContainerImage',
+ 'ContainerCluster',
'ContainerDriver'
]
@@ -30,7 +31,8 @@ class Container(object):
Container.
"""
- def __init__(self, id, name, image, state, driver, extra=None):
+ def __init__(self, id, name, image, state,
+ ip_addresses, driver, extra=None):
"""
:param id: Container id.
:type id: ``str``
@@ -44,6 +46,9 @@ class Container(object):
:param state: The state of the container, e.g. running
:type state: :class:`libcloud.container.types.ContainerState`
+ :param ip_addresses: A list of IP addresses for this container
+ :type ip_addresses: ``list`` of ``str``
+
:param driver: ContainerDriver instance.
:type driver: :class:`ContainerDriver`
@@ -54,6 +59,7 @@ class Container(object):
self.name = name
self.image = image
self.state = state
+ self.ip_addresses = ip_addresses
self.driver = driver
self.extra = extra or {}
@@ -120,6 +126,73 @@ class ContainerImage(object):
(self.id, self.name, self.driver.name))
+class ContainerCluster(object):
+ """
+ A cluster group for containers
+ """
+
+ def __init__(self, id, name, driver, extra=None):
+ """
+ :param id: Container Image id.
+ :type id: ``str``
+
+ :param name: The name of the image.
+ :type name: ``str``
+
+ :param driver: ContainerDriver instance.
+ :type driver: :class:`ContainerDriver`
+
+ :param extra: (optional) Extra attributes (driver specific).
+ :type extra: ``dict``
+ """
+ self.id = str(id) if id else None
+ self.name = name
+ self.driver = driver
+ self.extra = extra or {}
+
+ def list_containers(self):
+ return self.driver.list_containers(cluster=self)
+
+ def __repr__(self):
+ return ('<ContainerCluster: id=%s, name=%s, provider=%s ...>' %
+ (self.id, self.name, self.driver.name))
+
+
+class ClusterLocation(object):
+ """
+ A physical location where clusters can be.
+
+ >>> from libcloud.container.drivers.dummy import DummyNodeDriver
+ >>> driver = DummyNodeDriver(0)
+ >>> location = driver.list_locations()[0]
+ >>> location.country
+ 'US'
+ """
+
+ def __init__(self, id, name, country, driver):
+ """
+ :param id: Location ID.
+ :type id: ``str``
+
+ :param name: Location name.
+ :type name: ``str``
+
+ :param country: Location country.
+ :type country: ``str``
+
+ :param driver: Driver this location belongs to.
+ :type driver: :class:`.NodeDriver`
+ """
+ self.id = str(id)
+ self.name = name
+ self.country = country
+ self.driver = driver
+
+ def __repr__(self):
+ return (('<ClusterLocation: id=%s, name=%s, country=%s, driver=%s>')
+ % (self.id, self.name, self.country, self.driver.name))
+
+
class ContainerDriver(BaseDriver):
"""
A base ContainerDriver class to derive from
@@ -129,6 +202,10 @@ class ContainerDriver(BaseDriver):
connectionCls = ConnectionUserAndKey
name = None
website = None
+ supports_clusters = False
+ """
+ Whether the driver supports containers being deployed into clusters
+ """
def __init__(self, key, secret=None, secure=True, host=None, port=None,
**kwargs):
@@ -176,19 +253,23 @@ class ContainerDriver(BaseDriver):
raise NotImplementedError(
'list_images not implemented for this driver')
- def list_containers(self, image=None):
+ def list_containers(self, image=None, cluster=None):
"""
List the deployed container images
:param image: Filter to containers with a certain image
:type image: :class:`ContainerImage`
+ :param cluster: Filter to containers in a cluster
+ :type cluster: :class:`ContainerCluster`
+
:rtype: ``list`` of :class:`Container`
"""
raise NotImplementedError(
'list_containers not implemented for this driver')
- def deploy_container(self, name, image, parameters=None, start=True):
+ def deploy_container(self, name, image, cluster=None,
+ parameters=None, start=True):
"""
Deploy an installed container image
@@ -198,6 +279,9 @@ class ContainerDriver(BaseDriver):
:param image: The container image to deploy
:type image: :class:`ContainerImage`
+ :param cluster: The cluster to deploy to, None is default
+ :type cluster: :class:`ContainerCluster`
+
:param parameters: Container Image parameters
:type parameters: ``str``
@@ -268,3 +352,48 @@ class ContainerDriver(BaseDriver):
"""
raise NotImplementedError(
'delete_container not implemented for this driver')
+
+ def list_locations(self):
+ """
+ Get a list of potential locations to deploy clusters into
+
+ :rtype: ``list`` of :class:`ClusterLocation`
+ """
+ raise NotImplementedError(
+ 'list_locations not implemented for this driver')
+
+ def create_cluster(self, name, location=None):
+ """
+ Create a container cluster
+
+ :param name: The name of the cluster
+ :type name: ``str``
+
+ :param location: The location to create the cluster in
+ :type location: :class:`ClusterLocation`
+
+ :rtype: :class:`ContainerCluster`
+ """
+ raise NotImplementedError(
+ 'create_cluster not implemented for this driver')
+
+ def delete_cluster(self, cluster):
+ """
+ Delete a cluster
+
+ :rtype: ``list`` of :class:`ClusterLocation`
+ """
+ raise NotImplementedError(
+ 'delete_cluster not implemented for this driver')
+
+ def list_clusters(self, location=None):
+ """
+ Get a list of potential locations to deploy clusters into
+
+ :param location: The location to search in
+ :type location: :class:`ClusterLocation`
+
+ :rtype: ``list`` of :class:`ContainerCluster`
+ """
+ raise NotImplementedError(
+ 'list_clusters not implemented for this driver')
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8e749b5c/libcloud/container/drivers/docker.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/docker.py b/libcloud/container/drivers/docker.py
index e1c2043..3e456d5 100644
--- a/libcloud/container/drivers/docker.py
+++ b/libcloud/container/drivers/docker.py
@@ -128,6 +128,7 @@ class DockerContainerDriver(ContainerDriver):
name = 'Docker'
website = 'http://docker.io'
connectionCls = DockerConnection
+ supports_clusters = False
def __init__(self, key=None, secret=None, secure=False, host='localhost',
port=4243, key_file=None, cert_file=None):
@@ -356,35 +357,7 @@ class DockerContainerDriver(ContainerDriver):
result = self.connection.request("/containers/%s/json" %
id).object
- name = result.get('Name').strip('/')
- if result['State']['Running']:
- state = ContainerState.RUNNING
- else:
- state = ContainerState.STOPPED
- image = result.get('Image')
- extra = {
- 'volumes': result.get('Volumes'),
- 'env': result.get('Config', {}).get('Env'),
- 'ports': result.get('ExposedPorts'),
- 'network_settings': result.get('NetworkSettings', {})
- }
- container_id = result.get('Id')
- if not container_id:
- container_id = result.get('ID', '')
- container = (Container(
- id=container_id,
- name=name,
- image=ContainerImage(
- id=None,
- path=image,
- name=image,
- version=None,
- driver=self.connection.driver
- ),
- state=state,
- driver=self.connection.driver,
- extra=extra))
- return container
+ return self._to_container(result)
def start_container(self, container):
"""
@@ -586,29 +559,43 @@ class DockerContainerDriver(ContainerDriver):
Convert container in Container instances
"""
try:
- name = data.get('Names')[0].strip('/')
+ name = data.get('Name').strip('/')
except:
- name = data.get('Id')
- if 'Exited' in data.get('Status'):
+ try:
+ name = data.get('Names')[0].strip('/')
+ except:
+ name = data.get('Id')
+ state = data.get('State')
+ status = data.get('Status',
+ state.get('Status')
+ if state is not None else None)
+ if 'Exited' in status:
state = ContainerState.STOPPED
- elif data.get('Status').startswith('Up '):
+ elif status.startswith('Up '):
state = ContainerState.RUNNING
else:
state = ContainerState.STOPPED
image = data.get('Image')
- ports = json.dumps(data.get('Ports', {}))
+ ports = data.get('Ports', [])
+ created = data.get('Created')
+ if isinstance(created, float):
+ created = ts_to_str(created)
extra = {
'id': data.get('Id'),
'status': data.get('Status'),
- 'created': ts_to_str(data.get('Created')),
+ 'created': created,
'image': image,
'ports': ports,
'command': data.get('Command'),
'sizerw': data.get('SizeRw'),
'sizerootfs': data.get('SizeRootFs'),
}
-
- node = (Container(
+ ips = []
+ if ports is not None:
+ for port in ports:
+ if port.get('IP') is not None:
+ ips.append(port.get('IP'))
+ return Container(
id=data['Id'],
name=name,
image=ContainerImage(
@@ -618,10 +605,10 @@ class DockerContainerDriver(ContainerDriver):
version=None,
driver=self.connection.driver
),
+ ip_addresses=ips,
state=state,
driver=self.connection.driver,
- extra=extra))
- return node
+ extra=extra)
def _get_api_version(self):
"""
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8e749b5c/libcloud/container/drivers/dummy.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/dummy.py b/libcloud/container/drivers/dummy.py
index b3f5db5..2c99259 100644
--- a/libcloud/container/drivers/dummy.py
+++ b/libcloud/container/drivers/dummy.py
@@ -28,6 +28,7 @@ class DummyContainerDriver(ContainerDriver):
name = 'Dummy Container Provider'
website = 'http://example.com'
+ supports_clusters = False
def __init__(self, api_key, api_secret):
"""
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8e749b5c/libcloud/container/drivers/joyent.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/joyent.py b/libcloud/container/drivers/joyent.py
index f236808..e380f6a 100644
--- a/libcloud/container/drivers/joyent.py
+++ b/libcloud/container/drivers/joyent.py
@@ -34,6 +34,7 @@ class JoyentContainerDriver(DockerContainerDriver):
name = 'Joyent'
website = 'http://joyent.com'
connectionCls = DockerConnection
+ supports_clusters = False
def __init__(self, key=None, secret=None, secure=False, host='localhost',
port=2376, key_file=None, cert_file=None):
[50/50] libcloud git commit: Update the docs with the version
numbers. Mark the kubernetes driver as subject to change. Closes #666
Posted by an...@apache.org.
Update the docs with the version numbers. Mark the kubernetes driver as subject to change.
Closes #666
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/a313623d
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/a313623d
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/a313623d
Branch: refs/heads/trunk
Commit: a313623d56dc58920bc8940da723826f8b9b2ddd
Parents: 65bc1dd
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Jan 20 10:21:03 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Jan 20 14:43:14 2016 +1100
----------------------------------------------------------------------
docs/container/drivers/kubernetes.rst | 5 +++++
docs/container/index.rst | 6 +++++-
2 files changed, 10 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a313623d/docs/container/drivers/kubernetes.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/kubernetes.rst b/docs/container/drivers/kubernetes.rst
index e0253bd..e1c77e9 100644
--- a/docs/container/drivers/kubernetes.rst
+++ b/docs/container/drivers/kubernetes.rst
@@ -1,6 +1,11 @@
Kubernetes Documentation
========================
+.. note::
+
+ This Kubernetes driver will be subject to change from community feedback. How to map the core assets (pods, clusters) to API
+ entities will be subject to testing and further community feedback.
+
Kubernetes is an open source orchestration system for Docker containers. It handles scheduling onto nodes in a compute cluster and actively manages workloads to ensure that their state matches the users declared intentions. Using the concepts of "labels" and "pods",
it groups the containers which make up an application into logical units for easy management and discovery.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a313623d/docs/container/index.rst
----------------------------------------------------------------------
diff --git a/docs/container/index.rst b/docs/container/index.rst
index 2b33b4a..f763e9d 100644
--- a/docs/container/index.rst
+++ b/docs/container/index.rst
@@ -3,7 +3,11 @@ Container
.. note::
- Container API is available in Libcloud 0.21.0 and higher.
+ Container API is available in Libcloud 1.0.0RC and higher.
+
+.. note::
+
+ Container API is currently in an EXPERIMENTAL state.
Container API allows users to install and deploy containers onto container based virtualization platforms. This is designed to target both
on-premise installations of software like Docker as well as interfacing with Cloud Service Providers that offer Container-as-a-Service APIs.
[19/50] libcloud git commit: Docs for ECS driver
Posted by an...@apache.org.
Docs for ECS driver
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/0999e520
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0999e520
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0999e520
Branch: refs/heads/trunk
Commit: 0999e520ed9e768c904f0dd7e53c7f4474fcdc50
Parents: 5473771
Author: anthony-shaw <an...@gmail.com>
Authored: Sat Jan 2 07:35:55 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sat Jan 2 07:35:55 2016 +1100
----------------------------------------------------------------------
docs/container/drivers/ecs.rst | 25 ++++++++++++++++++++
.../container/ecs/instantiate_driver.py | 12 ++++++++++
2 files changed, 37 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0999e520/docs/container/drivers/ecs.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/ecs.rst b/docs/container/drivers/ecs.rst
new file mode 100644
index 0000000..45cc2f8
--- /dev/null
+++ b/docs/container/drivers/ecs.rst
@@ -0,0 +1,25 @@
+Amazon Elastic Container Service Documentation
+==============================================
+
+Elastic Container Service is a container-as-a-service feature of `AWS`_.
+
+.. figure:: /_static/images/provider_logos/aws.svg
+ :align: center
+ :width: 300
+ :target: http://aws.amazon.com/
+
+Instantiating the driver
+-------------------------------------
+
+.. literalinclude:: /examples/container/ecs/instantiate_driver.py
+ :language: python
+
+API Docs
+--------
+
+.. autoclass:: libcloud.container.drivers.ecs.ElasticContainerDriver
+ :members:
+ :inherited-members:
+
+
+.. _`AWS`: https://aws.amazon.com/
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0999e520/docs/examples/container/ecs/instantiate_driver.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/ecs/instantiate_driver.py b/docs/examples/container/ecs/instantiate_driver.py
new file mode 100644
index 0000000..a854745
--- /dev/null
+++ b/docs/examples/container/ecs/instantiate_driver.py
@@ -0,0 +1,12 @@
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+
+import libcloud.security
+libcloud.security.VERIFY_SSL_CERT = False
+
+cls = get_driver(Provider.ECS)
+
+conn = cls(access_id='AKIAI7OR4GWEEPRIFBBA', secret='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', region='ap-southeast-2')
+conn.connection.set_http_proxy(proxy_url='http://localhost:8888')
+
+print(conn.list_containers())
[38/50] libcloud git commit: Added a utility class for the Docker Hub
(and therefore docker registry v2 API hosts)
Posted by an...@apache.org.
Added a utility class for the Docker Hub (and therefore docker registry v2 API hosts)
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/223b5178
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/223b5178
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/223b5178
Branch: refs/heads/trunk
Commit: 223b5178de08b46862d558c81c20d1cd6e5171a7
Parents: 6e4df6d
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Jan 11 10:23:17 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Jan 11 10:23:17 2016 +1100
----------------------------------------------------------------------
docs/container/index.rst | 8 +-
docs/container/utilities.rst | 7 +
libcloud/container/util/__init__.py | 0
libcloud/container/util/docker.py | 137 +++++++
.../fixtures/docker/list_tags_ubuntu.json | 354 +++++++++++++++++++
5 files changed, 505 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/223b5178/docs/container/index.rst
----------------------------------------------------------------------
diff --git a/docs/container/index.rst b/docs/container/index.rst
index 4f5fb66..2b33b4a 100644
--- a/docs/container/index.rst
+++ b/docs/container/index.rst
@@ -128,4 +128,10 @@ API Reference
-------------
For a full reference of all the classes and methods exposed by the Container
-API, see :doc:`this page </container/api>`.
\ No newline at end of file
+API, see :doc:`this page </container/api>`.
+
+Utility Classes
+---------------
+
+There are some utility classes for example, a Docker Hub API client for fetching images
+and iterating through repositories see :doc:`this page </container/utilities>`.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/223b5178/docs/container/utilities.rst
----------------------------------------------------------------------
diff --git a/docs/container/utilities.rst b/docs/container/utilities.rst
new file mode 100644
index 0000000..48aafc2
--- /dev/null
+++ b/docs/container/utilities.rst
@@ -0,0 +1,7 @@
+:orphan:
+
+Container Utility API
+=====================
+
+.. autoclass:: libcloud.container.util.HubClient
+ :members:
http://git-wip-us.apache.org/repos/asf/libcloud/blob/223b5178/libcloud/container/util/__init__.py
----------------------------------------------------------------------
diff --git a/libcloud/container/util/__init__.py b/libcloud/container/util/__init__.py
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/libcloud/blob/223b5178/libcloud/container/util/docker.py
----------------------------------------------------------------------
diff --git a/libcloud/container/util/docker.py b/libcloud/container/util/docker.py
new file mode 100644
index 0000000..3edfec8
--- /dev/null
+++ b/libcloud/container/util/docker.py
@@ -0,0 +1,137 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import with_statement
+
+from requests.auth import HTTPBasicAuth
+import requests
+
+from libcloud.container.base import ContainerImage
+
+__all__ = [
+ 'HubClient'
+]
+
+
+class HubClient(object):
+ """
+ A client for the Docker Hub API
+
+ The hub is based on the v1 registry API
+ """
+ host = 'registry.hub.docker.com'
+ base_url = 'https://%s/' % (host)
+
+ def __init__(self, username=None, password=None):
+ """
+ Construct a Docker hub client
+
+ :param username: (optional) Your Hub account username
+ :type username: ``str``
+
+ :param password: (optional) Your hub account password
+ :type password: ``str``
+ """
+ if username is not None:
+ self.auth = HTTPBasicAuth(username, password)
+ else:
+ self.auth = None
+
+ def list_tags(self, repository_name, namespace='library', max_count=100):
+ """
+ List the tags (versions) in a repository
+
+ :param repository_name: The name of the repository e.g. 'ubuntu'
+ :type repository_name: ``str``
+
+ :param namespace: (optional) The docker namespace
+ :type namespace: ``str``
+
+ :param max_count: The maximum number of records to return
+ :type max_count: ``int``
+
+ :return: A list of tags
+ :rtype: ``list`` of ``object``
+ """
+ path = 'v2/repositories/%s/%s/tags/?page=1&page_size=%s' \
+ % (namespace, repository_name, max_count)
+ response = requests.get(self.base_url + path, auth=self.auth)
+ return response.json().results
+
+ def list_image_ids(self, repository_name, namespace='library'):
+ """
+ List the image IDs (versions) in a repository
+
+ :param repository_name: The name of the repository e.g. 'ubuntu'
+ :type repository_name: ``str``
+
+ :param namespace: (optional) The docker namespace
+ :type namespace: ``str``
+
+ :return: A list of ids
+ :rtype: ``list`` of ``object``
+ """
+ path = 'v1/repositories/%s/%s/images' % (namespace, repository_name)
+ response = requests.get(self.base_url + path, auth=self.auth)
+ return response.json()
+
+ def get_repository(self, repository_name, namespace='library'):
+ """
+ Get the information about a specific repository
+
+ :param repository_name: The name of the repository e.g. 'ubuntu'
+ :type repository_name: ``str``
+
+ :param namespace: (optional) The docker namespace
+ :type namespace: ``str``
+
+ :return: The details of the repository
+ :rtype: ``object``
+ """
+ path = 'v2/repositories/%s/%s' % (namespace, repository_name)
+ response = requests.get(self.base_url + path, auth=self.auth)
+ return response.json()
+
+ def get_image(self, repository_name, tag='latest', namespace='library'):
+ """
+ Get an image from a repository with a specific tag
+
+ :param repository_name: The name of the repository, e.g. ubuntu
+ :type repository_name: ``str``
+
+ :param tag: (optional) The image tag (defaults to latest)
+ :type tag: ``str``
+
+ :param namespace: (optional) The docker namespace
+ :type namespace: ``str``
+
+ :return: A container image
+ :rtype: :class:`libcloud.container.base.ContainerImage`
+ """
+ path = 'v2/repositories/%s/%s/tags/%s' \
+ % (namespace, repository_name, tag)
+ response = requests.get(self.base_url + path, auth=self.auth)
+ obj = response.json()
+ path = '%s/%s:%s' % (self.host, repository_name, tag)
+ return ContainerImage(
+ id=obj['id'],
+ path=path,
+ name=path,
+ version=tag,
+ extra={
+ 'full_size': obj['full_size']
+ },
+ driver=None
+ )
http://git-wip-us.apache.org/repos/asf/libcloud/blob/223b5178/libcloud/test/container/fixtures/docker/list_tags_ubuntu.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/docker/list_tags_ubuntu.json b/libcloud/test/container/fixtures/docker/list_tags_ubuntu.json
new file mode 100644
index 0000000..2786d5c
--- /dev/null
+++ b/libcloud/test/container/fixtures/docker/list_tags_ubuntu.json
@@ -0,0 +1,354 @@
+[
+ {
+ "layer": "af88597e",
+ "name": "latest"
+ },
+ {
+ "layer": "3db9c44f",
+ "name": "10.04"
+ },
+ {
+ "layer": "bad926a6",
+ "name": "12.04"
+ },
+ {
+ "layer": "bad926a6",
+ "name": "12.04.5"
+ },
+ {
+ "layer": "c5881f11",
+ "name": "12.10"
+ },
+ {
+ "layer": "463ff6be",
+ "name": "13.04"
+ },
+ {
+ "layer": "195eb90b",
+ "name": "13.10"
+ },
+ {
+ "layer": "af88597e",
+ "name": "14.04"
+ },
+ {
+ "layer": "5ba9dab4",
+ "name": "14.04.1"
+ },
+ {
+ "layer": "63e3c102",
+ "name": "14.04.2"
+ },
+ {
+ "layer": "af88597e",
+ "name": "14.04.3"
+ },
+ {
+ "layer": "dce38fb5",
+ "name": "14.10"
+ },
+ {
+ "layer": "3f0d2d4f",
+ "name": "15.04"
+ },
+ {
+ "layer": "3e0c71ad",
+ "name": "15.10"
+ },
+ {
+ "layer": "db856b41",
+ "name": "16.04"
+ },
+ {
+ "layer": "3db9c44f",
+ "name": "lucid"
+ },
+ {
+ "layer": "bad926a6",
+ "name": "precise"
+ },
+ {
+ "layer": "1f80e9ca",
+ "name": "precise-20150212"
+ },
+ {
+ "layer": "5898adab",
+ "name": "precise-20150228.11"
+ },
+ {
+ "layer": "9610cfc6",
+ "name": "precise-20150320"
+ },
+ {
+ "layer": "ac6b0eaa",
+ "name": "precise-20150427"
+ },
+ {
+ "layer": "5c97af89",
+ "name": "precise-20150528"
+ },
+ {
+ "layer": "78cef618",
+ "name": "precise-20150612"
+ },
+ {
+ "layer": "6d021018",
+ "name": "precise-20150626"
+ },
+ {
+ "layer": "d0e008c6",
+ "name": "precise-20150729"
+ },
+ {
+ "layer": "57bca513",
+ "name": "precise-20150813"
+ },
+ {
+ "layer": "61994089",
+ "name": "precise-20150924"
+ },
+ {
+ "layer": "0ac5b09d",
+ "name": "precise-20151020"
+ },
+ {
+ "layer": "04c3793b",
+ "name": "precise-20151028"
+ },
+ {
+ "layer": "bad926a6",
+ "name": "precise-20151208"
+ },
+ {
+ "layer": "c5881f11",
+ "name": "quantal"
+ },
+ {
+ "layer": "463ff6be",
+ "name": "raring"
+ },
+ {
+ "layer": "195eb90b",
+ "name": "saucy"
+ },
+ {
+ "layer": "af88597e",
+ "name": "trusty"
+ },
+ {
+ "layer": "2d24f826",
+ "name": "trusty-20150218.1"
+ },
+ {
+ "layer": "2103b00b",
+ "name": "trusty-20150228.11"
+ },
+ {
+ "layer": "b7cf8f0d",
+ "name": "trusty-20150320"
+ },
+ {
+ "layer": "07f8e8c5",
+ "name": "trusty-20150427"
+ },
+ {
+ "layer": "fa81ed08",
+ "name": "trusty-20150528"
+ },
+ {
+ "layer": "6d494699",
+ "name": "trusty-20150612"
+ },
+ {
+ "layer": "d2a0ecff",
+ "name": "trusty-20150630"
+ },
+ {
+ "layer": "63e3c102",
+ "name": "trusty-20150730"
+ },
+ {
+ "layer": "8251da35",
+ "name": "trusty-20150806"
+ },
+ {
+ "layer": "91e54dfb",
+ "name": "trusty-20150814"
+ },
+ {
+ "layer": "cdd47452",
+ "name": "trusty-20151001"
+ },
+ {
+ "layer": "a005e6b7",
+ "name": "trusty-20151009"
+ },
+ {
+ "layer": "a5a467fd",
+ "name": "trusty-20151021"
+ },
+ {
+ "layer": "ca4d7b1b",
+ "name": "trusty-20151028"
+ },
+ {
+ "layer": "d55e68e6",
+ "name": "trusty-20151208"
+ },
+ {
+ "layer": "af88597e",
+ "name": "trusty-20151218"
+ },
+ {
+ "layer": "dce38fb5",
+ "name": "utopic"
+ },
+ {
+ "layer": "78949b1e",
+ "name": "utopic-20150211"
+ },
+ {
+ "layer": "525b6e4a",
+ "name": "utopic-20150228.11"
+ },
+ {
+ "layer": "59a878f2",
+ "name": "utopic-20150319"
+ },
+ {
+ "layer": "0b79d1c2",
+ "name": "utopic-20150418"
+ },
+ {
+ "layer": "d191563a",
+ "name": "utopic-20150427"
+ },
+ {
+ "layer": "ce78e71c",
+ "name": "utopic-20150528"
+ },
+ {
+ "layer": "ab57dbaf",
+ "name": "utopic-20150612"
+ },
+ {
+ "layer": "dce38fb5",
+ "name": "utopic-20150625"
+ },
+ {
+ "layer": "3f0d2d4f",
+ "name": "vivid"
+ },
+ {
+ "layer": "2427658c",
+ "name": "vivid-20150218"
+ },
+ {
+ "layer": "19c8c047",
+ "name": "vivid-20150309"
+ },
+ {
+ "layer": "751a7482",
+ "name": "vivid-20150319.1"
+ },
+ {
+ "layer": "ef8182f3",
+ "name": "vivid-20150421"
+ },
+ {
+ "layer": "bd94ae58",
+ "name": "vivid-20150427"
+ },
+ {
+ "layer": "c6a35822",
+ "name": "vivid-20150528"
+ },
+ {
+ "layer": "6be21d1e",
+ "name": "vivid-20150611"
+ },
+ {
+ "layer": "23635bbe",
+ "name": "vivid-20150802"
+ },
+ {
+ "layer": "013f3d01",
+ "name": "vivid-20150813"
+ },
+ {
+ "layer": "82554298",
+ "name": "vivid-20150930"
+ },
+ {
+ "layer": "4e9c8310",
+ "name": "vivid-20151021"
+ },
+ {
+ "layer": "e97f8c6b",
+ "name": "vivid-20151106"
+ },
+ {
+ "layer": "db672630",
+ "name": "vivid-20151111"
+ },
+ {
+ "layer": "3f0d2d4f",
+ "name": "vivid-20151208"
+ },
+ {
+ "layer": "3e0c71ad",
+ "name": "wily"
+ },
+ {
+ "layer": "0fe5a10d",
+ "name": "wily-20150528.1"
+ },
+ {
+ "layer": "906f2d7d",
+ "name": "wily-20150611"
+ },
+ {
+ "layer": "22ba5544",
+ "name": "wily-20150708"
+ },
+ {
+ "layer": "6767f35d",
+ "name": "wily-20150731"
+ },
+ {
+ "layer": "1832625b",
+ "name": "wily-20150807"
+ },
+ {
+ "layer": "53816304",
+ "name": "wily-20150818"
+ },
+ {
+ "layer": "1884caee",
+ "name": "wily-20150829"
+ },
+ {
+ "layer": "4dc94650",
+ "name": "wily-20151006"
+ },
+ {
+ "layer": "6171b5c3",
+ "name": "wily-20151009"
+ },
+ {
+ "layer": "337d0fd7",
+ "name": "wily-20151019"
+ },
+ {
+ "layer": "3e0c71ad",
+ "name": "wily-20151208"
+ },
+ {
+ "layer": "db856b41",
+ "name": "xenial"
+ },
+ {
+ "layer": "db856b41",
+ "name": "xenial-20151218.1"
+ }
+]
\ No newline at end of file
[22/50] libcloud git commit: Updated AWS unit tests for the request
signing mocks with the new method signatures.
Posted by an...@apache.org.
Updated AWS unit tests for the request signing mocks with the new method signatures.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/57a0ca90
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/57a0ca90
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/57a0ca90
Branch: refs/heads/trunk
Commit: 57a0ca90fe29fdc617cc62564325e8ae91c15e14
Parents: 4bde5af
Author: anthony-shaw <an...@gmail.com>
Authored: Sun Jan 3 21:01:23 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sun Jan 3 21:01:23 2016 +1100
----------------------------------------------------------------------
libcloud/test/common/test_aws.py | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/57a0ca90/libcloud/test/common/test_aws.py
----------------------------------------------------------------------
diff --git a/libcloud/test/common/test_aws.py b/libcloud/test/common/test_aws.py
index 6661f7d..c855534 100644
--- a/libcloud/test/common/test_aws.py
+++ b/libcloud/test/common/test_aws.py
@@ -53,10 +53,10 @@ class AWSRequestSignerAlgorithmV4TestCase(LibcloudTestCase):
'SignedHeaders=accept-encoding;host;user-agent;x-amz-date, '
'Signature=f9868f8414b3c3f856c7955019cc1691265541f5162b9b772d26044280d39bd3')
- def test_v4_signature_raises_error_if_request_method_not_GET(self):
+ def test_v4_signature_raises_error_if_request_method_not_GET_OR_POST(self):
with self.assertRaises(Exception):
self.signer._get_authorization_v4_header(params={}, headers={},
- dt=self.now, method='POST')
+ dt=self.now, method='PUT')
def test_v4_signature_contains_user_id(self):
sig = self.signer._get_authorization_v4_header(params={}, headers={},
@@ -97,7 +97,7 @@ class AWSRequestSignerAlgorithmV4TestCase(LibcloudTestCase):
mock_get_key.return_value = 'my_signing_key'
mock_get_string.return_value = 'my_string_to_sign'
sig = self.signer._get_signature({}, {}, self.now,
- method='GET', path='/')
+ method='GET', path='/', data=None)
self.assertEqual(sig, 'H|my_signing_key|my_string_to_sign')
@@ -105,7 +105,7 @@ class AWSRequestSignerAlgorithmV4TestCase(LibcloudTestCase):
with mock.patch('hashlib.sha256') as mock_sha256:
mock_sha256.return_value.hexdigest.return_value = 'chksum_of_canonical_request'
to_sign = self.signer._get_string_to_sign({}, {}, self.now,
- method='GET', path='/')
+ method='GET', path='/', data=None)
self.assertEqual(to_sign,
'AWS4-HMAC-SHA256\n'
@@ -216,7 +216,7 @@ class AWSRequestSignerAlgorithmV4TestCase(LibcloudTestCase):
def test_get_payload_hash_returns_digest_of_empty_string_for_GET_requests(self):
SignedAWSConnection.method = 'GET'
- self.assertEqual(self.signer._get_payload_hash(),
+ self.assertEqual(self.signer._get_payload_hash(method='GET'),
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')
def test_get_canonical_request(self):
@@ -224,7 +224,8 @@ class AWSRequestSignerAlgorithmV4TestCase(LibcloudTestCase):
{'Action': 'DescribeInstances', 'Version': '2013-10-15'},
{'Accept-Encoding': 'gzip,deflate', 'User-Agent': 'My-UA'},
method='GET',
- path='/my_action/'
+ path='/my_action/',
+ data=None
)
self.assertEqual(req, 'GET\n'
'/my_action/\n'
@@ -235,5 +236,22 @@ class AWSRequestSignerAlgorithmV4TestCase(LibcloudTestCase):
'accept-encoding;user-agent\n'
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')
+ def test_post_canonical_request(self):
+ req = self.signer._get_canonical_request(
+ {'Action': 'DescribeInstances', 'Version': '2013-10-15'},
+ {'Accept-Encoding': 'gzip,deflate', 'User-Agent': 'My-UA'},
+ method='POST',
+ path='/my_action/',
+ data='{}'
+ )
+ self.assertEqual(req, 'POST\n'
+ '/my_action/\n'
+ 'Action=DescribeInstances&Version=2013-10-15\n'
+ 'accept-encoding:gzip,deflate\n'
+ 'user-agent:My-UA\n'
+ '\n'
+ 'accept-encoding;user-agent\n'
+ '44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a')
+
if __name__ == '__main__':
sys.exit(unittest.main())
[28/50] libcloud git commit: Improved the documentation to better
explain the 2 types of drivers (cluster and non-cluster)
Posted by an...@apache.org.
Improved the documentation to better explain the 2 types of drivers (cluster and non-cluster)
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c188d325
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c188d325
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c188d325
Branch: refs/heads/trunk
Commit: c188d325ebae989cffd2241fb3170fb99e52adec
Parents: 8c01c62
Author: anthony-shaw <an...@gmail.com>
Authored: Tue Jan 5 20:49:05 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Tue Jan 5 20:49:05 2016 +1100
----------------------------------------------------------------------
docs/container/api.rst | 6 ++
docs/container/examples.rst | 8 +++
docs/container/index.rst | 33 ++++++++++-
.../examples/container/working_with_clusters.py | 24 ++++++++
libcloud/container/base.py | 58 ++++++++++----------
libcloud/container/drivers/docker.py | 38 ++++++-------
libcloud/container/drivers/ecs.py | 50 ++++++++---------
7 files changed, 141 insertions(+), 76 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c188d325/docs/container/api.rst
----------------------------------------------------------------------
diff --git a/docs/container/api.rst b/docs/container/api.rst
index f9f7dd4..257b1a7 100644
--- a/docs/container/api.rst
+++ b/docs/container/api.rst
@@ -11,3 +11,9 @@ Container Base API
.. autoclass:: libcloud.container.base.ContainerImage
:members:
+
+.. autoclass:: libcloud.container.base.ContainerCluster
+ :members:
+
+.. autoclass:: libcloud.container.base.ClusterLocation
+ :members:
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c188d325/docs/container/examples.rst
----------------------------------------------------------------------
diff --git a/docs/container/examples.rst b/docs/container/examples.rst
index 7e63b2b..a4e4316 100644
--- a/docs/container/examples.rst
+++ b/docs/container/examples.rst
@@ -12,4 +12,12 @@ This example shows how to get install a container image, deploy and start that c
This example works with Libcloud version 0.21.0 and above.
.. literalinclude:: /examples/container/install_and_deploy.py
+ :language: python
+
+Working with cluster supported providers
+----------------------------------------
+
+This example shows listing the clusters, find a specific named cluster and deploying a container to it.
+
+.. literalinclude:: /examples/container/working_with_clusters.py
:language: python
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c188d325/docs/container/index.rst
----------------------------------------------------------------------
diff --git a/docs/container/index.rst b/docs/container/index.rst
index 8c6a271..01c9203 100644
--- a/docs/container/index.rst
+++ b/docs/container/index.rst
@@ -6,14 +6,41 @@ Container
Container API is available in Libcloud 0.21.0 and higher.
Container API allows users to install and deploy containers onto container based virtualization platforms. This is designed to target both
-on-premise installations of software like Docker and Rkt as well as interfacing with Cloud Service Providers that offer Container-as-a-Service APIs
+on-premise installations of software like Docker as well as interfacing with Cloud Service Providers that offer Container-as-a-Service APIs.
-Terminology
------------
+
+Drivers
+-------
+Container-as-a-Service providers will implement the `ContainerDriver` class to provide functionality for :
+
+* Listing deployed containers
+* Starting, stopping and restarting containers (where supported)
+* Destroying containers
+* Creating/deploying containers
+* Listing container images
+* Installing container images (pulling an image from a local copy or remote repository)
+
+Driver base API documentation is found here:
+
+* :class:`~libcloud.container.base.ContainerDriver` - A driver for interfacing to a container provider
+
+
+Simple Container Support
+------------------------
* :class:`~libcloud.container.base.ContainerImage` - Represents an image that can be deployed, like an application or an operating system
* :class:`~libcloud.container.base.Container` - Represents a deployed container image running on a container host
+Cluster Suppport
+----------------
+
+Cluster support extends on the basic driver functions, but where drivers implement the class-level attribute `supports_clusters` as True
+clusters may be listed, created and destroyed. When containers are deployed, the target cluster can be specified.
+
+* :class:`~libcloud.container.base.ContainerCluster` - Represents a deployed container image running on a container host
+* :class:`~libcloud.container.base.ClusterLocation` - Represents a location for clusters to be deployed
+
+
Supported Providers
-------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c188d325/docs/examples/container/working_with_clusters.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/working_with_clusters.py b/docs/examples/container/working_with_clusters.py
new file mode 100644
index 0000000..c63ce75
--- /dev/null
+++ b/docs/examples/container/working_with_clusters.py
@@ -0,0 +1,24 @@
+from libcloud.container.base import ContainerImage
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+
+cls = get_driver(Provider.ECS)
+
+conn = cls(access_id='SDHFISJDIFJSIDFJ',
+ secret='p07jkijhHjb6sdf82yjhunvBtzGwt+I6TVkv68o4H',
+ region='ap-southeast-2')
+
+for cluster in conn.list_clusters():
+ print(cluster.name)
+ if cluster.name == 'my-cluster':
+ conn.list_containers(cluster=cluster)
+ container = conn.deploy_container(
+ name='my-simple-app',
+ image=ContainerImage(
+ id=None,
+ name='simple-app',
+ path='simple-app',
+ version=None,
+ driver=conn
+ ),
+ cluster=cluster)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c188d325/libcloud/container/base.py
----------------------------------------------------------------------
diff --git a/libcloud/container/base.py b/libcloud/container/base.py
index 48ee573..7abe664 100644
--- a/libcloud/container/base.py
+++ b/libcloud/container/base.py
@@ -42,7 +42,7 @@ class Container(object):
:type name: ``str``
:param image: The image this container was deployed using.
- :type image: :class:`ContainerImage`
+ :type image: :class:`.ContainerImage`
:param state: The state of the container, e.g. running
:type state: :class:`libcloud.container.types.ContainerState`
@@ -51,7 +51,7 @@ class Container(object):
:type ip_addresses: ``list`` of ``str``
:param driver: ContainerDriver instance.
- :type driver: :class:`ContainerDriver`
+ :type driver: :class:`.ContainerDriver`
:param extra: (optional) Extra attributes (driver specific).
:type extra: ``dict``
@@ -103,7 +103,7 @@ class ContainerImage(object):
:type version: ``str``
:param driver: ContainerDriver instance.
- :type driver: :class:`ContainerDriver`
+ :type driver: :class:`.ContainerDriver`
:param extra: (optional) Extra attributes (driver specific).
:type extra: ``dict``
@@ -141,7 +141,7 @@ class ContainerCluster(object):
:type name: ``str``
:param driver: ContainerDriver instance.
- :type driver: :class:`ContainerDriver`
+ :type driver: :class:`.ContainerDriver`
:param extra: (optional) Extra attributes (driver specific).
:type extra: ``dict``
@@ -166,8 +166,8 @@ class ClusterLocation(object):
"""
A physical location where clusters can be.
- >>> from libcloud.container.drivers.dummy import DummyNodeDriver
- >>> driver = DummyNodeDriver(0)
+ >>> from libcloud.container.drivers.dummy import DummyContainerDriver
+ >>> driver = DummyContainerDriver(0)
>>> location = driver.list_locations()[0]
>>> location.country
'US'
@@ -185,7 +185,7 @@ class ClusterLocation(object):
:type country: ``str``
:param driver: Driver this location belongs to.
- :type driver: :class:`.NodeDriver`
+ :type driver: :class:`.ContainerDriver`
"""
self.id = str(id)
self.name = name
@@ -243,7 +243,7 @@ class ContainerDriver(BaseDriver):
:param path: Path to the container image
:type path: ``str``
- :rtype: :class:`ContainerImage`
+ :rtype: :class:`.ContainerImage`
"""
raise NotImplementedError(
'install_image not implemented for this driver')
@@ -252,7 +252,7 @@ class ContainerDriver(BaseDriver):
"""
List the installed container images
- :rtype: ``list`` of :class:`ContainerImage`
+ :rtype: ``list`` of :class:`.ContainerImage`
"""
raise NotImplementedError(
'list_images not implemented for this driver')
@@ -262,12 +262,12 @@ class ContainerDriver(BaseDriver):
List the deployed container images
:param image: Filter to containers with a certain image
- :type image: :class:`ContainerImage`
+ :type image: :class:`.ContainerImage`
:param cluster: Filter to containers in a cluster
- :type cluster: :class:`ContainerCluster`
+ :type cluster: :class:`.ContainerCluster`
- :rtype: ``list`` of :class:`Container`
+ :rtype: ``list`` of :class:`.Container`
"""
raise NotImplementedError(
'list_containers not implemented for this driver')
@@ -281,10 +281,10 @@ class ContainerDriver(BaseDriver):
:type name: ``str``
:param image: The container image to deploy
- :type image: :class:`ContainerImage`
+ :type image: :class:`.ContainerImage`
:param cluster: The cluster to deploy to, None is default
- :type cluster: :class:`ContainerCluster`
+ :type cluster: :class:`.ContainerCluster`
:param parameters: Container Image parameters
:type parameters: ``str``
@@ -292,7 +292,7 @@ class ContainerDriver(BaseDriver):
:param start: Start the container on deployment
:type start: ``bool``
- :rtype: :class:`Container`
+ :rtype: :class:`.Container`
"""
raise NotImplementedError(
'deploy_container not implemented for this driver')
@@ -304,7 +304,7 @@ class ContainerDriver(BaseDriver):
:param id: The ID of the container to get
:type id: ``str``
- :rtype: :class:`Container`
+ :rtype: :class:`.Container`
"""
raise NotImplementedError(
'get_container not implemented for this driver')
@@ -314,9 +314,9 @@ class ContainerDriver(BaseDriver):
Start a deployed container
:param container: The container to start
- :type container: :class:`Container`
+ :type container: :class:`.Container`
- :rtype: :class:`Container`
+ :rtype: :class:`.Container`
"""
raise NotImplementedError(
'start_container not implemented for this driver')
@@ -326,9 +326,9 @@ class ContainerDriver(BaseDriver):
Stop a deployed container
:param container: The container to stop
- :type container: :class:`Container`
+ :type container: :class:`.Container`
- :rtype: :class:`Container`
+ :rtype: :class:`.Container`
"""
raise NotImplementedError(
'stop_container not implemented for this driver')
@@ -338,9 +338,9 @@ class ContainerDriver(BaseDriver):
Restart a deployed container
:param container: The container to restart
- :type container: :class:`Container`
+ :type container: :class:`.Container`
- :rtype: :class:`Container`
+ :rtype: :class:`.Container`
"""
raise NotImplementedError(
'restart_container not implemented for this driver')
@@ -350,9 +350,9 @@ class ContainerDriver(BaseDriver):
Destroy a deployed container
:param container: The container to destroy
- :type container: :class:`Container`
+ :type container: :class:`.Container`
- :rtype: :class:`Container`
+ :rtype: :class:`.Container`
"""
raise NotImplementedError(
'destroy_container not implemented for this driver')
@@ -361,7 +361,7 @@ class ContainerDriver(BaseDriver):
"""
Get a list of potential locations to deploy clusters into
- :rtype: ``list`` of :class:`ClusterLocation`
+ :rtype: ``list`` of :class:`.ClusterLocation`
"""
raise NotImplementedError(
'list_locations not implemented for this driver')
@@ -374,9 +374,9 @@ class ContainerDriver(BaseDriver):
:type name: ``str``
:param location: The location to create the cluster in
- :type location: :class:`ClusterLocation`
+ :type location: :class:`.ClusterLocation`
- :rtype: :class:`ContainerCluster`
+ :rtype: :class:`.ContainerCluster`
"""
raise NotImplementedError(
'create_cluster not implemented for this driver')
@@ -396,9 +396,9 @@ class ContainerDriver(BaseDriver):
Get a list of potential locations to deploy clusters into
:param location: The location to search in
- :type location: :class:`ClusterLocation`
+ :type location: :class:`.ClusterLocation`
- :rtype: ``list`` of :class:`ContainerCluster`
+ :rtype: ``list`` of :class:`.ContainerCluster`
"""
raise NotImplementedError(
'list_clusters not implemented for this driver')
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c188d325/libcloud/container/drivers/docker.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/docker.py b/libcloud/container/drivers/docker.py
index 981411a..d7c8419 100644
--- a/libcloud/container/drivers/docker.py
+++ b/libcloud/container/drivers/docker.py
@@ -198,7 +198,7 @@ class DockerContainerDriver(ContainerDriver):
:param path: Path to the container image
:type path: ``str``
- :rtype: :class:`ContainerImage`
+ :rtype: :class:`libcloud.container.base.ContainerImage`
"""
payload = {
}
@@ -231,7 +231,7 @@ class DockerContainerDriver(ContainerDriver):
"""
List the installed container images
- :rtype: ``list`` of :class:`ContainerImage`
+ :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
"""
result = self.connection.request('/images/json').object
images = []
@@ -260,12 +260,12 @@ class DockerContainerDriver(ContainerDriver):
List the deployed container images
:param image: Filter to containers with a certain image
- :type image: :class:`ContainerImage`
+ :type image: :class:`libcloud.container.base.ContainerImage`
:param all: Show all container (including stopped ones)
:type all: ``bool``
- :rtype: ``list`` of :class:`Container`
+ :rtype: ``list`` of :class:`libcloud.container.base.Container`
"""
if all:
ex = '?all=1'
@@ -302,7 +302,7 @@ class DockerContainerDriver(ContainerDriver):
:type name: ``str``
:param image: The container image to deploy
- :type image: :class:`ContainerImage`
+ :type image: :class:`libcloud.container.base.ContainerImage`
:param parameters: Container Image parameters
:type parameters: ``str``
@@ -379,7 +379,7 @@ class DockerContainerDriver(ContainerDriver):
:param id: The ID of the container to get
:type id: ``str``
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
result = self.connection.request("/containers/%s/json" %
id).object
@@ -391,10 +391,10 @@ class DockerContainerDriver(ContainerDriver):
Start a container
:param container: The container to be started
- :type container: :class:`.Container`
+ :type container: :class:`libcloud.container.base.Container`
:return: The container refreshed with current data
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
payload = {
'Binds': [],
@@ -416,10 +416,10 @@ class DockerContainerDriver(ContainerDriver):
Stop a container
:param container: The container to be stopped
- :type container: :class:`.Container`
+ :type container: :class:`libcloud.container.base.Container`
:return: The container refreshed with current data
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
result = self.connection.request('/containers/%s/stop' %
(container.id),
@@ -435,10 +435,10 @@ class DockerContainerDriver(ContainerDriver):
Restart a container
:param container: The container to be stopped
- :type container: :class:`.Container`
+ :type container: :class:`libcloud.container.base.Container`
:return: The container refreshed with current data
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
data = json.dumps({'t': 10})
# number of seconds to wait before killing the container
@@ -456,7 +456,7 @@ class DockerContainerDriver(ContainerDriver):
Remove a container
:param container: The container to be destroyed
- :type container: :class:`.Container`
+ :type container: :class:`libcloud.container.base.Container`
:return: True if the destroy was successful, False otherwise.
:rtype: ``bool``
@@ -470,7 +470,7 @@ class DockerContainerDriver(ContainerDriver):
List processes running inside a container
:param container: The container to list processes for.
- :type container: :class:`.Container`
+ :type container: :class:`libcloud.container.base.Container`
:rtype: ``str``
"""
@@ -484,12 +484,12 @@ class DockerContainerDriver(ContainerDriver):
Rename a container
:param container: The container to be renamed
- :type container: :class:`.Container`
+ :type container: :class:`libcloud.container.base.Container`
:param name: The new name
:type name: ``str``
- :rtype: :class:`.Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
result = self.connection.request('/containers/%s/rename?name=%s'
% (container.id, name),
@@ -506,7 +506,7 @@ class DockerContainerDriver(ContainerDriver):
Logs are in different format of those of Version 1.10 and below
:param container: The container to list logs for
- :type container: :class:`.Container`
+ :type container: :class:`libcloud.container.base.Container`
:param stream: Stream the output
:type stream: ``bool``
@@ -542,7 +542,7 @@ class DockerContainerDriver(ContainerDriver):
:param term: The search term
:type term: ``str``
- :rtype: ``list`` of :class:`ContainerImage`
+ :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
"""
term = term.replace(' ', '+')
@@ -573,7 +573,7 @@ class DockerContainerDriver(ContainerDriver):
Remove image from the filesystem
:param image: The image to remove
- :type image: :class:`ContainerImage`
+ :type image: :class:`libcloud.container.base.ContainerImage`
:rtype: ``bool``
"""
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c188d325/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index d390201..9de61df 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -64,9 +64,9 @@ class ElasticContainerDriver(ContainerDriver):
Get a list of potential locations to deploy clusters into
:param location: The location to search in
- :type location: :class:`ClusterLocation`
+ :type location: :class:`libcloud.container.base.ClusterLocation`
- :rtype: ``list`` of :class:`ContainerCluster`
+ :rtype: ``list`` of :class:`libcloud.container.base.ContainerCluster`
"""
listdata = self.connection.request(
ROOT,
@@ -91,9 +91,9 @@ class ElasticContainerDriver(ContainerDriver):
:type name: ``str``
:param location: The location to create the cluster in
- :type location: :class:`ClusterLocation`
+ :type location: :class:`libcloud.container.base.ClusterLocation`
- :rtype: :class:`ContainerCluster`
+ :rtype: :class:`libcloud.container.base.ContainerCluster`
"""
request = {'clusterName': name}
response = self.connection.request(
@@ -125,12 +125,12 @@ class ElasticContainerDriver(ContainerDriver):
List the deployed container images
:param image: Filter to containers with a certain image
- :type image: :class:`ContainerImage`
+ :type image: :class:`libcloud.container.base.ContainerImage`
:param cluster: Filter to containers in a cluster
- :type cluster: :class:`ContainerCluster`
+ :type cluster: :class:`libcloud.container.base.ContainerCluster`
- :rtype: ``list`` of :class:`Container`
+ :rtype: ``list`` of :class:`libcloud.container.base.Container`
"""
request = {'cluster': 'default'}
if cluster is not None:
@@ -158,10 +158,10 @@ class ElasticContainerDriver(ContainerDriver):
:type name: ``str``
:param image: The container image to deploy
- :type image: :class:`ContainerImage`
+ :type image: :class:`libcloud.container.base.ContainerImage`
:param cluster: The cluster to deploy to, None is default
- :type cluster: :class:`ContainerCluster`
+ :type cluster: :class:`libcloud.container.base.ContainerCluster`
:param parameters: Container Image parameters
:type parameters: ``str``
@@ -169,7 +169,7 @@ class ElasticContainerDriver(ContainerDriver):
:param start: Start the container on deployment
:type start: ``bool``
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
data = {}
if ex_container_port is None and ex_host_port is None:
@@ -225,7 +225,7 @@ class ElasticContainerDriver(ContainerDriver):
:param id: The ID of the container to get
:type id: ``str``
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
containers = self.ex_list_containers_for_task([id])
return containers[0]
@@ -235,12 +235,12 @@ class ElasticContainerDriver(ContainerDriver):
Start a deployed task
:param container: The container to start
- :type container: :class:`Container`
+ :type container: :class:`libcloud.container.base.Container`
:param count: Number of containers to start
:type count: ``int``
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
return self.ex_start_task(container.extra['taskDefinitionArn'], count)
@@ -249,9 +249,9 @@ class ElasticContainerDriver(ContainerDriver):
Stop a deployed container
:param container: The container to stop
- :type container: :class:`Container`
+ :type container: :class:`libcloud.container.base.Container`
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
request = {'task': container.extra['taskArn']}
response = self.connection.request(
@@ -271,9 +271,9 @@ class ElasticContainerDriver(ContainerDriver):
Restart a deployed container
:param container: The container to restart
- :type container: :class:`Container`
+ :type container: :class:`libcloud.container.base.Container`
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
self.stop_container(container)
return self.start_container(container)
@@ -283,9 +283,9 @@ class ElasticContainerDriver(ContainerDriver):
Destroy a deployed container
:param container: The container to destroy
- :type container: :class:`Container`
+ :type container: :class:`libcloud.container.base.Container`
- :rtype: :class:`Container`
+ :rtype: :class:`libcloud.container.base.Container`
"""
return self.stop_container(container)
@@ -299,7 +299,7 @@ class ElasticContainerDriver(ContainerDriver):
:param count: The number of containers to start
:type count: ``int``
- :rtype: ``list`` of :class:`Container`
+ :rtype: ``list`` of :class:`libcloud.container.base.Container`
"""
request = None
request = {'count': count,
@@ -322,7 +322,7 @@ class ElasticContainerDriver(ContainerDriver):
:param task_arns: The list of ARNs
:type task_arns: ``list`` of ``str``
- :rtype: ``list`` of :class:`Container`
+ :rtype: ``list`` of :class:`libcloud.container.base.Container`
"""
describe_request = {'tasks': task_arns}
descripe_response = self.connection.request(
@@ -349,7 +349,7 @@ class ElasticContainerDriver(ContainerDriver):
:type name: ``str``
:param cluster: The cluster to run the service on
- :type cluster: :class:`ContainerCluster`
+ :type cluster: :class:`libcloud.container.base.ContainerCluster`
:param task_definition: The task definition name or ARN for the
service
@@ -379,7 +379,7 @@ class ElasticContainerDriver(ContainerDriver):
List the services
:param cluster: The cluster hosting the services
- :type cluster: :class:`ContainerCluster`
+ :type cluster: :class:`libcloud.container.base.ContainerCluster`
:rtype: ``list`` of ``str``
"""
@@ -399,7 +399,7 @@ class ElasticContainerDriver(ContainerDriver):
Get the details of a service
:param cluster: The hosting cluster
- :type cluster: :class:`ContainerCluster`
+ :type cluster: :class:`libcloud.container.base.ContainerCluster`
:param service_arn: The service ARN to describe
:type service_arn: ``str``
@@ -423,7 +423,7 @@ class ElasticContainerDriver(ContainerDriver):
Deletes a service
:param cluster: The target cluster
- :type cluster: :class:`ContainerCluster`
+ :type cluster: :class:`libcloud.container.base.ContainerCluster`
:param service_arn: The service ARN to destroy
:type service_arn: ``str``
[48/50] libcloud git commit: Docs for the kubernetes driver. Fixed
provider factory not referencing the correct class name.
Posted by an...@apache.org.
Docs for the kubernetes driver. Fixed provider factory not referencing the correct class name.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c8c6c2f7
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c8c6c2f7
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c8c6c2f7
Branch: refs/heads/trunk
Commit: c8c6c2f7c8ccef8cbf704fe4595f4ca350ba4fdd
Parents: 0b87588
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Jan 13 16:31:15 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Jan 13 16:31:15 2016 +1100
----------------------------------------------------------------------
.../images/provider_logos/kubernetes.png | Bin 0 -> 6357 bytes
docs/container/_supported_methods.rst | 4 +-
docs/container/_supported_providers.rst | 16 +++----
docs/container/drivers/kubernetes.rst | 42 +++++++++++++++++++
.../examples/container/kubernetes/docker_hub.py | 20 +++++++++
.../container/kubernetes/instantiate_driver.py | 14 +++++++
libcloud/container/drivers/kubernetes.py | 32 +++-----------
libcloud/container/providers.py | 2 +-
8 files changed, 94 insertions(+), 36 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c8c6c2f7/docs/_static/images/provider_logos/kubernetes.png
----------------------------------------------------------------------
diff --git a/docs/_static/images/provider_logos/kubernetes.png b/docs/_static/images/provider_logos/kubernetes.png
new file mode 100644
index 0000000..08da3fd
Binary files /dev/null and b/docs/_static/images/provider_logos/kubernetes.png differ
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c8c6c2f7/docs/container/_supported_methods.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_methods.rst b/docs/container/_supported_methods.rst
index ea52dfc..4361d25 100644
--- a/docs/container/_supported_methods.rst
+++ b/docs/container/_supported_methods.rst
@@ -4,10 +4,12 @@
Provider install image list images deploy container get container start container stop container restart container destroy container list containers list locations create cluster destroy cluster list clusters
=================================== ============= =========== ================ ============= =============== ============== ================= ================= =============== ============== ============== =============== =============
`Docker`_ yes yes yes yes yes yes yes yes yes no no no no
-`Amazon Elastic Container Service`_ no no yes yes yes yes yes yes yes no yes yes yes
+`Amazon Elastic Container Service`_ no yes yes yes yes yes yes yes yes no yes yes yes
`Joyent Triton`_ yes yes yes yes yes yes yes yes yes no no no no
+`Kubernetes`_ no no yes yes no no no yes yes no yes yes yes
=================================== ============= =========== ================ ============= =============== ============== ================= ================= =============== ============== ============== =============== =============
.. _`Docker`: http://docker.io
.. _`Amazon Elastic Container Service`: https://aws.amazon.com/ecs/details/
.. _`Joyent Triton`: http://joyent.com
+.. _`Kubernetes`: http://kubernetes.io
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c8c6c2f7/docs/container/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_providers.rst b/docs/container/_supported_providers.rst
index ebf4d82..3c400c6 100644
--- a/docs/container/_supported_providers.rst
+++ b/docs/container/_supported_providers.rst
@@ -1,13 +1,15 @@
.. NOTE: This file has been generated automatically using generate_provider_feature_matrix_table.py script, don't manually edit it
-=================================== ======================================== ================= ======================================== ===============================
-Provider Documentation Provider constant Module Class Name
-=================================== ======================================== ================= ======================================== ===============================
-`Docker`_ :doc:`Click </container/drivers/docker>` DOCKER :mod:`libcloud.container.drivers.docker` :class:`DockerContainerDriver`
-`Amazon Elastic Container Service`_ :doc:`Click </container/drivers/ecs>` ECS :mod:`libcloud.container.drivers.ecs` :class:`ElasticContainerDriver`
-`Joyent Triton`_ :doc:`Click </container/drivers/joyent>` JOYENT :mod:`libcloud.container.drivers.joyent` :class:`JoyentContainerDriver`
-=================================== ======================================== ================= ======================================== ===============================
+=================================== ============================================ ================= ============================================ ==================================
+Provider Documentation Provider constant Module Class Name
+=================================== ============================================ ================= ============================================ ==================================
+`Docker`_ :doc:`Click </container/drivers/docker>` DOCKER :mod:`libcloud.container.drivers.docker` :class:`DockerContainerDriver`
+`Amazon Elastic Container Service`_ :doc:`Click </container/drivers/ecs>` ECS :mod:`libcloud.container.drivers.ecs` :class:`ElasticContainerDriver`
+`Joyent Triton`_ :doc:`Click </container/drivers/joyent>` JOYENT :mod:`libcloud.container.drivers.joyent` :class:`JoyentContainerDriver`
+`Kubernetes`_ :doc:`Click </container/drivers/kubernetes>` KUBERNETES :mod:`libcloud.container.drivers.kubernetes` :class:`KubernetesContainerDriver`
+=================================== ============================================ ================= ============================================ ==================================
.. _`Docker`: http://docker.io
.. _`Amazon Elastic Container Service`: https://aws.amazon.com/ecs/details/
.. _`Joyent Triton`: http://joyent.com
+.. _`Kubernetes`: http://kubernetes.io
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c8c6c2f7/docs/container/drivers/kubernetes.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/kubernetes.rst b/docs/container/drivers/kubernetes.rst
new file mode 100644
index 0000000..e0253bd
--- /dev/null
+++ b/docs/container/drivers/kubernetes.rst
@@ -0,0 +1,42 @@
+Kubernetes Documentation
+========================
+
+Kubernetes is an open source orchestration system for Docker containers. It handles scheduling onto nodes in a compute cluster and actively manages workloads to ensure that their state matches the users declared intentions. Using the concepts of "labels" and "pods",
+it groups the containers which make up an application into logical units for easy management and discovery.
+
+.. figure:: /_static/images/provider_logos/kubernetes.png
+ :align: center
+ :width: 300
+ :target: http://kubernetes.io/
+
+
+Authentication
+--------------
+
+Authentication currently supported with the following methods:
+
+* Basic HTTP Authentication - http://kubernetes.io/v1.1/docs/admin/authentication.html
+* No authentication (testing only)
+
+Instantiating the driver
+------------------------
+
+.. literalinclude:: /examples/container/kubernetes/instantiate_driver.py
+ :language: python
+
+Deploying a container from Docker Hub
+-------------------------------------
+
+Docker Hub Client :class:`~libcloud.container.utils.docker.HubClient` is a shared utility class for interfacing to the public Docker Hub Service.
+
+You can use this class for fetching images to deploy to services like ECS
+
+.. literalinclude:: /examples/container/kubernetes/docker_hub.py
+ :language: python
+
+API Docs
+--------
+
+.. autoclass:: libcloud.container.drivers.kubernetes.KubernetesContainerDriver
+ :members:
+ :inherited-members:
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c8c6c2f7/docs/examples/container/kubernetes/docker_hub.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/kubernetes/docker_hub.py b/docs/examples/container/kubernetes/docker_hub.py
new file mode 100644
index 0000000..dce1bef
--- /dev/null
+++ b/docs/examples/container/kubernetes/docker_hub.py
@@ -0,0 +1,20 @@
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+from libcloud.container.utils.docker import HubClient
+
+cls = get_driver(Provider.KUBERNETES)
+
+conn = cls(key='my_username',
+ secret='THIS_IS)+_MY_SECRET_KEY+I6TVkv68o4H',
+ host='126.32.21.4')
+hub = HubClient()
+
+image = hub.get_image('ubuntu', 'latest')
+
+for cluster in conn.list_clusters():
+ print(cluster.name)
+ if cluster.name == 'default':
+ container = conn.deploy_container(
+ cluster=cluster,
+ name='my-simple-app',
+ image=image)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c8c6c2f7/docs/examples/container/kubernetes/instantiate_driver.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/kubernetes/instantiate_driver.py b/docs/examples/container/kubernetes/instantiate_driver.py
new file mode 100644
index 0000000..95fe997
--- /dev/null
+++ b/docs/examples/container/kubernetes/instantiate_driver.py
@@ -0,0 +1,14 @@
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+
+cls = get_driver(Provider.KUBERNETES)
+
+conn = cls(key='my_username',
+ secret='THIS_IS)+_MY_SECRET_KEY+I6TVkv68o4H',
+ host='126.32.21.4')
+
+for container in conn.list_containers():
+ print(container.name)
+
+for cluster in conn.list_clusters():
+ print(cluster.name)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c8c6c2f7/libcloud/container/drivers/kubernetes.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/kubernetes.py b/libcloud/container/drivers/kubernetes.py
index 13f2a51..ed02112 100644
--- a/libcloud/container/drivers/kubernetes.py
+++ b/libcloud/container/drivers/kubernetes.py
@@ -103,7 +103,7 @@ class KubernetesContainerDriver(ContainerDriver):
supports_clusters = True
def __init__(self, key=None, secret=None, secure=False, host='localhost',
- port=4243, key_file=None, cert_file=None):
+ port=4243):
"""
:param key: API key or username to used (required)
:type key: ``str``
@@ -121,20 +121,12 @@ class KubernetesContainerDriver(ContainerDriver):
:param port: Override port used for connections.
:type port: ``int``
- :param key_file: Path to private key for TLS connection (optional)
- :type key_file: ``str``
-
- :param cert_file: Path to public key for TLS connection (optional)
- :type cert_file: ``str``
-
:return: ``None``
"""
super(KubernetesContainerDriver, self).__init__(key=key, secret=secret,
secure=secure,
host=host,
- port=port,
- key_file=key_file,
- cert_file=cert_file)
+ port=port)
if host.startswith('https://'):
secure = True
@@ -144,23 +136,9 @@ class KubernetesContainerDriver(ContainerDriver):
if host.startswith(prefix):
host = host.strip(prefix)
- if key_file or cert_file:
- # docker tls authentication-
- # https://docs.docker.com/articles/https/
- # We pass two files, a key_file with the
- # private key and cert_file with the certificate
- # libcloud will handle them through LibcloudHTTPSConnection
- if not (key_file and cert_file):
- raise Exception(
- 'Needs both private key file and '
- 'certificate file for tls authentication')
- self.connection.key_file = key_file
- self.connection.cert_file = cert_file
- self.connection.secure = True
- else:
- self.connection.secure = secure
- self.connection.key = key
- self.connection.secret = secret
+ self.connection.secure = secure
+ self.connection.key = key
+ self.connection.secret = secret
self.connection.host = host
self.connection.port = port
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c8c6c2f7/libcloud/container/providers.py
----------------------------------------------------------------------
diff --git a/libcloud/container/providers.py b/libcloud/container/providers.py
index c39566f..47897ed 100644
--- a/libcloud/container/providers.py
+++ b/libcloud/container/providers.py
@@ -27,7 +27,7 @@ DRIVERS = {
Provider.ECS:
('libcloud.container.drivers.ecs', 'ElasticContainerDriver'),
Provider.KUBERNETES:
- ('libcloud.container.drivers.kubernetes', 'KubenetesContainerDriver'),
+ ('libcloud.container.drivers.kubernetes', 'KubernetesContainerDriver'),
}
[45/50] libcloud git commit: updated build configuration with
recommendation from travis support team
Posted by an...@apache.org.
updated build configuration with recommendation from travis support team
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/f3943eab
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/f3943eab
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/f3943eab
Branch: refs/heads/trunk
Commit: f3943eabf7259c8658291c240490bfeb4ef89f83
Parents: 8537731
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Jan 13 07:41:46 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Jan 13 07:41:46 2016 +1100
----------------------------------------------------------------------
.travis.yml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f3943eab/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index df48842..af0690d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,7 @@ python:
- "pypy"
os:
- linux
+ - osx
env:
matrix:
@@ -17,10 +18,12 @@ matrix:
allow_failures:
- os: osx
include:
- - python: 2.7
+ - sudo: required
+ python: 2.7
env: ENV=lint
before_script: TOX_ENV=lint
- - python: 2.7
+ - sudo: required
+ python: 2.7
env: ENV=docs
before_script: TOX_ENV=docs-travis
before_install:
[04/50] libcloud git commit: Updated example doc with correct syntax.
Formatted bash prompt for joyent driver.
Posted by an...@apache.org.
Updated example doc with correct syntax. Formatted bash prompt for joyent driver.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/2450063a
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/2450063a
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/2450063a
Branch: refs/heads/trunk
Commit: 2450063adbdfabc1aab5a48e3cc1a28a764d41dc
Parents: e7665f9
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Dec 23 15:46:20 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Dec 23 15:46:20 2015 +1100
----------------------------------------------------------------------
docs/container/drivers/joyent.rst | 6 +++---
docs/examples/container/install_and_deploy.py | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/2450063a/docs/container/drivers/joyent.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/joyent.rst b/docs/container/drivers/joyent.rst
index c2a2233..f6feb5f 100644
--- a/docs/container/drivers/joyent.rst
+++ b/docs/container/drivers/joyent.rst
@@ -1,7 +1,7 @@
Joyent Triton Container Driver Documentation
==================================
-`Joyent Triton`_ is a Docker hosting service, provided by service provider `Joyent`.
+`Joyent Triton`_ is a Docker hosting service, provided by service provider `Joyent`_.
Docker-native tools and elastic hosts make deploying on Triton as easy as running Docker on your laptop.
There is no special software to install or configure.
Mix Docker containers with container-native Linux to extend the benefits of containerization to legacy applications and stateful services.
@@ -18,11 +18,11 @@ Download the script:
curl -O https://raw.githubusercontent.com/joyent/sdc-docker/master/tools/sdc-docker-setup.sh
-Now execute the script, substituting the correct values:
+Now execute the script, substituting the correct values::
bash sdc-docker-setup.sh <CLOUDAPI_URL> <ACCOUNT_USERNAME> ~/.ssh/<PRIVATE_KEY_FILE>
-This should output something similar to the following:
+This should output something similar to the following::
Setting up Docker client for SDC using:
CloudAPI: https://us-east-1.api.joyent.com
http://git-wip-us.apache.org/repos/asf/libcloud/blob/2450063a/docs/examples/container/install_and_deploy.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/install_and_deploy.py b/docs/examples/container/install_and_deploy.py
index d11bdfe..4e25c54 100644
--- a/docs/examples/container/install_and_deploy.py
+++ b/docs/examples/container/install_and_deploy.py
@@ -9,4 +9,4 @@ driver = Cls(*CREDS)
image = driver.install_image('tomcat:8.0')
container = driver.deploy_container('tomcat', image)
-container.restart
+container.restart()
[35/50] libcloud git commit: less-convincing looking secrets
Posted by an...@apache.org.
less-convincing looking secrets
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/3280fc33
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/3280fc33
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/3280fc33
Branch: refs/heads/trunk
Commit: 3280fc33e1f9e6699b2ce4a74b12106ad64f06f9
Parents: 5e6b38f
Author: anthony-shaw <an...@gmail.com>
Authored: Thu Jan 7 20:57:50 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Thu Jan 7 20:57:50 2016 +1100
----------------------------------------------------------------------
docs/examples/container/ecs/deploy_container.py | 5 ++---
docs/examples/container/ecs/instantiate_driver.py | 4 ++--
docs/examples/container/working_with_clusters.py | 2 +-
3 files changed, 5 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/3280fc33/docs/examples/container/ecs/deploy_container.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/ecs/deploy_container.py b/docs/examples/container/ecs/deploy_container.py
index 2dd6662..6d005a4 100644
--- a/docs/examples/container/ecs/deploy_container.py
+++ b/docs/examples/container/ecs/deploy_container.py
@@ -4,11 +4,10 @@ from libcloud.container.providers import get_driver
cls = get_driver(Provider.ECS)
-conn = cls(access_id='AKIAI7OR4GWEEPRIFBBA',
- secret='xiKazLqsAgMQ4c3rC2RSXHBJrJTqNZmjYcXHsYXO',
+conn = cls(access_id='SDHFISJDIFJSIDFJ',
+ secret='THIS_IS)+_MY_SECRET_KEY+I6TVkv68o4H',
region='ap-southeast-2')
-
for cluster in conn.list_clusters():
print(cluster.name)
if cluster.name == 'default':
http://git-wip-us.apache.org/repos/asf/libcloud/blob/3280fc33/docs/examples/container/ecs/instantiate_driver.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/ecs/instantiate_driver.py b/docs/examples/container/ecs/instantiate_driver.py
index d053c79..4085fef 100644
--- a/docs/examples/container/ecs/instantiate_driver.py
+++ b/docs/examples/container/ecs/instantiate_driver.py
@@ -3,8 +3,8 @@ from libcloud.container.providers import get_driver
cls = get_driver(Provider.ECS)
-conn = cls(access_id='AKIAI7OR4GWEEPRIFBBA',
- secret='xiKazLqsAgMQ4c3rC2RSXHBJrJTqNZmjYcXHsYXO',
+conn = cls(access_id='SDHFISJDIFJSIDFJ',
+ secret='THIS_IS)+_MY_SECRET_KEY+I6TVkv68o4H',
region='ap-southeast-2')
for container in conn.list_containers():
http://git-wip-us.apache.org/repos/asf/libcloud/blob/3280fc33/docs/examples/container/working_with_clusters.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/working_with_clusters.py b/docs/examples/container/working_with_clusters.py
index c63ce75..e4d519e 100644
--- a/docs/examples/container/working_with_clusters.py
+++ b/docs/examples/container/working_with_clusters.py
@@ -5,7 +5,7 @@ from libcloud.container.providers import get_driver
cls = get_driver(Provider.ECS)
conn = cls(access_id='SDHFISJDIFJSIDFJ',
- secret='p07jkijhHjb6sdf82yjhunvBtzGwt+I6TVkv68o4H',
+ secret='THIS_IS)+_MY_SECRET_KEY+I6TVkv68o4H',
region='ap-southeast-2')
for cluster in conn.list_clusters():
[14/50] libcloud git commit: Corrected indentation
Posted by an...@apache.org.
Corrected indentation
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c82230f5
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c82230f5
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c82230f5
Branch: refs/heads/trunk
Commit: c82230f51ce3fd5494ebe5dc8d73b33151af201d
Parents: d51dd3d
Author: anthony-shaw <an...@gmail.com>
Authored: Tue Dec 29 08:42:38 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Tue Dec 29 08:42:38 2015 +1100
----------------------------------------------------------------------
libcloud/container/drivers/ecs.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c82230f5/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index 12b544f..e3a356f 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -281,7 +281,7 @@ class ElasticContainerDriver(ContainerDriver):
path=None,
version=None,
driver=self.connection.driver
- ),
+ ),
ip_addresses=None,
state=self.status_map.get(data['lastStatus'], None),
extra={
[27/50] libcloud git commit: You can't have 2 drivers with the same
name. That's really a bug but I'm not here to fix that now!
Posted by an...@apache.org.
You can't have 2 drivers with the same name. That's really a bug but I'm not here to fix that now!
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/8c01c62b
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/8c01c62b
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/8c01c62b
Branch: refs/heads/trunk
Commit: 8c01c62b25312bbecf10ce87ce03109c1980f5b4
Parents: c5edd3a
Author: anthony-shaw <an...@gmail.com>
Authored: Sun Jan 3 21:44:30 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sun Jan 3 21:44:30 2016 +1100
----------------------------------------------------------------------
docs/container/_supported_methods.rst | 6 +++---
docs/container/_supported_providers.rst | 4 ++--
libcloud/container/drivers/joyent.py | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8c01c62b/docs/container/_supported_methods.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_methods.rst b/docs/container/_supported_methods.rst
index a62a8e5..ea52dfc 100644
--- a/docs/container/_supported_methods.rst
+++ b/docs/container/_supported_methods.rst
@@ -4,10 +4,10 @@
Provider install image list images deploy container get container start container stop container restart container destroy container list containers list locations create cluster destroy cluster list clusters
=================================== ============= =========== ================ ============= =============== ============== ================= ================= =============== ============== ============== =============== =============
`Docker`_ yes yes yes yes yes yes yes yes yes no no no no
-`Amazon Elastic Container Service`_ yes yes yes yes yes yes yes yes yes no yes yes yes
-`Joyent`_ yes yes yes yes yes yes yes yes yes no no no no
+`Amazon Elastic Container Service`_ no no yes yes yes yes yes yes yes no yes yes yes
+`Joyent Triton`_ yes yes yes yes yes yes yes yes yes no no no no
=================================== ============= =========== ================ ============= =============== ============== ================= ================= =============== ============== ============== =============== =============
.. _`Docker`: http://docker.io
.. _`Amazon Elastic Container Service`: https://aws.amazon.com/ecs/details/
-.. _`Joyent`: http://joyent.com
+.. _`Joyent Triton`: http://joyent.com
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8c01c62b/docs/container/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_providers.rst b/docs/container/_supported_providers.rst
index 114af32..ebf4d82 100644
--- a/docs/container/_supported_providers.rst
+++ b/docs/container/_supported_providers.rst
@@ -5,9 +5,9 @@ Provider Documentation Pro
=================================== ======================================== ================= ======================================== ===============================
`Docker`_ :doc:`Click </container/drivers/docker>` DOCKER :mod:`libcloud.container.drivers.docker` :class:`DockerContainerDriver`
`Amazon Elastic Container Service`_ :doc:`Click </container/drivers/ecs>` ECS :mod:`libcloud.container.drivers.ecs` :class:`ElasticContainerDriver`
-`Joyent`_ :doc:`Click </container/drivers/joyent>` JOYENT :mod:`libcloud.container.drivers.joyent` :class:`JoyentContainerDriver`
+`Joyent Triton`_ :doc:`Click </container/drivers/joyent>` JOYENT :mod:`libcloud.container.drivers.joyent` :class:`JoyentContainerDriver`
=================================== ======================================== ================= ======================================== ===============================
.. _`Docker`: http://docker.io
.. _`Amazon Elastic Container Service`: https://aws.amazon.com/ecs/details/
-.. _`Joyent`: http://joyent.com
+.. _`Joyent Triton`: http://joyent.com
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8c01c62b/libcloud/container/drivers/joyent.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/joyent.py b/libcloud/container/drivers/joyent.py
index e380f6a..39df019 100644
--- a/libcloud/container/drivers/joyent.py
+++ b/libcloud/container/drivers/joyent.py
@@ -31,7 +31,7 @@ class JoyentContainerDriver(DockerContainerDriver):
"""
type = Provider.JOYENT
- name = 'Joyent'
+ name = 'Joyent Triton'
website = 'http://joyent.com'
connectionCls = DockerConnection
supports_clusters = False
[03/50] libcloud git commit: Added Joyent help links
Posted by an...@apache.org.
Added Joyent help links
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/e7665f9e
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/e7665f9e
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/e7665f9e
Branch: refs/heads/trunk
Commit: e7665f9eb8bd56bbc7ac7305f711eebfc3ed56d5
Parents: e61bad5
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Dec 23 15:37:51 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Dec 23 15:37:51 2015 +1100
----------------------------------------------------------------------
docs/container/_supported_methods.rst | 2 ++
docs/container/_supported_providers.rst | 2 ++
2 files changed, 4 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e7665f9e/docs/container/_supported_methods.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_methods.rst b/docs/container/_supported_methods.rst
index 8621352..daceb3e 100644
--- a/docs/container/_supported_methods.rst
+++ b/docs/container/_supported_methods.rst
@@ -4,6 +4,8 @@
Provider install image list images deploy container get container start container stop container restart container delete container
========= ============= =========== ================ ============= =============== ============== ================= ================
`Docker`_ yes yes yes yes yes yes yes yes
+`Joyent`_ yes yes yes yes yes yes yes yes
========= ============= =========== ================ ============= =============== ============== ================= ================
.. _`Docker`: http://docker.io
+.. _`Joyent`: http://joyent.com
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e7665f9e/docs/container/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_providers.rst b/docs/container/_supported_providers.rst
index f7743b1..26f4755 100644
--- a/docs/container/_supported_providers.rst
+++ b/docs/container/_supported_providers.rst
@@ -4,6 +4,8 @@
Provider Documentation Provider constant Module Class Name
========= ======================================== ================= ======================================== ==============================
`Docker`_ :doc:`Click </container/drivers/docker>` DOCKER :mod:`libcloud.container.drivers.docker` :class:`DockerContainerDriver`
+`Joyent`_ :doc:`Click </container/drivers/joyent>` JOYENT :mod:`libcloud.container.drivers.joyent` :class:`JoyentContainerDriver`
========= ======================================== ================= ======================================== ==============================
.. _`Docker`: http://docker.io
+.. _`Joyent`: http://joyent.com
[24/50] libcloud git commit: Merge branch 'trunk' into
LIBCLOUD-781_containers
Posted by an...@apache.org.
Merge branch 'trunk' into LIBCLOUD-781_containers
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c247ea85
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c247ea85
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c247ea85
Branch: refs/heads/trunk
Commit: c247ea85e504f606b4830f07da1b40921e5e4daf
Parents: 83c06fe 9ddaa91
Author: anthony-shaw <an...@gmail.com>
Authored: Sun Jan 3 21:14:56 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sun Jan 3 21:14:56 2016 +1100
----------------------------------------------------------------------
CHANGES.rst | 26 +++++++-------
docs/compute/drivers/auroracompute.rst | 2 +-
docs/compute/drivers/cloudstack.rst | 6 ++--
docs/compute/drivers/dimensiondata.rst | 2 +-
docs/compute/drivers/onapp.rst | 2 +-
docs/compute/drivers/openstack.rst | 2 +-
docs/compute/drivers/packet.rst | 2 +-
docs/conf.py | 35 +++++++++++++++++-
docs/development.rst | 2 +-
docs/dns/drivers/digital_ocean.rst | 2 +-
docs/dns/drivers/dnsimple.rst | 6 ++--
docs/dns/drivers/durabledns.rst | 4 +--
docs/dns/drivers/godaddy.rst | 8 ++---
docs/dns/drivers/liquidweb.rst | 4 +--
docs/dns/drivers/pointdns.rst | 4 +--
docs/dns/drivers/vultr.rst | 4 +--
docs/dns/drivers/worldwidedns.rst | 4 +--
docs/dns/drivers/zonomi.rst | 4 +--
.../examples/http_proxy/constructor_argument.py | 8 +++++
docs/loadbalancer/drivers/dimensiondata.rst | 2 +-
docs/loadbalancer/drivers/elb.rst | 14 ++++----
docs/loadbalancer/drivers/gce.rst | 6 ++--
docs/loadbalancer/drivers/index.rst | 4 +--
docs/storage/drivers/auroraobjects.rst | 6 ++--
docs/storage/drivers/s3.rst | 2 +-
docs/upgrade_notes.rst | 2 +-
libcloud/common/abiquo.py | 2 +-
libcloud/common/base.py | 2 +-
libcloud/common/dimensiondata.py | 24 +++++++------
libcloud/common/exceptions.py | 2 +-
libcloud/common/google.py | 11 +++---
libcloud/common/onapp.py | 5 +--
libcloud/common/openstack.py | 38 +++++++++++---------
libcloud/common/openstack_identity.py | 10 +++---
libcloud/compute/deployment.py | 2 +-
libcloud/compute/drivers/abiquo.py | 4 +--
libcloud/compute/drivers/azure.py | 36 ++++++++++---------
libcloud/compute/drivers/cloudsigma.py | 8 ++---
libcloud/compute/drivers/cloudstack.py | 17 ++++-----
libcloud/compute/drivers/dimensiondata.py | 10 ++++--
libcloud/compute/drivers/ec2.py | 6 ++--
libcloud/compute/drivers/ecp.py | 4 +--
libcloud/compute/drivers/gce.py | 24 ++++++-------
libcloud/compute/drivers/hostvirtual.py | 9 +++--
libcloud/compute/drivers/ibm_sce.py | 3 +-
libcloud/compute/drivers/linode.py | 24 ++++++-------
libcloud/compute/drivers/nephoscale.py | 14 ++++----
libcloud/compute/drivers/profitbricks.py | 4 +--
libcloud/compute/drivers/runabove.py | 4 +--
libcloud/compute/drivers/vsphere.py | 2 +-
libcloud/dns/drivers/cloudflare.py | 2 +-
libcloud/dns/drivers/pointdns.py | 2 +-
libcloud/dns/types.py | 2 --
libcloud/loadbalancer/base.py | 2 +-
libcloud/storage/base.py | 4 +--
libcloud/storage/drivers/google_storage.py | 18 +++++++---
libcloud/storage/drivers/s3.py | 2 +-
libcloud/test/compute/test_elasticstack.py | 10 ------
libcloud/utils/files.py | 2 +-
libcloud/utils/networking.py | 2 +-
tox.ini | 2 +-
61 files changed, 267 insertions(+), 209 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c247ea85/CHANGES.rst
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c247ea85/libcloud/common/base.py
----------------------------------------------------------------------
[37/50] libcloud git commit: Added basic ECR support
Posted by an...@apache.org.
Added basic ECR support
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/6e4df6d3
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/6e4df6d3
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/6e4df6d3
Branch: refs/heads/trunk
Commit: 6e4df6d37b30652569e10b8361582bfabc96a15f
Parents: 5aa34e1
Author: anthony-shaw <an...@gmail.com>
Authored: Sat Jan 9 21:58:19 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sat Jan 9 21:58:19 2016 +1100
----------------------------------------------------------------------
libcloud/container/drivers/ecs.py | 87 +++++++++++++++++++++++++++++---
libcloud/test/container/test_ecs.py | 3 ++
2 files changed, 83 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/6e4df6d3/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index 9de61df..7f6faf3 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -28,23 +28,36 @@ __all__ = [
]
-VERSION = '2014-11-13'
-HOST = 'ecs.%s.amazonaws.com'
+ECS_VERSION = '2014-11-13'
+ECR_VERSION = '2015-09-21'
+ECS_HOST = 'ecs.%s.amazonaws.com'
+ECR_HOST = 'ecr.%s.amazonaws.com'
ROOT = '/'
-TARGET_BASE = 'AmazonEC2ContainerServiceV%s' % (VERSION.replace('-', ''))
+ECS_TARGET_BASE = 'AmazonEC2ContainerServiceV%s' % \
+ (ECS_VERSION.replace('-', ''))
+ECR_TARGET_BASE = 'AmazonEC2ContainerRegistry_V%s' % \
+ (ECR_VERSION.replace('-', ''))
class ECSJsonConnection(SignedAWSConnection):
- version = VERSION
- host = HOST
+ version = ECS_VERSION
+ host = ECS_HOST
responseCls = AWSJsonResponse
service_name = 'ecs'
+class ECRJsonConnection(SignedAWSConnection):
+ version = ECR_VERSION
+ host = ECR_HOST
+ responseCls = AWSJsonResponse
+ service_name = 'ecr'
+
+
class ElasticContainerDriver(ContainerDriver):
name = 'Amazon Elastic Container Service'
website = 'https://aws.amazon.com/ecs/details/'
connectionCls = ECSJsonConnection
+ ecrConnectionClass = ECRJsonConnection
supports_clusters = False
status_map = {
'RUNNING': ContainerState.RUNNING
@@ -54,11 +67,39 @@ class ElasticContainerDriver(ContainerDriver):
super(ElasticContainerDriver, self).__init__(access_id, secret)
self.region = region
self.region_name = region
- self.connection.host = HOST % (region)
+ self.connection.host = ECS_HOST % (region)
+
+ # Setup another connection class for ECR
+ conn_kwargs = self._ex_connection_class_kwargs()
+ self.ecr_connection = self.ecrConnectionClass(
+ access_id, secret, **conn_kwargs)
+ self.ecr_connection.host = ECR_HOST % (region)
+ self.ecr_connection.driver = self
+ self.ecr_connection.connect()
def _ex_connection_class_kwargs(self):
return {'signature_version': '4'}
+ def list_images(self, ex_repository_name=None):
+ """
+ List the images in an ECR repository
+
+ :param ex_repository_name: The name of the repository to check
+ defaults to the default repository.
+ :type ex_repository_name: ``str``
+
+ :return: a list of images
+ :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
+ """
+ request = {'repositoryName': 'default'}
+ list_response = self.ecr_connection.request(
+ ROOT,
+ method='POST',
+ data=json.dumps(request),
+ headers=self._get_ecr_headers('ListImages')
+ ).object
+ return self._to_images(list_response)
+
def list_clusters(self):
"""
Get a list of potential locations to deploy clusters into
@@ -143,6 +184,8 @@ class ElasticContainerDriver(ContainerDriver):
data=json.dumps(request),
headers=self._get_headers('ListTasks')
).object
+ if len(list_response['taskArns']) == 0:
+ return []
containers = self.ex_list_containers_for_task(
list_response['taskArns'])
return containers
@@ -441,10 +484,25 @@ class ElasticContainerDriver(ContainerDriver):
def _get_headers(self, action):
return {'x-amz-target': '%s.%s' %
- (TARGET_BASE, action),
+ (ECS_TARGET_BASE, action),
'Content-Type': 'application/x-amz-json-1.1'
}
+ def _get_ecr_headers(self, action):
+ return {'x-amz-target': '%s.%s' %
+ (ECR_TARGET_BASE, action),
+ 'Content-Type': 'application/x-amz-json-1.1'
+ }
+
+ def ex_docker_hub_image(self, name):
+ return ContainerImage(
+ id=None,
+ name=name,
+ path=None,
+ version=None,
+ driver=self.connection.driver
+ )
+
def _to_clusters(self, data):
clusters = []
for cluster in data['clusters']:
@@ -483,3 +541,18 @@ class ElasticContainerDriver(ContainerDriver):
},
driver=self.connection.driver
)
+
+ def _to_images(self, data):
+ images = []
+ for image in data['images']:
+ images.append(self._to_image(image))
+ return images
+
+ def _to_image(self, data):
+ return ContainerImage(
+ id=None,
+ name=data['name'],
+ path=None,
+ version=None,
+ driver=self.connection.driver
+ )
http://git-wip-us.apache.org/repos/asf/libcloud/blob/6e4df6d3/libcloud/test/container/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_ecs.py b/libcloud/test/container/test_ecs.py
index e2fdb3f..2a3a2c2 100644
--- a/libcloud/test/container/test_ecs.py
+++ b/libcloud/test/container/test_ecs.py
@@ -33,6 +33,9 @@ class ElasticContainerDriverTestCase(unittest.TestCase):
ECSMockHttp, ECSMockHttp)
ECSMockHttp.type = None
ECSMockHttp.use_param = 'a'
+ ElasticContainerDriver.ecrConnectionClass.conn_classes = (
+ ECSMockHttp, ECSMockHttp)
+
self.driver = ElasticContainerDriver(*CONTAINER_PARAMS_ECS)
def test_list_clusters(self):
[10/50] libcloud git commit: Merge branch 'trunk' into
LIBCLOUD-781_containers
Posted by an...@apache.org.
Merge branch 'trunk' into LIBCLOUD-781_containers
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/edb1265c
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/edb1265c
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/edb1265c
Branch: refs/heads/trunk
Commit: edb1265c4a048f730f95920dbea7afbb87b3be0a
Parents: c8024ad adfaacf
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Dec 28 21:11:24 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Dec 28 21:11:24 2015 +1100
----------------------------------------------------------------------
.travis.yml | 6 ++++++
libcloud/test/compute/test_ec2.py | 8 ++++----
2 files changed, 10 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
[46/50] libcloud git commit: Start of a kubernetes server running
against an unauthenticated host, also with support for basic http auth
Posted by an...@apache.org.
Start of a kubernetes server running against an unauthenticated host, also with support for basic http auth
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/936fe421
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/936fe421
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/936fe421
Branch: refs/heads/trunk
Commit: 936fe42152217e0a35eb3cf52ffe155b518cd8c4
Parents: f3943ea
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Jan 13 14:46:08 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Jan 13 14:46:08 2016 +1100
----------------------------------------------------------------------
libcloud/container/base.py | 12 +
libcloud/container/drivers/kubernetes.py | 310 +++++++++++++++++++
libcloud/container/providers.py | 2 +
libcloud/container/types.py | 1 +
.../fixtures/kubernetes/_api_v1_namespaces.json | 44 +++
.../kubernetes/_api_v1_namespaces_default.json | 19 ++
.../_api_v1_namespaces_default_DELETE.json | 20 ++
.../kubernetes/_api_v1_namespaces_test.json | 19 ++
.../fixtures/kubernetes/_api_v1_nodes.json | 81 +++++
.../kubernetes/_api_v1_nodes_127_0_0_1.json | 73 +++++
libcloud/test/container/test_kubernetes.py | 125 ++++++++
libcloud/test/secrets.py-dist | 1 +
12 files changed, 707 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/container/base.py
----------------------------------------------------------------------
diff --git a/libcloud/container/base.py b/libcloud/container/base.py
index a03ea91..ea41e50 100644
--- a/libcloud/container/base.py
+++ b/libcloud/container/base.py
@@ -402,3 +402,15 @@ class ContainerDriver(BaseDriver):
"""
raise NotImplementedError(
'list_clusters not implemented for this driver')
+
+ def get_cluster(self, id):
+ """
+ Get a cluster by ID
+
+ :param id: The ID of the cluster to get
+ :type id: ``str``
+
+ :rtype: :class:`.ContainerCluster`
+ """
+ raise NotImplementedError(
+ 'list_clusters not implemented for this driver')
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/container/drivers/kubernetes.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/kubernetes.py b/libcloud/container/drivers/kubernetes.py
new file mode 100644
index 0000000..a947fd2
--- /dev/null
+++ b/libcloud/container/drivers/kubernetes.py
@@ -0,0 +1,310 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import base64
+import datetime
+
+try:
+ import simplejson as json
+except:
+ import json
+
+from libcloud.utils.py3 import httplib
+from libcloud.utils.py3 import b
+
+from libcloud.common.base import JsonResponse, ConnectionUserAndKey
+from libcloud.common.types import InvalidCredsError
+
+from libcloud.container.base import (Container, ContainerDriver,
+ ContainerCluster)
+
+from libcloud.container.providers import Provider
+from libcloud.container.types import ContainerState
+
+
+VALID_RESPONSE_CODES = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
+ httplib.NO_CONTENT]
+
+ROOT_URL = '/api/'
+
+
+class KubernetesResponse(JsonResponse):
+
+ valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
+ httplib.NO_CONTENT]
+
+ def parse_error(self):
+ if self.status == 401:
+ raise InvalidCredsError('Invalid credentials')
+ return self.body
+
+ def success(self):
+ return self.status in self.valid_response_codes
+
+
+class KubernetesException(Exception):
+
+ def __init__(self, code, message):
+ self.code = code
+ self.message = message
+ self.args = (code, message)
+
+ def __str__(self):
+ return "%s %s" % (self.code, self.message)
+
+ def __repr__(self):
+ return "KubernetesException %s %s" % (self.code, self.message)
+
+
+class KubernetesConnection(ConnectionUserAndKey):
+ responseCls = KubernetesResponse
+ timeout = 60
+
+ def add_default_headers(self, headers):
+ """
+ Add parameters that are necessary for every request
+ If user and password are specified, include a base http auth
+ header
+ """
+ headers['Content-Type'] = 'application/json'
+ if self.key and self.secret:
+ user_b64 = base64.b64encode(b('%s:%s' % (self.key, self.secret)))
+ headers['Authorization'] = 'Basic %s' % (user_b64.decode('utf-8'))
+ return headers
+
+
+class KubernetesContainerDriver(ContainerDriver):
+ type = Provider.KUBERNETES
+ name = 'Kubernetes'
+ website = 'http://kubernetes.io'
+ connectionCls = KubernetesConnection
+ supports_clusters = True
+
+ def __init__(self, key=None, secret=None, secure=False, host='localhost',
+ port=4243, key_file=None, cert_file=None):
+ """
+ :param key: API key or username to used (required)
+ :type key: ``str``
+
+ :param secret: Secret password to be used (required)
+ :type secret: ``str``
+
+ :param secure: Whether to use HTTPS or HTTP. Note: Some providers
+ only support HTTPS, and it is on by default.
+ :type secure: ``bool``
+
+ :param host: Override hostname used for connections.
+ :type host: ``str``
+
+ :param port: Override port used for connections.
+ :type port: ``int``
+
+ :param key_file: Path to private key for TLS connection (optional)
+ :type key_file: ``str``
+
+ :param cert_file: Path to public key for TLS connection (optional)
+ :type cert_file: ``str``
+
+ :return: ``None``
+ """
+ super(KubernetesContainerDriver, self).__init__(key=key, secret=secret,
+ secure=secure,
+ host=host,
+ port=port,
+ key_file=key_file,
+ cert_file=cert_file)
+ if host.startswith('https://'):
+ secure = True
+
+ # strip the prefix
+ prefixes = ['http://', 'https://']
+ for prefix in prefixes:
+ if host.startswith(prefix):
+ host = host.strip(prefix)
+
+ if key_file or cert_file:
+ # docker tls authentication-
+ # https://docs.docker.com/articles/https/
+ # We pass two files, a key_file with the
+ # private key and cert_file with the certificate
+ # libcloud will handle them through LibcloudHTTPSConnection
+ if not (key_file and cert_file):
+ raise Exception(
+ 'Needs both private key file and '
+ 'certificate file for tls authentication')
+ self.connection.key_file = key_file
+ self.connection.cert_file = cert_file
+ self.connection.secure = True
+ else:
+ self.connection.secure = secure
+ self.connection.key = key
+ self.connection.secret = secret
+
+ self.connection.host = host
+ self.connection.port = port
+
+ def list_containers(self, image=None, all=True):
+ """
+ List the deployed container images
+
+ :param image: Filter to containers with a certain image
+ :type image: :class:`libcloud.container.base.ContainerImage`
+
+ :param all: Show all container (including stopped ones)
+ :type all: ``bool``
+
+ :rtype: ``list`` of :class:`libcloud.container.base.Container`
+ """
+ try:
+ result = self.connection.request(
+ ROOT_URL + "v1/nodes/").object
+ except Exception as exc:
+ if hasattr(exc, 'errno') and exc.errno == 111:
+ raise KubernetesException(
+ exc.errno,
+ 'Make sure kube host is accessible'
+ 'and the API port is correct')
+ raise
+
+ containers = [self._to_container(value) for value in result['items']]
+ return containers
+
+ def get_container(self, id):
+ """
+ Get a container by ID
+
+ :param id: The ID of the container to get
+ :type id: ``str``
+
+ :rtype: :class:`libcloud.container.base.Container`
+ """
+ result = self.connection.request(ROOT_URL + "v1/nodes/%s" %
+ id).object
+
+ return self._to_container(result)
+
+ def list_clusters(self):
+ """
+ Get a list of namespaces that pods can be deployed into
+
+ :param location: The location to search in
+ :type location: :class:`libcloud.container.base.ClusterLocation`
+
+ :rtype: ``list`` of :class:`libcloud.container.base.ContainerCluster`
+ """
+ try:
+ result = self.connection.request(
+ ROOT_URL + "v1/namespaces/").object
+ except Exception as exc:
+ if hasattr(exc, 'errno') and exc.errno == 111:
+ raise KubernetesException(
+ exc.errno,
+ 'Make sure kube host is accessible'
+ 'and the API port is correct')
+ raise
+
+ clusters = [self._to_cluster(value) for value in result['items']]
+ return clusters
+
+ def get_cluster(self, id):
+ """
+ Get a cluster by ID
+
+ :param id: The ID of the cluster to get
+ :type id: ``str``
+
+ :rtype: :class:`libcloud.container.base.ContainerCluster`
+ """
+ result = self.connection.request(ROOT_URL + "v1/namespaces/%s" %
+ id).object
+
+ return self._to_cluster(result)
+
+ def destroy_cluster(self, cluster):
+ """
+ Delete a cluster (namespace)
+
+ :return: ``True`` if the destroy was successful, otherwise ``False``.
+ :rtype: ``bool``
+ """
+ self.connection.request(ROOT_URL + "v1/namespaces/%s" %
+ cluster.id, method='DELETE').object
+ return True
+
+ def create_cluster(self, name, location=None):
+ """
+ Create a container cluster (a namespace)
+
+ :param name: The name of the cluster
+ :type name: ``str``
+
+ :param location: The location to create the cluster in
+ :type location: :class:`.ClusterLocation`
+
+ :rtype: :class:`.ContainerCluster`
+ """
+ request = {
+ 'metadata': {
+ 'name': name
+ }
+ }
+ result = self.connection.request(ROOT_URL + "v1/namespaces",
+ method='POST',
+ data=json.dumps(request)).object
+ return self._to_cluster(result)
+
+ def _to_container(self, data):
+ """
+ Convert container in Container instances
+ """
+ metadata = data['metadata']
+ return Container(
+ id=data['spec']['externalID'],
+ name=metadata['name'],
+ image=None,
+ ip_addresses="ips",
+ state=ContainerState.RUNNING,
+ driver=self.connection.driver,
+ extra=None)
+
+ def _to_cluster(self, data):
+ """
+ Convert namespace to a cluster
+ """
+ metadata = data['metadata']
+ status = data['status']
+ return ContainerCluster(
+ id=metadata['name'],
+ name=metadata['name'],
+ driver=self.connection.driver,
+ extra={'phase': status['phase']})
+
+ def _get_api_version(self):
+ """
+ Get the docker API version information
+ """
+ result = self.connection.request('/version').object
+ api_version = result.get('ApiVersion')
+
+ return api_version
+
+
+def ts_to_str(timestamp):
+ """
+ Return a timestamp as a nicely formated datetime string.
+ """
+ date = datetime.datetime.fromtimestamp(timestamp)
+ date_string = date.strftime("%d/%m/%Y %H:%M %Z")
+ return date_string
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/container/providers.py
----------------------------------------------------------------------
diff --git a/libcloud/container/providers.py b/libcloud/container/providers.py
index 458eae8..c39566f 100644
--- a/libcloud/container/providers.py
+++ b/libcloud/container/providers.py
@@ -26,6 +26,8 @@ DRIVERS = {
('libcloud.container.drivers.joyent', 'JoyentContainerDriver'),
Provider.ECS:
('libcloud.container.drivers.ecs', 'ElasticContainerDriver'),
+ Provider.KUBERNETES:
+ ('libcloud.container.drivers.kubernetes', 'KubenetesContainerDriver'),
}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/container/types.py
----------------------------------------------------------------------
diff --git a/libcloud/container/types.py b/libcloud/container/types.py
index 6236468..263d9d4 100644
--- a/libcloud/container/types.py
+++ b/libcloud/container/types.py
@@ -44,6 +44,7 @@ class Provider(object):
DOCKER = 'docker'
JOYENT = 'joyent'
ECS = 'ecs'
+ KUBERNETES = 'kubernetes'
class ContainerState(Type):
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces.json b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces.json
new file mode 100644
index 0000000..38e8bec
--- /dev/null
+++ b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces.json
@@ -0,0 +1,44 @@
+{
+ "kind": "NamespaceList",
+ "apiVersion": "v1",
+ "metadata": {
+ "selfLink": "/api/v1/namespaces",
+ "resourceVersion": "443"
+ },
+ "items": [
+ {
+ "metadata": {
+ "name": "default",
+ "selfLink": "/api/v1/namespaces/default",
+ "uid": "43e99cf9-b99d-11e5-8d53-0050568157ec",
+ "resourceVersion": "6",
+ "creationTimestamp": "2016-01-13T02:28:00Z"
+ },
+ "spec": {
+ "finalizers": [
+ "kubernetes"
+ ]
+ },
+ "status": {
+ "phase": "Active"
+ }
+ },
+ {
+ "metadata": {
+ "name": "test",
+ "selfLink": "/api/v1/namespaces/test",
+ "uid": "7cb89199-b9a6-11e5-8d53-0050568157ec",
+ "resourceVersion": "419",
+ "creationTimestamp": "2016-01-13T03:34:01Z"
+ },
+ "spec": {
+ "finalizers": [
+ "kubernetes"
+ ]
+ },
+ "status": {
+ "phase": "Active"
+ }
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default.json b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default.json
new file mode 100644
index 0000000..d59d2c1
--- /dev/null
+++ b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default.json
@@ -0,0 +1,19 @@
+{
+ "kind": "Namespace",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "default",
+ "selfLink": "/api/v1/namespaces/default",
+ "uid": "43e99cf9-b99d-11e5-8d53-0050568157ec",
+ "resourceVersion": "6",
+ "creationTimestamp": "2016-01-13T02:28:00Z"
+ },
+ "spec": {
+ "finalizers": [
+ "kubernetes"
+ ]
+ },
+ "status": {
+ "phase": "Active"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default_DELETE.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default_DELETE.json b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default_DELETE.json
new file mode 100644
index 0000000..8b47e26
--- /dev/null
+++ b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_default_DELETE.json
@@ -0,0 +1,20 @@
+{
+ "kind": "Namespace",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "test",
+ "selfLink": "/api/v1/namespaces/test",
+ "uid": "7cb89199-b9a6-11e5-8d53-0050568157ec",
+ "resourceVersion": "447",
+ "creationTimestamp": "2016-01-13T03:34:01Z",
+ "deletionTimestamp": "2016-01-13T03:38:05Z"
+ },
+ "spec": {
+ "finalizers": [
+ "kubernetes"
+ ]
+ },
+ "status": {
+ "phase": "Terminating"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_test.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_test.json b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_test.json
new file mode 100644
index 0000000..fddefa0
--- /dev/null
+++ b/libcloud/test/container/fixtures/kubernetes/_api_v1_namespaces_test.json
@@ -0,0 +1,19 @@
+{
+ "kind": "Namespace",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "test",
+ "selfLink": "/api/v1/namespaces/test",
+ "uid": "7cb89199-b9a6-11e5-8d53-0050568157ec",
+ "resourceVersion": "419",
+ "creationTimestamp": "2016-01-13T03:34:01Z"
+ },
+ "spec": {
+ "finalizers": [
+ "kubernetes"
+ ]
+ },
+ "status": {
+ "phase": "Active"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/test/container/fixtures/kubernetes/_api_v1_nodes.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/kubernetes/_api_v1_nodes.json b/libcloud/test/container/fixtures/kubernetes/_api_v1_nodes.json
new file mode 100644
index 0000000..2664914
--- /dev/null
+++ b/libcloud/test/container/fixtures/kubernetes/_api_v1_nodes.json
@@ -0,0 +1,81 @@
+{
+ "kind": "NodeList",
+ "apiVersion": "v1",
+ "metadata": {
+ "selfLink": "/api/v1/nodes",
+ "resourceVersion": "24"
+ },
+ "items": [
+ {
+ "metadata": {
+ "name": "127.0.0.1",
+ "selfLink": "/api/v1/nodes/127.0.0.1",
+ "uid": "45949cbb-b99d-11e5-8d53-0050568157ec",
+ "resourceVersion": "24",
+ "creationTimestamp": "2016-01-13T02:28:03Z",
+ "labels": {
+ "kubernetes.io/hostname": "127.0.0.1"
+ }
+ },
+ "spec": {
+ "externalID": "127.0.0.1"
+ },
+ "status": {
+ "capacity": {
+ "cpu": "2",
+ "memory": "4048236Ki",
+ "pods": "40"
+ },
+ "allocatable": {
+ "cpu": "2",
+ "memory": "4048236Ki",
+ "pods": "40"
+ },
+ "conditions": [
+ {
+ "type": "OutOfDisk",
+ "status": "False",
+ "lastHeartbeatTime": "2016-01-13T02:28:53Z",
+ "lastTransitionTime": "2016-01-13T02:28:03Z",
+ "reason": "KubeletHasSufficientDisk",
+ "message": "kubelet has sufficient disk space available"
+ },
+ {
+ "type": "Ready",
+ "status": "True",
+ "lastHeartbeatTime": "2016-01-13T02:28:53Z",
+ "lastTransitionTime": "2016-01-13T02:28:03Z",
+ "reason": "KubeletReady",
+ "message": "kubelet is posting ready status"
+ }
+ ],
+ "addresses": [
+ {
+ "type": "LegacyHostIP",
+ "address": "127.0.0.1"
+ },
+ {
+ "type": "InternalIP",
+ "address": "127.0.0.1"
+ }
+ ],
+ "daemonEndpoints": {
+ "kubeletEndpoint": {
+ "Port": 10250
+ }
+ },
+ "nodeInfo": {
+ "machineID": "1d9faaba9168d4b4a3416e99000002a2",
+ "systemUUID": "42015AA3-9AF2-D089-9105-63CEF89EFE35",
+ "bootID": "c31fdd67-f995-4be5-942d-10df26b40501",
+ "kernelVersion": "3.13.0-46-generic",
+ "osImage": "Ubuntu 14.04.2 LTS",
+ "containerRuntimeVersion": "docker://1.9.1",
+ "kubeletVersion": "v1.2.0-alpha.5.848+3f2e99b7e7d6d8",
+ "kubeProxyVersion": "v1.2.0-alpha.5.848+3f2e99b7e7d6d8"
+ },
+ "images": null
+ }
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/test/container/fixtures/kubernetes/_api_v1_nodes_127_0_0_1.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/kubernetes/_api_v1_nodes_127_0_0_1.json b/libcloud/test/container/fixtures/kubernetes/_api_v1_nodes_127_0_0_1.json
new file mode 100644
index 0000000..1077b73
--- /dev/null
+++ b/libcloud/test/container/fixtures/kubernetes/_api_v1_nodes_127_0_0_1.json
@@ -0,0 +1,73 @@
+{
+ "kind": "Node",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "127.0.0.1",
+ "selfLink": "/api/v1/nodes/127.0.0.1",
+ "uid": "45949cbb-b99d-11e5-8d53-0050568157ec",
+ "resourceVersion": "184",
+ "creationTimestamp": "2016-01-13T02:28:03Z",
+ "labels": {
+ "kubernetes.io/hostname": "127.0.0.1"
+ }
+ },
+ "spec": {
+ "externalID": "127.0.0.1"
+ },
+ "status": {
+ "capacity": {
+ "cpu": "2",
+ "memory": "4048236Ki",
+ "pods": "40"
+ },
+ "allocatable": {
+ "cpu": "2",
+ "memory": "4048236Ki",
+ "pods": "40"
+ },
+ "conditions": [
+ {
+ "type": "OutOfDisk",
+ "status": "False",
+ "lastHeartbeatTime": "2016-01-13T02:55:34Z",
+ "lastTransitionTime": "2016-01-13T02:28:03Z",
+ "reason": "KubeletHasSufficientDisk",
+ "message": "kubelet has sufficient disk space available"
+ },
+ {
+ "type": "Ready",
+ "status": "True",
+ "lastHeartbeatTime": "2016-01-13T02:55:34Z",
+ "lastTransitionTime": "2016-01-13T02:28:03Z",
+ "reason": "KubeletReady",
+ "message": "kubelet is posting ready status"
+ }
+ ],
+ "addresses": [
+ {
+ "type": "LegacyHostIP",
+ "address": "127.0.0.1"
+ },
+ {
+ "type": "InternalIP",
+ "address": "127.0.0.1"
+ }
+ ],
+ "daemonEndpoints": {
+ "kubeletEndpoint": {
+ "Port": 10250
+ }
+ },
+ "nodeInfo": {
+ "machineID": "1d9faaba9168d4b4a3416e99000002a2",
+ "systemUUID": "42015AA3-9AF2-D089-9105-63CEF89EFE35",
+ "bootID": "c31fdd67-f995-4be5-942d-10df26b40501",
+ "kernelVersion": "3.13.0-46-generic",
+ "osImage": "Ubuntu 14.04.2 LTS",
+ "containerRuntimeVersion": "docker://1.9.1",
+ "kubeletVersion": "v1.2.0-alpha.5.848+3f2e99b7e7d6d8",
+ "kubeProxyVersion": "v1.2.0-alpha.5.848+3f2e99b7e7d6d8"
+ },
+ "images": null
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/test/container/test_kubernetes.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_kubernetes.py b/libcloud/test/container/test_kubernetes.py
new file mode 100644
index 0000000..2e8da4e
--- /dev/null
+++ b/libcloud/test/container/test_kubernetes.py
@@ -0,0 +1,125 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+
+from libcloud.test import unittest
+
+from libcloud.container.drivers.kubernetes import KubernetesContainerDriver
+
+from libcloud.utils.py3 import httplib
+from libcloud.test.secrets import CONTAINER_PARAMS_KUBERNETES
+from libcloud.test.file_fixtures import ContainerFileFixtures
+from libcloud.test import MockHttp
+
+
+class KubernetesContainerDriverTestCase(unittest.TestCase):
+
+ def setUp(self):
+ KubernetesContainerDriver.connectionCls.conn_classes = (
+ KubernetesMockHttp, KubernetesMockHttp)
+ KubernetesMockHttp.type = None
+ KubernetesMockHttp.use_param = 'a'
+ self.driver = KubernetesContainerDriver(*CONTAINER_PARAMS_KUBERNETES)
+
+ def test_list_containers(self):
+ containers = self.driver.list_containers()
+ self.assertEqual(len(containers), 1)
+ self.assertEqual(containers[0].id,
+ '127.0.0.1')
+ self.assertEqual(containers[0].name, '127.0.0.1')
+
+ def test_get_container(self):
+ container = self.driver.get_container('127.0.0.1')
+ self.assertEqual(container.id,
+ '127.0.0.1')
+ self.assertEqual(container.name, '127.0.0.1')
+
+ def test_list_clusters(self):
+ clusters = self.driver.list_clusters()
+ self.assertEqual(len(clusters), 2)
+ self.assertEqual(clusters[0].id,
+ 'default')
+ self.assertEqual(clusters[0].name, 'default')
+
+ def test_get_cluster(self):
+ cluster = self.driver.get_cluster('default')
+ self.assertEqual(cluster.id,
+ 'default')
+ self.assertEqual(cluster.name, 'default')
+
+ def test_create_cluster(self):
+ cluster = self.driver.create_cluster('test')
+ self.assertEqual(cluster.id,
+ 'test')
+ self.assertEqual(cluster.name, 'test')
+
+ def test_destroy_cluster(self):
+ cluster = self.driver.get_cluster('default')
+ result = self.driver.destroy_cluster(cluster)
+ self.assertTrue(result)
+
+
+class KubernetesMockHttp(MockHttp):
+ fixtures = ContainerFileFixtures('kubernetes')
+
+ def _version(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('version.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_v1_nodes(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('_api_v1_nodes.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_v1_nodes_127_0_0_1(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('_api_v1_nodes_127_0_0_1.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_v1_namespaces(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('_api_v1_namespaces.json')
+ elif method == 'POST':
+ body = self.fixtures.load('_api_v1_namespaces_test.json')
+ elif method == 'DELETE':
+ body = self.fixtures.load('_api_v1_namespaces_DELETE.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_v1_namespaces_default(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('_api_v1_namespaces_default.json')
+ elif method == 'DELETE':
+ body = self.fixtures.load('_api_v1_namespaces_default_DELETE.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
http://git-wip-us.apache.org/repos/asf/libcloud/blob/936fe421/libcloud/test/secrets.py-dist
----------------------------------------------------------------------
diff --git a/libcloud/test/secrets.py-dist b/libcloud/test/secrets.py-dist
index 230cef0..216a7d5 100644
--- a/libcloud/test/secrets.py-dist
+++ b/libcloud/test/secrets.py-dist
@@ -85,3 +85,4 @@ DNS_PARAMS_AURORADNS = ('apikey', 'secretkey')
# Container
CONTAINER_PARAMS_DOCKER = ('user', 'password')
CONTAINER_PARAMS_ECS = ('user', 'password', 'region')
+CONTAINER_PARAMS_KUBERNETES = ('user', 'password')
[32/50] libcloud git commit: ask travis to install graphviz
Posted by an...@apache.org.
ask travis to install graphviz
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/88390aed
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/88390aed
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/88390aed
Branch: refs/heads/trunk
Commit: 88390aedf91e4abb54b004747250a526dd20b33d
Parents: 0aec851
Author: anthony-shaw <an...@gmail.com>
Authored: Thu Jan 7 20:37:18 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Thu Jan 7 20:37:18 2016 +1100
----------------------------------------------------------------------
.travis.yml | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/88390aed/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index 719063d..8ace6bd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,6 +25,8 @@ matrix:
- python: 2.7
env: ENV=docs
before_script: TOX_ENV=docs-travis
+ before_install:
+ - sudo apt-get -qq install graphviz > /dev/null
install:
- TOX_ENV=py$TRAVIS_PYTHON_VERSION
[40/50] libcloud git commit: refactor the docker hub client to
inherit from a registry api client,
updated docs with examples and renamed the package to utils
Posted by an...@apache.org.
refactor the docker hub client to inherit from a registry api client, updated docs with examples and renamed the package to utils
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/d29629de
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/d29629de
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/d29629de
Branch: refs/heads/trunk
Commit: d29629de79d790995d4435e1b5081bb31f3b7b82
Parents: 104cdb1
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Jan 11 12:59:51 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Jan 11 12:59:51 2016 +1100
----------------------------------------------------------------------
docs/container/drivers/ecs.rst | 12 +-
docs/container/examples.rst | 10 +
docs/container/utilities.rst | 2 +-
docs/examples/container/docker_hub.py | 20 +
libcloud/container/util/__init__.py | 0
libcloud/container/util/docker.py | 137 ---
libcloud/container/utils/__init__.py | 0
libcloud/container/utils/docker.py | 164 ++++
.../fixtures/docker/list_tags_ubuntu.json | 354 -------
.../v2_repositories_library_ubuntu.json | 15 +
.../v2_repositories_library_ubuntu_tags.json | 975 +++++++++++++++++++
...repositories_library_ubuntu_tags_latest.json | 11 +
libcloud/test/container/test_docker_utils.py | 86 ++
libcloud/test/container/test_ecs.py | 2 +-
14 files changed, 1294 insertions(+), 494 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/docs/container/drivers/ecs.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/ecs.rst b/docs/container/drivers/ecs.rst
index 20ab400..fbde93f 100644
--- a/docs/container/drivers/ecs.rst
+++ b/docs/container/drivers/ecs.rst
@@ -23,7 +23,17 @@ Deploying a container
.. literalinclude:: /examples/container/ecs/deploy_container.py
:language: python
-
+
+Deploying a container from Docker Hub
+-------------------------------------
+
+Docker Hub Client :class:`~libcloud.container.utils.docker.HubClient` is a shared utility class for interfacing to the public Docker Hub Service.
+
+You can use this class for fetching images to deploy to services like ECS
+
+.. literalinclude:: /examples/container/docker_hub.py
+ :language: python
+
API Docs
--------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/docs/container/examples.rst
----------------------------------------------------------------------
diff --git a/docs/container/examples.rst b/docs/container/examples.rst
index a4e4316..f35662c 100644
--- a/docs/container/examples.rst
+++ b/docs/container/examples.rst
@@ -20,4 +20,14 @@ Working with cluster supported providers
This example shows listing the clusters, find a specific named cluster and deploying a container to it.
.. literalinclude:: /examples/container/working_with_clusters.py
+ :language: python
+
+Working with docker hub
+-----------------------
+
+Docker Hub Client :class:`~libcloud.container.utils.docker.HubClient` is a shared utility class for interfacing to the public Docker Hub Service.
+
+You can use this class for fetching images to deploy to services like ECS
+
+.. literalinclude:: /examples/container/docker_hub.py
:language: python
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/docs/container/utilities.rst
----------------------------------------------------------------------
diff --git a/docs/container/utilities.rst b/docs/container/utilities.rst
index 48aafc2..c2b17e9 100644
--- a/docs/container/utilities.rst
+++ b/docs/container/utilities.rst
@@ -3,5 +3,5 @@
Container Utility API
=====================
-.. autoclass:: libcloud.container.util.HubClient
+.. autoclass:: libcloud.container.utils.docker.HubClient
:members:
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/docs/examples/container/docker_hub.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/docker_hub.py b/docs/examples/container/docker_hub.py
new file mode 100644
index 0000000..dd9d1a6
--- /dev/null
+++ b/docs/examples/container/docker_hub.py
@@ -0,0 +1,20 @@
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+from libcloud.container.utils.docker import HubClient
+
+cls = get_driver(Provider.ECS)
+
+conn = cls(access_id='SDHFISJDIFJSIDFJ',
+ secret='THIS_IS)+_MY_SECRET_KEY+I6TVkv68o4H',
+ region='ap-southeast-2')
+hub = HubClient()
+
+image = hub.get_image('ubuntu', 'latest')
+
+for cluster in conn.list_clusters():
+ print(cluster.name)
+ if cluster.name == 'default':
+ container = conn.deploy_container(
+ cluster=cluster,
+ name='my-simple-app',
+ image=image)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/container/util/__init__.py
----------------------------------------------------------------------
diff --git a/libcloud/container/util/__init__.py b/libcloud/container/util/__init__.py
deleted file mode 100644
index e69de29..0000000
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/container/util/docker.py
----------------------------------------------------------------------
diff --git a/libcloud/container/util/docker.py b/libcloud/container/util/docker.py
deleted file mode 100644
index 3edfec8..0000000
--- a/libcloud/container/util/docker.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from __future__ import with_statement
-
-from requests.auth import HTTPBasicAuth
-import requests
-
-from libcloud.container.base import ContainerImage
-
-__all__ = [
- 'HubClient'
-]
-
-
-class HubClient(object):
- """
- A client for the Docker Hub API
-
- The hub is based on the v1 registry API
- """
- host = 'registry.hub.docker.com'
- base_url = 'https://%s/' % (host)
-
- def __init__(self, username=None, password=None):
- """
- Construct a Docker hub client
-
- :param username: (optional) Your Hub account username
- :type username: ``str``
-
- :param password: (optional) Your hub account password
- :type password: ``str``
- """
- if username is not None:
- self.auth = HTTPBasicAuth(username, password)
- else:
- self.auth = None
-
- def list_tags(self, repository_name, namespace='library', max_count=100):
- """
- List the tags (versions) in a repository
-
- :param repository_name: The name of the repository e.g. 'ubuntu'
- :type repository_name: ``str``
-
- :param namespace: (optional) The docker namespace
- :type namespace: ``str``
-
- :param max_count: The maximum number of records to return
- :type max_count: ``int``
-
- :return: A list of tags
- :rtype: ``list`` of ``object``
- """
- path = 'v2/repositories/%s/%s/tags/?page=1&page_size=%s' \
- % (namespace, repository_name, max_count)
- response = requests.get(self.base_url + path, auth=self.auth)
- return response.json().results
-
- def list_image_ids(self, repository_name, namespace='library'):
- """
- List the image IDs (versions) in a repository
-
- :param repository_name: The name of the repository e.g. 'ubuntu'
- :type repository_name: ``str``
-
- :param namespace: (optional) The docker namespace
- :type namespace: ``str``
-
- :return: A list of ids
- :rtype: ``list`` of ``object``
- """
- path = 'v1/repositories/%s/%s/images' % (namespace, repository_name)
- response = requests.get(self.base_url + path, auth=self.auth)
- return response.json()
-
- def get_repository(self, repository_name, namespace='library'):
- """
- Get the information about a specific repository
-
- :param repository_name: The name of the repository e.g. 'ubuntu'
- :type repository_name: ``str``
-
- :param namespace: (optional) The docker namespace
- :type namespace: ``str``
-
- :return: The details of the repository
- :rtype: ``object``
- """
- path = 'v2/repositories/%s/%s' % (namespace, repository_name)
- response = requests.get(self.base_url + path, auth=self.auth)
- return response.json()
-
- def get_image(self, repository_name, tag='latest', namespace='library'):
- """
- Get an image from a repository with a specific tag
-
- :param repository_name: The name of the repository, e.g. ubuntu
- :type repository_name: ``str``
-
- :param tag: (optional) The image tag (defaults to latest)
- :type tag: ``str``
-
- :param namespace: (optional) The docker namespace
- :type namespace: ``str``
-
- :return: A container image
- :rtype: :class:`libcloud.container.base.ContainerImage`
- """
- path = 'v2/repositories/%s/%s/tags/%s' \
- % (namespace, repository_name, tag)
- response = requests.get(self.base_url + path, auth=self.auth)
- obj = response.json()
- path = '%s/%s:%s' % (self.host, repository_name, tag)
- return ContainerImage(
- id=obj['id'],
- path=path,
- name=path,
- version=tag,
- extra={
- 'full_size': obj['full_size']
- },
- driver=None
- )
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/container/utils/__init__.py
----------------------------------------------------------------------
diff --git a/libcloud/container/utils/__init__.py b/libcloud/container/utils/__init__.py
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/container/utils/docker.py
----------------------------------------------------------------------
diff --git a/libcloud/container/utils/docker.py b/libcloud/container/utils/docker.py
new file mode 100644
index 0000000..9e9703c
--- /dev/null
+++ b/libcloud/container/utils/docker.py
@@ -0,0 +1,164 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import with_statement
+
+from base64 import b64encode
+
+from libcloud.common.base import Connection, JsonResponse
+from libcloud.container.base import ContainerImage
+
+__all__ = [
+ 'RegistryClient',
+ 'HubClient'
+]
+
+
+class DockerHubConnection(Connection):
+ responseCls = JsonResponse
+
+ def __init__(self, host, username=None, password=None, **kwargs):
+ super(DockerHubConnection, self).__init__(host=host, **kwargs)
+ self.username = username
+ self.password = password
+
+ def add_default_headers(self, headers):
+ if self.username is not None:
+ authstr = 'Basic ' + str(
+ b64encode(
+ ('%s:%s' % (self.username,
+ self.password))
+ .encode('latin1'))
+ .strip()
+ )
+ headers['Authorization'] = authstr
+ return headers
+
+
+class RegistryClient(object):
+ """
+ A client for the Docker v2 registry API
+ """
+ connectionCls = DockerHubConnection
+
+ def __init__(self, host, username=None, password=None, **kwargs):
+ """
+ Construct a Docker hub client
+
+ :param username: (optional) Your Hub account username
+ :type username: ``str``
+
+ :param password: (optional) Your hub account password
+ :type password: ``str``
+ """
+ self.connection = DockerHubConnection(host, username, password, **kwargs)
+
+ def list_images(self, repository_name, namespace='library', max_count=100):
+ """
+ List the tags (versions) in a repository
+
+ :param repository_name: The name of the repository e.g. 'ubuntu'
+ :type repository_name: ``str``
+
+ :param namespace: (optional) The docker namespace
+ :type namespace: ``str``
+
+ :param max_count: The maximum number of records to return
+ :type max_count: ``int``
+
+ :return: A list of images
+ :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
+ """
+ path = 'v2/repositories/%s/%s/tags/?page=1&page_size=%s' \
+ % (namespace, repository_name, max_count)
+ response = self.connection.request(path)
+ images = []
+ for image in response.object['results']:
+ images.append(self._to_image(repository_name, image))
+ return images
+
+ def get_repository(self, repository_name, namespace='library'):
+ """
+ Get the information about a specific repository
+
+ :param repository_name: The name of the repository e.g. 'ubuntu'
+ :type repository_name: ``str``
+
+ :param namespace: (optional) The docker namespace
+ :type namespace: ``str``
+
+ :return: The details of the repository
+ :rtype: ``object``
+ """
+ path = 'v2/repositories/%s/%s' % (namespace, repository_name)
+ response = self.connection.request(path)
+ return response.object
+
+ def get_image(self, repository_name, tag='latest', namespace='library'):
+ """
+ Get an image from a repository with a specific tag
+
+ :param repository_name: The name of the repository, e.g. ubuntu
+ :type repository_name: ``str``
+
+ :param tag: (optional) The image tag (defaults to latest)
+ :type tag: ``str``
+
+ :param namespace: (optional) The docker namespace
+ :type namespace: ``str``
+
+ :return: A container image
+ :rtype: :class:`libcloud.container.base.ContainerImage`
+ """
+ path = 'v2/repositories/%s/%s/tags/%s' \
+ % (namespace, repository_name, tag)
+ response = self.connection.request(path)
+ return self._to_image(repository_name, response.object)
+
+ def _to_image(self, repository_name, obj):
+ path = '%s/%s:%s' % (self.connection.host,
+ repository_name,
+ obj['name'])
+ return ContainerImage(
+ id=obj['id'],
+ path=path,
+ name=path,
+ version=obj['name'],
+ extra={
+ 'full_size': obj['full_size']
+ },
+ driver=None
+ )
+
+
+class HubClient(RegistryClient):
+ """
+ A client for the Docker Hub API
+
+ The hub is based on the v2 registry API
+ """
+ host = 'registry.hub.docker.com'
+
+ def __init__(self, username=None, password=None, **kwargs):
+ """
+ Construct a Docker hub client
+
+ :param username: (optional) Your Hub account username
+ :type username: ``str``
+
+ :param password: (optional) Your hub account password
+ :type password: ``str``
+ """
+ self.connection = DockerHubConnection(self.host, username, password, **kwargs)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/test/container/fixtures/docker/list_tags_ubuntu.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/docker/list_tags_ubuntu.json b/libcloud/test/container/fixtures/docker/list_tags_ubuntu.json
deleted file mode 100644
index 2786d5c..0000000
--- a/libcloud/test/container/fixtures/docker/list_tags_ubuntu.json
+++ /dev/null
@@ -1,354 +0,0 @@
-[
- {
- "layer": "af88597e",
- "name": "latest"
- },
- {
- "layer": "3db9c44f",
- "name": "10.04"
- },
- {
- "layer": "bad926a6",
- "name": "12.04"
- },
- {
- "layer": "bad926a6",
- "name": "12.04.5"
- },
- {
- "layer": "c5881f11",
- "name": "12.10"
- },
- {
- "layer": "463ff6be",
- "name": "13.04"
- },
- {
- "layer": "195eb90b",
- "name": "13.10"
- },
- {
- "layer": "af88597e",
- "name": "14.04"
- },
- {
- "layer": "5ba9dab4",
- "name": "14.04.1"
- },
- {
- "layer": "63e3c102",
- "name": "14.04.2"
- },
- {
- "layer": "af88597e",
- "name": "14.04.3"
- },
- {
- "layer": "dce38fb5",
- "name": "14.10"
- },
- {
- "layer": "3f0d2d4f",
- "name": "15.04"
- },
- {
- "layer": "3e0c71ad",
- "name": "15.10"
- },
- {
- "layer": "db856b41",
- "name": "16.04"
- },
- {
- "layer": "3db9c44f",
- "name": "lucid"
- },
- {
- "layer": "bad926a6",
- "name": "precise"
- },
- {
- "layer": "1f80e9ca",
- "name": "precise-20150212"
- },
- {
- "layer": "5898adab",
- "name": "precise-20150228.11"
- },
- {
- "layer": "9610cfc6",
- "name": "precise-20150320"
- },
- {
- "layer": "ac6b0eaa",
- "name": "precise-20150427"
- },
- {
- "layer": "5c97af89",
- "name": "precise-20150528"
- },
- {
- "layer": "78cef618",
- "name": "precise-20150612"
- },
- {
- "layer": "6d021018",
- "name": "precise-20150626"
- },
- {
- "layer": "d0e008c6",
- "name": "precise-20150729"
- },
- {
- "layer": "57bca513",
- "name": "precise-20150813"
- },
- {
- "layer": "61994089",
- "name": "precise-20150924"
- },
- {
- "layer": "0ac5b09d",
- "name": "precise-20151020"
- },
- {
- "layer": "04c3793b",
- "name": "precise-20151028"
- },
- {
- "layer": "bad926a6",
- "name": "precise-20151208"
- },
- {
- "layer": "c5881f11",
- "name": "quantal"
- },
- {
- "layer": "463ff6be",
- "name": "raring"
- },
- {
- "layer": "195eb90b",
- "name": "saucy"
- },
- {
- "layer": "af88597e",
- "name": "trusty"
- },
- {
- "layer": "2d24f826",
- "name": "trusty-20150218.1"
- },
- {
- "layer": "2103b00b",
- "name": "trusty-20150228.11"
- },
- {
- "layer": "b7cf8f0d",
- "name": "trusty-20150320"
- },
- {
- "layer": "07f8e8c5",
- "name": "trusty-20150427"
- },
- {
- "layer": "fa81ed08",
- "name": "trusty-20150528"
- },
- {
- "layer": "6d494699",
- "name": "trusty-20150612"
- },
- {
- "layer": "d2a0ecff",
- "name": "trusty-20150630"
- },
- {
- "layer": "63e3c102",
- "name": "trusty-20150730"
- },
- {
- "layer": "8251da35",
- "name": "trusty-20150806"
- },
- {
- "layer": "91e54dfb",
- "name": "trusty-20150814"
- },
- {
- "layer": "cdd47452",
- "name": "trusty-20151001"
- },
- {
- "layer": "a005e6b7",
- "name": "trusty-20151009"
- },
- {
- "layer": "a5a467fd",
- "name": "trusty-20151021"
- },
- {
- "layer": "ca4d7b1b",
- "name": "trusty-20151028"
- },
- {
- "layer": "d55e68e6",
- "name": "trusty-20151208"
- },
- {
- "layer": "af88597e",
- "name": "trusty-20151218"
- },
- {
- "layer": "dce38fb5",
- "name": "utopic"
- },
- {
- "layer": "78949b1e",
- "name": "utopic-20150211"
- },
- {
- "layer": "525b6e4a",
- "name": "utopic-20150228.11"
- },
- {
- "layer": "59a878f2",
- "name": "utopic-20150319"
- },
- {
- "layer": "0b79d1c2",
- "name": "utopic-20150418"
- },
- {
- "layer": "d191563a",
- "name": "utopic-20150427"
- },
- {
- "layer": "ce78e71c",
- "name": "utopic-20150528"
- },
- {
- "layer": "ab57dbaf",
- "name": "utopic-20150612"
- },
- {
- "layer": "dce38fb5",
- "name": "utopic-20150625"
- },
- {
- "layer": "3f0d2d4f",
- "name": "vivid"
- },
- {
- "layer": "2427658c",
- "name": "vivid-20150218"
- },
- {
- "layer": "19c8c047",
- "name": "vivid-20150309"
- },
- {
- "layer": "751a7482",
- "name": "vivid-20150319.1"
- },
- {
- "layer": "ef8182f3",
- "name": "vivid-20150421"
- },
- {
- "layer": "bd94ae58",
- "name": "vivid-20150427"
- },
- {
- "layer": "c6a35822",
- "name": "vivid-20150528"
- },
- {
- "layer": "6be21d1e",
- "name": "vivid-20150611"
- },
- {
- "layer": "23635bbe",
- "name": "vivid-20150802"
- },
- {
- "layer": "013f3d01",
- "name": "vivid-20150813"
- },
- {
- "layer": "82554298",
- "name": "vivid-20150930"
- },
- {
- "layer": "4e9c8310",
- "name": "vivid-20151021"
- },
- {
- "layer": "e97f8c6b",
- "name": "vivid-20151106"
- },
- {
- "layer": "db672630",
- "name": "vivid-20151111"
- },
- {
- "layer": "3f0d2d4f",
- "name": "vivid-20151208"
- },
- {
- "layer": "3e0c71ad",
- "name": "wily"
- },
- {
- "layer": "0fe5a10d",
- "name": "wily-20150528.1"
- },
- {
- "layer": "906f2d7d",
- "name": "wily-20150611"
- },
- {
- "layer": "22ba5544",
- "name": "wily-20150708"
- },
- {
- "layer": "6767f35d",
- "name": "wily-20150731"
- },
- {
- "layer": "1832625b",
- "name": "wily-20150807"
- },
- {
- "layer": "53816304",
- "name": "wily-20150818"
- },
- {
- "layer": "1884caee",
- "name": "wily-20150829"
- },
- {
- "layer": "4dc94650",
- "name": "wily-20151006"
- },
- {
- "layer": "6171b5c3",
- "name": "wily-20151009"
- },
- {
- "layer": "337d0fd7",
- "name": "wily-20151019"
- },
- {
- "layer": "3e0c71ad",
- "name": "wily-20151208"
- },
- {
- "layer": "db856b41",
- "name": "xenial"
- },
- {
- "layer": "db856b41",
- "name": "xenial-20151218.1"
- }
-]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu.json b/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu.json
new file mode 100644
index 0000000..d60b25d
--- /dev/null
+++ b/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu.json
@@ -0,0 +1,15 @@
+{
+ "user": "library",
+ "name": "ubuntu",
+ "namespace": "library",
+ "status": 1,
+ "description": "Ubuntu is a Debian-based Linux operating system based on free software.",
+ "is_private": false,
+ "is_automated": false,
+ "can_edit": false,
+ "star_count": 2954,
+ "pull_count": 37627788,
+ "last_updated": "2016-01-04T19:00:53.547174Z",
+ "has_starred": false,
+ "full_description": "# Supported tags and respective `Dockerfile` links\n\n-\t[`12.04.5`, `12.04`, `precise-20151208`, `precise` (*precise/Dockerfile*)](https://github.com/tianon/docker-brew-ubuntu-core/blob/d7f2045ad9b08962d9728f6d9910fa252282b85f/precise/Dockerfile)\n-\t[`14.04.3`, `14.04`, `trusty-20151218`, `trusty`, `latest` (*trusty/Dockerfile*)](https://github.com/tianon/docker-brew-ubuntu-core/blob/d7f2045ad9b08962d9728f6d9910fa252282b85f/trusty/Dockerfile)\n-\t[`15.04`, `vivid-20151208`, `vivid` (*vivid/Dockerfile*)](https://github.com/tianon/docker-brew-ubuntu-core/blob/d7f2045ad9b08962d9728f6d9910fa252282b85f/vivid/Dockerfile)\n-\t[`15.10`, `wily-20151208`, `wily` (*wily/Dockerfile*)](https://github.com/tianon/docker-brew-ubuntu-core/blob/d7f2045ad9b08962d9728f6d9910fa252282b85f/wily/Dockerfile)\n-\t[`16.04`, `xenial-20151218.1`, `xenial` (*xenial/Dockerfile*)](https://github.com/tianon/docker-brew-ubuntu-core/blob/d7f2045ad9b08962d9728f6d9910fa252282b85f/xenial/Dockerf
ile)\n\nFor more information about this image and its history, please see [the relevant manifest file (`library/ubuntu`)](https://github.com/docker-library/official-images/blob/master/library/ubuntu). This image is updated via pull requests to [the `docker-library/official-images` GitHub repo](https://github.com/docker-library/official-images).\n\nFor detailed information about the virtual/transfer sizes and individual layers of each of the above supported tags, please see [the `ubuntu/tag-details.md` file](https://github.com/docker-library/docs/blob/master/ubuntu/tag-details.md) in [the `docker-library/docs` GitHub repo](https://github.com/docker-library/docs).\n\n# What is Ubuntu?\n\nUbuntu is a Debian-based Linux operating system, with Unity as its default desktop environment. It is based on free software and named after the Southern African philosophy of ubuntu (literally, \"human-ness\"), which often is translated as \"humanity towards others\" or \"the belief in a universal bo
nd of sharing that connects all humanity\".\n\nDevelopment of Ubuntu is led by UK-based Canonical Ltd., a company owned by South African entrepreneur Mark Shuttleworth. Canonical generates revenue through the sale of technical support and other services related to Ubuntu. The Ubuntu project is publicly committed to the principles of open-source software development; people are encouraged to use free software, study how it works, improve upon it, and distribute it.\n\n> [wikipedia.org/wiki/Ubuntu_(operating_system)](https://en.wikipedia.org/wiki/Ubuntu_%28operating_system%29)\n\n\n\n# What's in this image?\n\n## `/etc/apt/sources.list`\n\n### `ubuntu:14.04`\n\n```console\n$ docker run ubuntu:14.04 grep -v '^#' /etc/apt/sources.list\n\ndeb http://archive.ubuntu.com/ubuntu/ trusty main restricted\ndeb-src http://archive.ubuntu.com/ubuntu/ trusty main restricted\n\ndeb
http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted\ndeb-src http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted\n\ndeb http://archive.ubuntu.com/ubuntu/ trusty universe\ndeb-src http://archive.ubuntu.com/ubuntu/ trusty universe\ndeb http://archive.ubuntu.com/ubuntu/ trusty-updates universe\ndeb-src http://archive.ubuntu.com/ubuntu/ trusty-updates universe\n\n\ndeb http://archive.ubuntu.com/ubuntu/ trusty-security main restricted\ndeb-src http://archive.ubuntu.com/ubuntu/ trusty-security main restricted\ndeb http://archive.ubuntu.com/ubuntu/ trusty-security universe\ndeb-src http://archive.ubuntu.com/ubuntu/ trusty-security universe\n```\n\n### `ubuntu:12.04`\n\n```console\n$ docker run ubuntu:12.04 cat /etc/apt/sources.list\n\ndeb http://archive.ubuntu.com/ubuntu/ precise main restricted\ndeb-src http://archive.ubuntu.com/ubuntu/ precise main restricted\n\ndeb http://archive.ubuntu.com/ubuntu/ precise-updates main restricted\ndeb-src http://archive.ubuntu.
com/ubuntu/ precise-updates main restricted\n\ndeb http://archive.ubuntu.com/ubuntu/ precise universe\ndeb-src http://archive.ubuntu.com/ubuntu/ precise universe\ndeb http://archive.ubuntu.com/ubuntu/ precise-updates universe\ndeb-src http://archive.ubuntu.com/ubuntu/ precise-updates universe\n\n\ndeb http://archive.ubuntu.com/ubuntu/ precise-security main restricted\ndeb-src http://archive.ubuntu.com/ubuntu/ precise-security main restricted\ndeb http://archive.ubuntu.com/ubuntu/ precise-security universe\ndeb-src http://archive.ubuntu.com/ubuntu/ precise-security universe\n```\n\n# Supported Docker versions\n\nThis image is officially supported on Docker version 1.9.1.\n\nSupport for older versions (down to 1.6) is provided on a best-effort basis.\n\nPlease see [the Docker installation documentation](https://docs.docker.com/installation/) for details on how to upgrade your Docker daemon.\n\n# User Feedback\n\n## Documentation\n\nDocumentation for this image is stored in the [`ubunt
u/` directory](https://github.com/docker-library/docs/tree/master/ubuntu) of the [`docker-library/docs` GitHub repo](https://github.com/docker-library/docs). Be sure to familiarize yourself with the [repository's `README.md` file](https://github.com/docker-library/docs/blob/master/README.md) before attempting a pull request.\n\n## Issues\n\nIf you have any problems with or questions about this image, please contact us through a [GitHub issue](https://github.com/tianon/docker-brew-ubuntu-core/issues).\n\nYou can also reach many of the official image maintainers via the `#docker-library` IRC channel on [Freenode](https://freenode.net).\n\n## Contributing\n\nYou are invited to contribute new features, fixes, or updates, large or small; we are always thrilled to receive pull requests, and do our best to process them as fast as we can.\n\nBefore you start to code, we recommend discussing your plans through a [GitHub issue](https://github.com/tianon/docker-brew-ubuntu-core/issues), especi
ally for more ambitious contributions. This gives other contributors a chance to point you in the right direction, give you feedback on your design, and help you find out if someone else is working on the same thing."
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu_tags.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu_tags.json b/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu_tags.json
new file mode 100644
index 0000000..f3914c9
--- /dev/null
+++ b/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu_tags.json
@@ -0,0 +1,975 @@
+{
+ "count": 88,
+ "next": null,
+ "previous": null,
+ "results": [
+ {
+ "name": "xenial",
+ "full_size": 47439662,
+ "id": 1589976,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T19:00:51.344198Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "xenial-20151218.1",
+ "full_size": 47439662,
+ "id": 1589974,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T19:00:45.326998Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "16.04",
+ "full_size": 47439662,
+ "id": 1589970,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T19:00:39.215205Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily",
+ "full_size": 50294202,
+ "id": 2332,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T19:00:30.141301Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily-20151208",
+ "full_size": 50294202,
+ "id": 1509180,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T19:00:24.324323Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "15.10",
+ "full_size": 50294202,
+ "id": 2327,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T19:00:18.625895Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid",
+ "full_size": 49334628,
+ "id": 2329,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T19:00:12.764756Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20151208",
+ "full_size": 49334628,
+ "id": 1509158,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T19:00:07.282476Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "15.04",
+ "full_size": 49334628,
+ "id": 2298,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T19:00:01.659187Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "latest",
+ "full_size": 65747044,
+ "id": 2343,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:59:54.779484Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty",
+ "full_size": 65747044,
+ "id": 2305,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:59:49.102906Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20151218",
+ "full_size": 65747044,
+ "id": 1657173,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:59:43.103725Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "14.04",
+ "full_size": 65747044,
+ "id": 2324,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:59:37.496154Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "14.04.3",
+ "full_size": 65747044,
+ "id": 693829,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:58:46.261151Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise",
+ "full_size": 44194573,
+ "id": 2292,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:57:33.494399Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20151208",
+ "full_size": 44194573,
+ "id": 1509115,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:57:22.912930Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "12.04",
+ "full_size": 44194573,
+ "id": 2310,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:57:14.495660Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "12.04.5",
+ "full_size": 44194573,
+ "id": 2295,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:57:08.237857Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20151208",
+ "full_size": 65742980,
+ "id": 1509143,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2015-12-18T18:26:56.770757Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily-20151019",
+ "full_size": 49817335,
+ "id": 1168566,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2015-12-08T09:04:03.336941Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20151111",
+ "full_size": 49333876,
+ "id": 1389462,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2015-12-08T09:02:56.243906Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20151028",
+ "full_size": 65742789,
+ "id": 1313714,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2015-12-08T09:02:32.340602Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20151028",
+ "full_size": 44096878,
+ "id": 1313721,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2015-12-08T09:02:07.834932Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20151106",
+ "full_size": 49329280,
+ "id": 1313735,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 213249,
+ "last_updated": "2015-11-21T01:14:52.126272Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "12.10",
+ "full_size": 58078433,
+ "id": 2339,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:42:40.878495Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20150218.1",
+ "full_size": 65832655,
+ "id": 2325,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:42:29.777917Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "utopic-20150211",
+ "full_size": 68374766,
+ "id": 2307,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:41:34.805100Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "quantal",
+ "full_size": 58078433,
+ "id": 2341,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:40:29.962553Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "14.04.1",
+ "full_size": 65827193,
+ "id": 2322,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:39:42.479726Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "raring",
+ "full_size": 57667348,
+ "id": 2316,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:38:47.745980Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20150218",
+ "full_size": 44122689,
+ "id": 2320,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:38:37.964774Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20150309",
+ "full_size": 49448856,
+ "id": 2317,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:37:59.209284Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "10.04",
+ "full_size": 63533781,
+ "id": 2299,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:37:16.010344Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "saucy",
+ "full_size": 60522580,
+ "id": 2301,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:37:04.113916Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20150228.11",
+ "full_size": 43657047,
+ "id": 2331,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:36:51.552688Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "utopic-20150228.11",
+ "full_size": 68379536,
+ "id": 2318,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:36:02.986916Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "13.10",
+ "full_size": 60522580,
+ "id": 2304,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:34:52.333445Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "13.04",
+ "full_size": 57667348,
+ "id": 2294,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:33:49.391093Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20150212",
+ "full_size": 43616335,
+ "id": 2340,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:32:59.135708Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20150228.11",
+ "full_size": 65828716,
+ "id": 2323,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:32:14.798440Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "lucid",
+ "full_size": 63533781,
+ "id": 2321,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 134455,
+ "last_updated": "2015-11-14T14:31:11.758283Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20151021",
+ "full_size": 49328003,
+ "id": 1168551,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2015-10-28T12:21:31.210637Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20151021",
+ "full_size": 65741561,
+ "id": 1168539,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2015-10-28T12:21:07.780326Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20151020",
+ "full_size": 44096883,
+ "id": 1168524,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": "2015-10-28T12:20:39.816211Z",
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily-20151009",
+ "full_size": 49844614,
+ "id": 1096696,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20151009",
+ "full_size": 65861875,
+ "id": 1096682,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily-20151006",
+ "full_size": 49861095,
+ "id": 1081815,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20150930",
+ "full_size": 49345386,
+ "id": 1081804,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20151001",
+ "full_size": 65757468,
+ "id": 1081789,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20150924",
+ "full_size": 44037965,
+ "id": 1081772,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily-20150829",
+ "full_size": 49614664,
+ "id": 828778,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily-20150818",
+ "full_size": 50298307,
+ "id": 778618,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20150813",
+ "full_size": 43977816,
+ "id": 776393,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20150813",
+ "full_size": 49343696,
+ "id": 776144,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20150814",
+ "full_size": 65859249,
+ "id": 775535,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily-20150807",
+ "full_size": 50528668,
+ "id": 693839,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 213249,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20150806",
+ "full_size": 65857914,
+ "id": 693834,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 213249,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily-20150731",
+ "full_size": 50488452,
+ "id": 674054,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 213249,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20150802",
+ "full_size": 49340063,
+ "id": 674043,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 213249,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20150730",
+ "full_size": 65860360,
+ "id": 674034,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 213249,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20150729",
+ "full_size": 43967445,
+ "id": 674016,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 213249,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "wily-20150708",
+ "full_size": 50494409,
+ "id": 541269,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "utopic-20150625",
+ "full_size": 68399747,
+ "id": 541258,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20150630",
+ "full_size": 65858138,
+ "id": 541253,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20150626",
+ "full_size": 43878461,
+ "id": 541246,
+ "repository": 130,
+ "creator": 2215,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20150528",
+ "full_size": 131333439,
+ "id": 2338,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "utopic-20150528",
+ "full_size": 194454267,
+ "id": 2337,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "utopic",
+ "full_size": 68399747,
+ "id": 2336,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "precise-20150528",
+ "full_size": 133416464,
+ "id": 2335,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "utopic-20150319",
+ "full_size": 194424279,
+ "id": 2334,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "utopic-20150418",
+ "full_size": 194463410,
+ "id": 2333,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "precise-20150427",
+ "full_size": 132465012,
+ "id": 2330,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "trusty-20150612",
+ "full_size": 188284994,
+ "id": 2328,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "wily-20150528.1",
+ "full_size": 132392276,
+ "id": 2326,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "vivid-20150319.1",
+ "full_size": 131685773,
+ "id": 2315,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "14.04.2",
+ "full_size": 65860360,
+ "id": 2314,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 213249,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20150528",
+ "full_size": 188281989,
+ "id": 2313,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "precise-20150612",
+ "full_size": 133706040,
+ "id": 2312,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "trusty-20150320",
+ "full_size": 188300556,
+ "id": 2311,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "vivid-20150611",
+ "full_size": 49338475,
+ "id": 2309,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "trusty-20150427",
+ "full_size": 188278440,
+ "id": 2308,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "wily-20150611",
+ "full_size": 133648792,
+ "id": 2306,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "utopic-20150612",
+ "full_size": 194462706,
+ "id": 2303,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "utopic-20150427",
+ "full_size": 194461653,
+ "id": 2302,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "precise-20150320",
+ "full_size": 131886863,
+ "id": 2300,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "14.10",
+ "full_size": 68399747,
+ "id": 2297,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": null,
+ "image_id": null,
+ "v2": true
+ },
+ {
+ "name": "vivid-20150427",
+ "full_size": 131302888,
+ "id": 2296,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ },
+ {
+ "name": "vivid-20150421",
+ "full_size": 131279915,
+ "id": 2293,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 7,
+ "last_updated": null,
+ "image_id": null,
+ "v2": false
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu_tags_latest.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu_tags_latest.json b/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu_tags_latest.json
new file mode 100644
index 0000000..c5ce942
--- /dev/null
+++ b/libcloud/test/container/fixtures/docker_utils/v2_repositories_library_ubuntu_tags_latest.json
@@ -0,0 +1,11 @@
+{
+ "name": "latest",
+ "full_size": 65747044,
+ "id": 2343,
+ "repository": 130,
+ "creator": 7,
+ "last_updater": 2215,
+ "last_updated": "2016-01-04T18:59:54.779484Z",
+ "image_id": null,
+ "v2": true
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/test/container/test_docker_utils.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_docker_utils.py b/libcloud/test/container/test_docker_utils.py
new file mode 100644
index 0000000..d209447
--- /dev/null
+++ b/libcloud/test/container/test_docker_utils.py
@@ -0,0 +1,86 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+
+from libcloud.test import unittest
+from libcloud.container.utils.docker import HubClient
+from libcloud.utils.py3 import httplib
+from libcloud.test.file_fixtures import ContainerFileFixtures
+from libcloud.test import MockHttp
+
+
+class DockerUtilitiesTestCase(unittest.TestCase):
+
+ def setUp(self):
+ HubClient.connectionCls.conn_classes = (
+ DockerMockHttp, DockerMockHttp)
+ DockerMockHttp.type = None
+ DockerMockHttp.use_param = 'a'
+ self.driver = HubClient()
+
+ def test_list_tags(self):
+ tags = self.driver.list_images('ubuntu', max_count=100)
+ self.assertEqual(len(tags), 88)
+ self.assertEqual(tags[0].name, 'registry.hub.docker.com/ubuntu:xenial')
+
+ def test_get_repository(self):
+ repo = self.driver.get_repository('ubuntu')
+ self.assertEqual(repo['name'], 'ubuntu')
+
+ def test_get_image(self):
+ image = self.driver.get_image('ubuntu', 'latest')
+ self.assertEqual(image.id, '2343')
+ self.assertEqual(image.name, 'registry.hub.docker.com/ubuntu:latest')
+ self.assertEqual(image.path, 'registry.hub.docker.com/ubuntu:latest')
+
+
+class DockerMockHttp(MockHttp):
+ fixtures = ContainerFileFixtures('docker_utils')
+
+ def _version(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('version.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def v2_repositories_library_ubuntu_tags_latest(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('v2_repositories_library_ubuntu_tags_latest.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def v2_repositories_library_ubuntu_tags(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('v2_repositories_library_ubuntu_tags.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def v2_repositories_library_ubuntu(
+ self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('v2_repositories_library_ubuntu.json')
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d29629de/libcloud/test/container/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_ecs.py b/libcloud/test/container/test_ecs.py
index 2a3a2c2..518daae 100644
--- a/libcloud/test/container/test_ecs.py
+++ b/libcloud/test/container/test_ecs.py
@@ -35,7 +35,7 @@ class ElasticContainerDriverTestCase(unittest.TestCase):
ECSMockHttp.use_param = 'a'
ElasticContainerDriver.ecrConnectionClass.conn_classes = (
ECSMockHttp, ECSMockHttp)
-
+
self.driver = ElasticContainerDriver(*CONTAINER_PARAMS_ECS)
def test_list_clusters(self):
[02/50] libcloud git commit: Added Joyent Triton as a Docker service
provider with driver.
Posted by an...@apache.org.
Added Joyent Triton as a Docker service provider with driver.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/e61bad54
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/e61bad54
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/e61bad54
Branch: refs/heads/trunk
Commit: e61bad54fad40c9c9cf0d3ea334c399f2d028af9
Parents: fe7ba5c
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Dec 23 15:31:42 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Dec 23 15:31:42 2015 +1100
----------------------------------------------------------------------
docs/_static/images/provider_logos/triton.svg | 107 +++++++++++++++++++
docs/container/drivers/joyent.rst | 57 ++++++++++
.../container/joyent/instantiate_driver.py | 9 ++
libcloud/container/drivers/joyent.py | 72 +++++++++++++
libcloud/container/providers.py | 2 +
libcloud/container/types.py | 1 +
6 files changed, 248 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e61bad54/docs/_static/images/provider_logos/triton.svg
----------------------------------------------------------------------
diff --git a/docs/_static/images/provider_logos/triton.svg b/docs/_static/images/provider_logos/triton.svg
new file mode 100644
index 0000000..505257e
--- /dev/null
+++ b/docs/_static/images/provider_logos/triton.svg
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="298.2px" height="62.8px" viewBox="0 0 298.2 62.8" enable-background="new 0 0 298.2 62.8" xml:space="preserve">
+<g>
+ <g id="XMLID_35277_">
+ <path id="XMLID_35290_" fill-rule="evenodd" clip-rule="evenodd" fill="#3E3E3F" d="M99.1,15.8c0.4,0.3,0.8,0.5,1.3,0.5
+ c0.8,0,1-0.5,1-1.2V9.4h0.9v4.7c0,0.4,0,0.9,0,1.3c0,1.1-0.6,1.7-1.9,1.7c-0.9,0-1.5-0.4-1.8-0.6L99.1,15.8z M107.7,14.1
+ c0-1.4-0.4-2.3-1.5-2.3c-1.1,0-1.6,0.9-1.6,2.1c0,1.1,0.2,2.4,1.5,2.4C107.2,16.4,107.7,15.4,107.7,14.1z M106.2,11.1
+ c0.8,0,2.3,0.2,2.3,2.8c0,2.2-1.1,3.1-2.5,3.1c-1.4,0-2.3-1-2.3-3C103.7,11.7,105.1,11.1,106.2,11.1 M114,16.7v-5.4h-0.9v3.4
+ c0,0.8-0.5,1.3-1.4,1.3c-1.2,0-1.3-0.7-1.3-1.5v-3.2h-0.9v3.4c0,1.3,0.6,1.8,1.6,1.9c-0.6,0.4-1.2,1-1.2,1.9
+ c0,0.9,0.6,1.4,1.7,1.4c1.2,0,1.9-0.6,2.2-1.7C113.9,17.9,114,17.2,114,16.7z M111.7,19.3c1,0,1.4-0.9,1.4-2.1v-1
+ c-1.4,0.6-2.3,1.2-2.3,2.3C110.8,19,111.1,19.3,111.7,19.3z M117.6,11.1c-1.7,0-2.6,1.4-2.6,3.1c0,1.7,0.7,2.9,2.5,2.9
+ c0.9,0,1.6-0.4,1.8-0.6l-0.3-0.6c-0.2,0.2-0.7,0.5-1.5,0.5c-1.2,0-1.7-1-1.7-1.9c0.1,0,0.2,0,0.3,0c1.1,0,3.1-0.3,3.1-1.9
+ C119.3,11.7,118.7,11.1,117.6,11.1z M117.6,11.8c-1.2,0-1.7,1.1-1.7,2c0.1,0,0.1,0,0.2,0c0.8,0,2.4-0.2,2.4-1.2
+ C118.5,12.1,118.1,11.8,117.6,11.8z M121.3,16.9v-3.7c0-0.7,0.7-1.4,1.5-1.4c1,0,1.1,0.7,1.1,1.5v3.6h0.9v-3.8
+ c0-1.3-0.6-1.9-1.8-1.9c-0.7,0-1.4,0.3-1.8,1l-0.1-0.8h-0.8l0.1,0.9v4.8H121.3z M126.2,9v6.3c0,0.8,0,1.7,1.6,1.7
+ c0.5,0,1-0.1,1.3-0.4l-0.3-0.6c-0.2,0.1-0.5,0.3-0.9,0.3c-0.5,0-0.8-0.2-0.8-1V12h1.6v-0.8h-1.6V9H126.2z"/>
+ <g id="XMLID_35316_">
+ <g>
+ <path id="XMLID_112_" fill="#3E3E3F" d="M98,23.4h31.5V30h-10.8v22.9h-9.8V30H98V23.4z"/>
+ <path id="XMLID_109_" fill="#3E3E3F" d="M132.4,23.4H156c7.2,0,9.9,3.3,9.9,8.2c0,3.9-2.1,6.1-4.7,6.7v0.1
+ c1.9,0.6,3.3,2.1,3.6,5.3c0.5,5.8,0.6,7.7,1.9,9.2h-10.8c-0.5-1.3-0.6-3-0.6-4.4c0-4.6-1.5-5.5-4-5.5h-9v9.8h-9.8V23.4z
+ M142.2,36.4h9.5c2.4,0,3.7-1.2,3.7-3.3c0-1.9-1.3-3.2-3.7-3.2h-9.5V36.4z"/>
+ <path id="XMLID_107_" fill="#3E3E3F" d="M170,23.4h9.8v29.5H170V23.4z"/>
+ <path id="XMLID_105_" fill="#3E3E3F" d="M182.9,23.4h31.5V30h-10.8v22.9h-9.8V30h-10.8V23.4z"/>
+ <path id="XMLID_102_" fill="#3E3E3F" d="M233.3,22.5c10.4,0,19.2,3.4,19.2,15.7c0,12.2-8.8,15.7-19.2,15.7
+ c-10.4,0-19.2-3.4-19.2-15.7C214.1,25.9,222.9,22.5,233.3,22.5z M233.3,47.2c5.3,0,8.8-2.9,8.8-9.1c0-6.2-3.5-9.1-8.8-9.1
+ c-5.2,0-8.8,2.9-8.8,9.1C224.5,44.3,228.1,47.2,233.3,47.2z"/>
+ <path id="XMLID_100_" fill="#3E3E3F" d="M254.5,23.4h11.3l13.7,18.5h0.1V23.4h9.5v29.5h-10.9l-14.1-18.6H264v18.6h-9.5V23.4z"/>
+ </g>
+ </g>
+ <g id="XMLID_35331_">
+ <path id="XMLID_35332_" fill="#3E3E3F" d="M294.4,23.9h-0.9v2.5H293v-2.5h-0.9v-0.4h2.3V23.9z M298.2,26.4h-0.5V24h0l-0.9,2.4
+ h-0.3l-0.9-2.4h0v2.4H295v-2.9h0.7l0.9,2.2l0.8-2.2h0.7V26.4z"/>
+ </g>
+ </g>
+ <g id="XMLID_34924_">
+ <g id="XMLID_34928_" opacity="0.5">
+ <polygon id="XMLID_34929_" fill="#3B5967" points="42.8,42.8 42.8,44.7 58.1,60.1 60.1,60.1 60.1,58.1 44.7,42.8 "/>
+ </g>
+ <path id="XMLID_34930_" fill="#C42C28" d="M42.8,21.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1-0.1-0.1c0,0,0-0.1-0.1-0.1
+ c-0.1-0.1-0.1-0.1-0.2-0.2l-20-20c-0.1-0.1-0.1-0.1-0.2-0.2c0,0-0.1,0-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1,0-0.1,0
+ c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.3,0h-20C1.3,0,1.2,0,1.1,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0.1c0,0-0.1,0-0.1,0.1
+ C0.5,0.3,0.3,0.5,0.2,0.6c0,0,0,0.1-0.1,0.1c0,0-0.1,0.1-0.1,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.1,0,0.2,0,0.3v20
+ c0,0.1,0,0.2,0,0.3c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0.1,0.1c0,0,0,0.1,0.1,0.1c0.1,0.1,0.1,0.1,0.2,0.2l20,20
+ c0.1,0.1,0.1,0.1,0.2,0.2c0,0,0.1,0,0.1,0.1c0,0,0.1,0.1,0.1,0.1c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0.1,0,0.2,0,0.3,0h20
+ c0.8,0,1.4-0.6,1.4-1.4v-20C42.8,21.3,42.8,21.2,42.8,21.1z M2.7,4.7L20,22v16.1L2.7,20.8V4.7z M22,20L4.7,2.7h16.1L38.1,20H22z
+ M22.8,40.1V22.8h17.3v17.3H22.8z"/>
+ <g id="XMLID_34935_" opacity="0.5">
+ <polygon id="XMLID_34936_" fill="#C52B27" points="22.8,22.8 22.8,24.7 38.1,40.1 40.1,40.1 40.1,38.1 24.7,22.8 "/>
+ <polygon id="XMLID_34937_" fill="#C52B27" points="20,2.7 20,18.1 22,20 22.8,20 22.8,4.7 20.8,2.7 "/>
+ <polygon id="XMLID_34938_" fill="#C52B27" points="18.1,20 2.7,20 2.7,20.8 4.7,22.8 20,22.8 20,22 "/>
+ <path id="XMLID_34940_" fill="#C52B27" d="M41.8,42.7c0,0,0.1,0,0.1,0C41.9,42.7,41.9,42.7,41.8,42.7z"/>
+ <path id="XMLID_34941_" fill="#C52B27" d="M42.6,42.1c0,0,0,0.1-0.1,0.1C42.6,42.2,42.6,42.1,42.6,42.1z"/>
+ <path id="XMLID_34942_" fill="#C52B27" d="M42.7,41.8c0,0,0,0.1,0,0.1C42.7,41.9,42.7,41.9,42.7,41.8z"/>
+ <path id="XMLID_34944_" fill="#C52B27" d="M42.8,41.4c0,0.1,0,0.2,0,0.3C42.8,41.6,42.8,41.5,42.8,41.4z"/>
+ <path id="XMLID_34946_" fill="#C52B27" d="M41.4,42.8c0.1,0,0.2,0,0.3,0C41.6,42.8,41.5,42.8,41.4,42.8z"/>
+ <path id="XMLID_34947_" fill="#C52B27" d="M42.1,42.6c0,0,0.1,0,0.1-0.1C42.2,42.6,42.1,42.6,42.1,42.6z"/>
+ </g>
+ <path id="XMLID_34948_" fill="#F16323" d="M62.8,21.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1-0.1-0.1c0,0,0-0.1-0.1-0.1
+ c-0.1-0.1-0.1-0.1-0.2-0.2l-20-20c-0.1-0.1-0.1-0.1-0.2-0.2c0,0-0.1,0-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1,0-0.1,0
+ c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.3,0h-20c0.1,0,0.2,0,0.3,0h0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0h0c0.1,0,0.1,0.1,0.2,0.1
+ c0,0,0,0,0,0l0,0c0.1,0.1,0.1,0.1,0.2,0.2l2.3,2.3h16.1L58.1,20H42l0.4,0.4c0.1,0.1,0.1,0.1,0.2,0.2c0,0,0,0.1,0.1,0.1
+ c0,0,0.1,0.1,0.1,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.1,0,0.2,0,0.3v1.4h17.3v17.3H42.8v1.4c0,0.1,0,0.2,0,0.3
+ c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1-0.1,0.1c0,0,0,0.1-0.1,0.1c-0.1,0.2-0.2,0.3-0.4,0.4c0,0-0.1,0-0.1,0.1
+ c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.3,0h20c0.8,0,1.4-0.6,1.4-1.4v-20
+ C62.8,21.3,62.8,21.2,62.8,21.1z"/>
+ <path fill="#BDBEC0" d="M41.4,42.8h-1.4v17.3H22.8V42.8h-1.4c-0.1,0-0.2,0-0.3,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0
+ c0,0-0.1,0-0.1-0.1c0,0-0.1,0-0.1-0.1c-0.1-0.1-0.1-0.1-0.2-0.2L20,42v16.1L2.7,40.9V24.7l-2.3-2.3c-0.1-0.1-0.1-0.1-0.2-0.2l0,0
+ c0,0,0,0,0-0.1c0-0.1-0.1-0.2-0.1-0.3c0,0,0,0,0-0.1l0,0C0,21.7,0,21.5,0,21.4v20c0,0.1,0,0.2,0,0.3c0,0,0,0.1,0,0.1
+ c0,0,0,0.1,0,0.1c0,0,0,0.1,0.1,0.1c0,0,0,0.1,0.1,0.1c0.1,0.1,0.1,0.1,0.2,0.2l20,20c0.1,0.1,0.1,0.1,0.2,0.2c0,0,0.1,0,0.1,0.1
+ c0,0,0.1,0.1,0.1,0.1c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0.1,0,0.2,0,0.3,0h20c0.8,0,1.4-0.6,1.4-1.4V42.8H41.4z"/>
+ <g id="XMLID_34949_">
+ <polygon id="XMLID_34950_" opacity="0.5" fill="#F16323" points="42.8,20 42.8,4.7 40.9,2.7 40.1,2.7 40.1,18.1 42,20 "/>
+ <polygon id="XMLID_34951_" opacity="0.5" fill="#F16323" points="42.8,22.8 42.8,24.7 58.1,40.1 60.1,40.1 60.1,38.1 44.7,22.8
+ "/>
+ <path id="XMLID_34952_" opacity="0.5" fill="#F16323" d="M41.8,0.1c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0.1c0,0,0.1,0,0.1,0.1
+ c0.1,0.1,0.1,0.1,0.2,0.2l0,0c-0.2-0.3-0.6-0.4-1-0.4c0.1,0,0.2,0,0.3,0C41.7,0,41.8,0.1,41.8,0.1z"/>
+ </g>
+ <g id="XMLID_34953_" opacity="0.5">
+ <path id="XMLID_34954_" fill="#F19922" d="M62,0.1c0,0,0.1,0,0.1,0.1c0,0,0,0,0.1,0C62.1,0.2,62.1,0.1,62,0.1z"/>
+ <path id="XMLID_34955_" fill="#F19922" d="M62.4,0.4c-0.1-0.1-0.1-0.1-0.2-0.2C62.3,0.3,62.4,0.3,62.4,0.4z"/>
+ <polygon id="XMLID_34956_" fill="#F19922" points="60.1,2.7 60.1,18.1 62,20 62.8,20 62.8,4.7 60.9,2.7 "/>
+ <path id="XMLID_34957_" fill="#F19922" d="M61.8,0.1C61.9,0.1,61.9,0.1,61.8,0.1c0,0-0.1,0-0.1,0C61.8,0,61.8,0.1,61.8,0.1z"/>
+ <polygon id="XMLID_34958_" fill="#F19922" points="62.8,22.8 62.8,24.7 78.2,40.1 80.1,40.1 80.1,38.1 64.8,22.8 "/>
+ </g>
+ <polygon id="XMLID_34959_" opacity="0.5" fill="#83D2E6" points="64.8,42.8 62.8,42.8 62.8,44.7 78.2,60.1 80.1,60.1 80.1,58.1
+ "/>
+ <path id="XMLID_34960_" fill="#83D2E6" d="M81.5,42.8h-1.4v17.3H62.8v1.4c0,0.8-0.6,1.4-1.4,1.4h20c0.8,0,1.4-0.6,1.4-1.4v-20
+ C82.9,42.2,82.2,42.8,81.5,42.8z"/>
+ <path id="XMLID_34961_" fill="#5A88A9" d="M61.5,42.8h-1.4v17.3H42.8v1.4c0,0.8-0.6,1.4-1.4,1.4h20c0.8,0,1.4-0.6,1.4-1.4V42.8
+ H61.5z"/>
+ <g id="XMLID_34962_" opacity="0.5">
+ <polygon id="XMLID_34963_" fill="#BDBEC0" points="38.1,60.1 40.1,60.1 40.1,58.2 24.7,42.8 22.8,42.8 22.8,44.8 "/>
+ <polygon id="XMLID_34964_" fill="#BDBEC0" points="2.7,40.9 4.7,42.8 20,42.8 20,42 18.1,40.1 2.7,40.1 "/>
+ </g>
+ <path id="XMLID_34965_" fill="#F19922" d="M82.8,21.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1-0.1-0.1c0,0,0-0.1-0.1-0.1
+ c-0.1-0.1-0.1-0.1-0.2-0.2l-20-20c-0.1-0.1-0.1-0.1-0.2-0.2c0,0-0.1,0-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1,0-0.1,0
+ c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.3,0h-20c0.1,0,0.2,0,0.3,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0.1c0,0,0.1,0,0.1,0.1
+ c0.1,0.1,0.1,0.1,0.2,0.2l2.3,2.3h16.1L78.2,20H62l0.4,0.4c0.1,0.1,0.1,0.1,0.2,0.2c0,0,0,0.1,0.1,0.1c0,0,0.1,0.1,0.1,0.1
+ c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.1,0,0.2,0,0.3v1.4h17.3v17.3H62.8v1.4c0,0.8-0.6,1.4-1.4,1.4h20c0.8,0,1.4-0.6,1.4-1.4v-20
+ C82.9,21.3,82.8,21.2,82.8,21.1z"/>
+ </g>
+</g>
+</svg>
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e61bad54/docs/container/drivers/joyent.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/joyent.rst b/docs/container/drivers/joyent.rst
new file mode 100644
index 0000000..c2a2233
--- /dev/null
+++ b/docs/container/drivers/joyent.rst
@@ -0,0 +1,57 @@
+Joyent Triton Container Driver Documentation
+==================================
+
+`Joyent Triton`_ is a Docker hosting service, provided by service provider `Joyent`.
+Docker-native tools and elastic hosts make deploying on Triton as easy as running Docker on your laptop.
+There is no special software to install or configure.
+Mix Docker containers with container-native Linux to extend the benefits of containerization to legacy applications and stateful services.
+
+.. figure:: /_static/images/provider_logos/triton.svg
+ :align: center
+ :width: 300
+ :target: http://joyent.com/
+
+Instantiating the driver
+-------------------------------------
+
+Download the script:
+
+ curl -O https://raw.githubusercontent.com/joyent/sdc-docker/master/tools/sdc-docker-setup.sh
+
+Now execute the script, substituting the correct values:
+
+ bash sdc-docker-setup.sh <CLOUDAPI_URL> <ACCOUNT_USERNAME> ~/.ssh/<PRIVATE_KEY_FILE>
+
+This should output something similar to the following:
+
+ Setting up Docker client for SDC using:
+ CloudAPI: https://us-east-1.api.joyent.com
+ Account: jill
+ Key: /Users/localuser/.ssh/sdc-docker.id_rsa
+
+ If you have a pass phrase on your key, the openssl command will
+ prompt you for your pass phrase now and again later.
+
+ Verifying CloudAPI access.
+ CloudAPI access verified.
+
+ Generating client certificate from SSH private key.
+ writing RSA key
+ Wrote certificate files to /Users/localuser/.sdc/docker/jill
+
+ Get Docker host endpoint from cloudapi.
+ Docker service endpoint is: tcp://us-east-1.docker.joyent.com:2376
+
+ * * *
+ Success. Set your environment as follows:
+
+ export DOCKER_CERT_PATH=/Users/localuser/.sdc/docker/jill
+ export DOCKER_HOST=tcp://us-east-1.docker.joyent.com:2376
+ export DOCKER_CLIENT_TIMEOUT=300
+ export DOCKER_TLS_VERIFY=1
+
+.. literalinclude:: /examples/container/joyent/instantiate_driver.py
+ :language: python
+
+.. _`Joyent Triton`: https://www.joyent.com/blog/understanding-triton-containers
+.. _`Joyent`: https://www.joyent.com/
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e61bad54/docs/examples/container/joyent/instantiate_driver.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/joyent/instantiate_driver.py b/docs/examples/container/joyent/instantiate_driver.py
new file mode 100644
index 0000000..97f011e
--- /dev/null
+++ b/docs/examples/container/joyent/instantiate_driver.py
@@ -0,0 +1,9 @@
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+
+cls = get_driver(Provider.JOYENT)
+
+conn = cls(host='us-east-1.docker.joyent.com', port=2376,
+ key_file='key.pem', cert_file='~/.sdc/docker/admin/ca.pem')
+
+conn.list_images()
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e61bad54/libcloud/container/drivers/joyent.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/joyent.py b/libcloud/container/drivers/joyent.py
new file mode 100644
index 0000000..f236808
--- /dev/null
+++ b/libcloud/container/drivers/joyent.py
@@ -0,0 +1,72 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from libcloud.container.providers import Provider
+
+from libcloud.container.drivers.docker import (DockerContainerDriver,
+ DockerConnection)
+
+
+class JoyentContainerDriver(DockerContainerDriver):
+ """
+ Joyent Triton container driver class.
+
+ >>> from libcloud.container.providers import get_driver
+ >>> driver = get_driver('joyent')
+ >>> conn = driver(host='https://us-east-1.docker.joyent.com',
+ port=2376, key_file='key.pem', cert_file='cert.pem')
+ """
+
+ type = Provider.JOYENT
+ name = 'Joyent'
+ website = 'http://joyent.com'
+ connectionCls = DockerConnection
+
+ def __init__(self, key=None, secret=None, secure=False, host='localhost',
+ port=2376, key_file=None, cert_file=None):
+
+ super(JoyentContainerDriver, self).__init__(key=key, secret=secret,
+ secure=secure, host=host,
+ port=port,
+ key_file=key_file,
+ cert_file=cert_file)
+ if host.startswith('https://'):
+ secure = True
+
+ # strip the prefix
+ prefixes = ['http://', 'https://']
+ for prefix in prefixes:
+ if host.startswith(prefix):
+ host = host.strip(prefix)
+
+ if key_file or cert_file:
+ # docker tls authentication-
+ # https://docs.docker.com/articles/https/
+ # We pass two files, a key_file with the
+ # private key and cert_file with the certificate
+ # libcloud will handle them through LibcloudHTTPSConnection
+ if not (key_file and cert_file):
+ raise Exception(
+ 'Needs both private key file and '
+ 'certificate file for tls authentication')
+ self.connection.key_file = key_file
+ self.connection.cert_file = cert_file
+ self.connection.secure = True
+ else:
+ self.connection.secure = secure
+
+ self.connection.host = host
+ self.connection.port = port
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e61bad54/libcloud/container/providers.py
----------------------------------------------------------------------
diff --git a/libcloud/container/providers.py b/libcloud/container/providers.py
index 0afd200..45daa88 100644
--- a/libcloud/container/providers.py
+++ b/libcloud/container/providers.py
@@ -22,6 +22,8 @@ DRIVERS = {
('libcloud.container.drivers.dummy', 'DummyContainerDriver'),
Provider.DOCKER:
('libcloud.container.drivers.docker', 'DockerContainerDriver'),
+ Provider.JOYENT:
+ ('libcloud.container.drivers.joyent', 'JoyentContainerDriver'),
}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e61bad54/libcloud/container/types.py
----------------------------------------------------------------------
diff --git a/libcloud/container/types.py b/libcloud/container/types.py
index ce57f06..559d779 100644
--- a/libcloud/container/types.py
+++ b/libcloud/container/types.py
@@ -42,6 +42,7 @@ class Type(object):
class Provider(object):
DUMMY = 'dummy'
DOCKER = 'docker'
+ JOYENT = 'joyent'
class ContainerState(Type):
[39/50] libcloud git commit: Merge branch 'trunk' into
LIBCLOUD-781_containers
Posted by an...@apache.org.
Merge branch 'trunk' into LIBCLOUD-781_containers
# Conflicts:
# CHANGES.rst
# libcloud/test/secrets.py-dist
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/104cdb15
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/104cdb15
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/104cdb15
Branch: refs/heads/trunk
Commit: 104cdb1563cdd6ce75f8b570aa4cd456782cb1ce
Parents: 223b517 ae5b069
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Jan 11 10:30:34 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Jan 11 10:30:34 2016 +1100
----------------------------------------------------------------------
CHANGES.rst | 17 +-
docs/development.rst | 3 +
docs/other/ssl-certificate-validation.rst | 9 +
libcloud/data/pricing.json | 260 ++++++++++---------
libcloud/dns/drivers/auroradns.py | 2 +-
libcloud/test/backup/test_dimensiondata.py | 13 +-
libcloud/test/common/test_retry_limit.py | 15 ++
libcloud/test/compute/test_dimensiondata.py | 59 ++---
libcloud/test/dns/test_auroradns.py | 63 +++++
.../test/loadbalancer/test_dimensiondata.py | 13 +-
libcloud/test/secrets.py-dist | 1 +
libcloud/utils/misc.py | 96 ++++---
12 files changed, 328 insertions(+), 223 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/104cdb15/CHANGES.rst
----------------------------------------------------------------------
diff --cc CHANGES.rst
index d14076c,c5ee099..68aa8de
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@@ -7,11 -7,8 +7,13 @@@ Changes with current version of Apache
General
~~~~~~~
+- Introduction of container based drivers for Docker, Rkt and Container-as-a-service
+ providers
+ (LIBCLOUD-781, GITHUB-666)
++ [Anthony Shaw]
+
- - Introduced a Backup API driver
+ - Introduce a new ``libcloud.backup`` API for Backup as a Service projects and
+ products.
(GITHUB-621)
[Anthony Shaw]
@@@ -31,8 -33,16 +38,16 @@@ Comput
(GITHUB-664)
[Anthony Shaw]
+ DNS
+ ~~~
+
+ - Make sure ``ttl`` attribute is correctly parsed and added to the ``Record``
+ ``extra`` dictionary.
+ (GITHUB-675)
+ [Wido den Hollander]
+
Changes with Apache Libcloud 0.20.0
------------------------------------
+-------------------------------------------
General
~~~~~~~
http://git-wip-us.apache.org/repos/asf/libcloud/blob/104cdb15/libcloud/test/secrets.py-dist
----------------------------------------------------------------------
diff --cc libcloud/test/secrets.py-dist
index 608fdbd,dfc7a5b..230cef0
--- a/libcloud/test/secrets.py-dist
+++ b/libcloud/test/secrets.py-dist
@@@ -80,7 -80,4 +80,8 @@@ DNS_PARAMS_ZONOMI = ('key'
DNS_PARAMS_DURABLEDNS = ('api_user', 'api_key')
DNS_PARAMS_GODADDY = ('customer-id', 'api_user', 'api_key')
DNS_PARAMS_CLOUDFLARE = ('user@example.com', 'key')
+ DNS_PARAMS_AURORADNS = ('apikey', 'secretkey')
+
+# Container
+CONTAINER_PARAMS_DOCKER = ('user', 'password')
+CONTAINER_PARAMS_ECS = ('user', 'password', 'region')
[31/50] libcloud git commit: Fixes to docs and merge tags
Posted by an...@apache.org.
Fixes to docs and merge tags
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/0aec8515
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0aec8515
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0aec8515
Branch: refs/heads/trunk
Commit: 0aec8515047fd4776d0c5be8fe37b8d96aaf16e7
Parents: f909e6b
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Jan 6 21:45:53 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Jan 6 21:45:53 2016 +1100
----------------------------------------------------------------------
contrib/generate_provider_feature_matrix_table.py | 4 +---
docs/examples/container/docker/deploy_container.py | 2 +-
2 files changed, 2 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0aec8515/contrib/generate_provider_feature_matrix_table.py
----------------------------------------------------------------------
diff --git a/contrib/generate_provider_feature_matrix_table.py b/contrib/generate_provider_feature_matrix_table.py
index 43e6bfb..5bdcf32 100755
--- a/contrib/generate_provider_feature_matrix_table.py
+++ b/contrib/generate_provider_feature_matrix_table.py
@@ -45,17 +45,15 @@ from libcloud.dns.providers import get_driver as get_dns_driver
from libcloud.dns.providers import DRIVERS as DNS_DRIVERS
from libcloud.dns.types import Provider as DNSProvider
-<<<<<<< HEAD
from libcloud.container.base import ContainerDriver
from libcloud.container.providers import get_driver as get_container_driver
from libcloud.container.providers import DRIVERS as CONTAINER_DRIVERS
from libcloud.container.types import Provider as ContainerProvider
-=======
+
from libcloud.backup.base import BackupDriver
from libcloud.backup.providers import get_driver as get_backup_driver
from libcloud.backup.providers import DRIVERS as BACKUP_DRIVERS
from libcloud.backup.types import Provider as BackupProvider
->>>>>>> trunk
REQUIRED_DEPENDENCIES = [
'pysphere'
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0aec8515/docs/examples/container/docker/deploy_container.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/docker/deploy_container.py b/docs/examples/container/docker/deploy_container.py
index 7d643c2..7c59dc2 100644
--- a/docs/examples/container/docker/deploy_container.py
+++ b/docs/examples/container/docker/deploy_container.py
@@ -4,7 +4,7 @@ from libcloud.container.providers import get_driver
cls = get_driver(Provider.DOCKER)
driver = cls(host='https://198.61.239.128', port=4243,
- key_file='key.pem', cert_file='cert.pem')
+ key_file='key.pem', cert_file='cert.pem')
image = driver.install_image('tomcat:8.0')
container = driver.deploy_container('tomcat', image)
[43/50] libcloud git commit: Docker hub root paths were incorrect,
also include content-type headers just incase.
Posted by an...@apache.org.
Docker hub root paths were incorrect, also include content-type headers just incase.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/a3ed405e
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/a3ed405e
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/a3ed405e
Branch: refs/heads/trunk
Commit: a3ed405e7b5ec32d0d42bdf00bfca5cc600c424f
Parents: 621ec71
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Jan 11 15:51:43 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Jan 11 15:51:43 2016 +1100
----------------------------------------------------------------------
libcloud/container/utils/docker.py | 33 +++++++++++++++--------
libcloud/test/container/test_docker_utils.py | 14 +++-------
2 files changed, 25 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3ed405e/libcloud/container/utils/docker.py
----------------------------------------------------------------------
diff --git a/libcloud/container/utils/docker.py b/libcloud/container/utils/docker.py
index a8a544a..ba83097 100644
--- a/libcloud/container/utils/docker.py
+++ b/libcloud/container/utils/docker.py
@@ -29,12 +29,23 @@ __all__ = [
class DockerHubConnection(Connection):
responseCls = JsonResponse
- def __init__(self, host, username=None, password=None, **kwargs):
- super(DockerHubConnection, self).__init__(host=host, **kwargs)
+ def __init__(self, host, username=None, password=None,
+ secure=True,
+ port=None, url=None, timeout=None,
+ proxy_url=None, backoff=None, retry_delay=None):
+ super(DockerHubConnection, self).__init__(
+ secure=secure, host=host,
+ port=port, url=url,
+ timeout=timeout,
+ proxy_url=proxy_url,
+ backoff=backoff,
+ retry_delay=retry_delay
+ )
self.username = username
self.password = password
def add_default_headers(self, headers):
+ headers['Content-Type'] = 'application/json'
if self.username is not None:
authstr = 'Basic ' + str(
b64encode(
@@ -63,10 +74,10 @@ class RegistryClient(object):
:param password: (optional) Your hub account password
:type password: ``str``
"""
- self.connection = DockerHubConnection(host,
- username,
- password,
- **kwargs)
+ self.connection = self.connectionCls(host,
+ username,
+ password,
+ **kwargs)
def list_images(self, repository_name, namespace='library', max_count=100):
"""
@@ -84,7 +95,7 @@ class RegistryClient(object):
:return: A list of images
:rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
"""
- path = 'v2/repositories/%s/%s/tags/?page=1&page_size=%s' \
+ path = '/v2/repositories/%s/%s/tags/?page=1&page_size=%s' \
% (namespace, repository_name, max_count)
response = self.connection.request(path)
images = []
@@ -105,7 +116,7 @@ class RegistryClient(object):
:return: The details of the repository
:rtype: ``object``
"""
- path = 'v2/repositories/%s/%s' % (namespace, repository_name)
+ path = '/v2/repositories/%s/%s' % (namespace, repository_name)
response = self.connection.request(path)
return response.object
@@ -125,7 +136,7 @@ class RegistryClient(object):
:return: A container image
:rtype: :class:`libcloud.container.base.ContainerImage`
"""
- path = 'v2/repositories/%s/%s/tags/%s' \
+ path = '/v2/repositories/%s/%s/tags/%s' \
% (namespace, repository_name, tag)
response = self.connection.request(path)
return self._to_image(repository_name, response.object)
@@ -164,5 +175,5 @@ class HubClient(RegistryClient):
:param password: (optional) Your hub account password
:type password: ``str``
"""
- self.connection = DockerHubConnection(self.host, username,
- password, **kwargs)
+ super(HubClient, self).__init__(self.host, username,
+ password, **kwargs)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3ed405e/libcloud/test/container/test_docker_utils.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_docker_utils.py b/libcloud/test/container/test_docker_utils.py
index d209447..8c8bd90 100644
--- a/libcloud/test/container/test_docker_utils.py
+++ b/libcloud/test/container/test_docker_utils.py
@@ -50,15 +50,7 @@ class DockerUtilitiesTestCase(unittest.TestCase):
class DockerMockHttp(MockHttp):
fixtures = ContainerFileFixtures('docker_utils')
- def _version(
- self, method, url, body, headers):
- if method == 'GET':
- body = self.fixtures.load('version.json')
- else:
- raise AssertionError('Unsupported method')
- return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
- def v2_repositories_library_ubuntu_tags_latest(
+ def _v2_repositories_library_ubuntu_tags_latest(
self, method, url, body, headers):
if method == 'GET':
body = self.fixtures.load('v2_repositories_library_ubuntu_tags_latest.json')
@@ -66,7 +58,7 @@ class DockerMockHttp(MockHttp):
raise AssertionError('Unsupported method')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
- def v2_repositories_library_ubuntu_tags(
+ def _v2_repositories_library_ubuntu_tags(
self, method, url, body, headers):
if method == 'GET':
body = self.fixtures.load('v2_repositories_library_ubuntu_tags.json')
@@ -74,7 +66,7 @@ class DockerMockHttp(MockHttp):
raise AssertionError('Unsupported method')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
- def v2_repositories_library_ubuntu(
+ def _v2_repositories_library_ubuntu(
self, method, url, body, headers):
if method == 'GET':
body = self.fixtures.load('v2_repositories_library_ubuntu.json')
[07/50] libcloud git commit: Adding comments and additional
explanation to the docker driver.
Posted by an...@apache.org.
Adding comments and additional explanation to the docker driver.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/6a4a772c
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/6a4a772c
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/6a4a772c
Branch: refs/heads/trunk
Commit: 6a4a772c88ce7667fc52ca8f1d71f4ec3121da56
Parents: 8e749b5
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Dec 23 19:28:42 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Dec 23 19:28:42 2015 +1100
----------------------------------------------------------------------
libcloud/container/drivers/docker.py | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/6a4a772c/libcloud/container/drivers/docker.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/docker.py b/libcloud/container/drivers/docker.py
index 3e456d5..9d60d20 100644
--- a/libcloud/container/drivers/docker.py
+++ b/libcloud/container/drivers/docker.py
@@ -28,6 +28,7 @@ from libcloud.utils.py3 import b
from libcloud.common.base import JsonResponse, ConnectionUserAndKey
from libcloud.common.types import InvalidCredsError
+
from libcloud.container.base import (Container, ContainerDriver,
ContainerImage)
@@ -121,7 +122,7 @@ class DockerContainerDriver(ContainerDriver):
connect with tls authentication, by providing a hostname, port, a private
key file (.pem) and certificate (.pem) file
>>> conn = driver(host='https://198.61.239.128',
- port=4243, key_file='key.pem', cert_file='cert.pem')
+ >>> port=4243, key_file='key.pem', cert_file='cert.pem')
"""
type = Provider.DOCKER
@@ -132,7 +133,31 @@ class DockerContainerDriver(ContainerDriver):
def __init__(self, key=None, secret=None, secure=False, host='localhost',
port=4243, key_file=None, cert_file=None):
+ """
+ :param key: API key or username to used (required)
+ :type key: ``str``
+
+ :param secret: Secret password to be used (required)
+ :type secret: ``str``
+
+ :param secure: Whether to use HTTPS or HTTP. Note: Some providers
+ only support HTTPS, and it is on by default.
+ :type secure: ``bool``
+
+ :param host: Override hostname used for connections.
+ :type host: ``str``
+ :param port: Override port used for connections.
+ :type port: ``int``
+
+ :param key_file: Path to private key for TLS connection (optional)
+ :type key_file: ``str``
+
+ :param cert_file: Path to public key for TLS connection (optional)
+ :type cert_file: ``str``
+
+ :return: ``None``
+ """
super(DockerContainerDriver, self).__init__(key=key, secret=secret,
secure=secure, host=host,
port=port,
@@ -271,6 +296,8 @@ class DockerContainerDriver(ContainerDriver):
"""
Deploy an installed container image
+ For details on the additional parameters see : http://bit.ly/1PjMVKV
+
:param name: The name of the new container
:type name: ``str``
@@ -599,7 +626,7 @@ class DockerContainerDriver(ContainerDriver):
id=data['Id'],
name=name,
image=ContainerImage(
- id=None,
+ id=data.get('ImageID', None),
path=image,
name=image,
version=None,
[25/50] libcloud git commit: Updated docs to fix warning about
duplicate key
Posted by an...@apache.org.
Updated docs to fix warning about duplicate key
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/92744501
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/92744501
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/92744501
Branch: refs/heads/trunk
Commit: 92744501078ff22bf55610b42b05801049d5ad09
Parents: c247ea8
Author: anthony-shaw <an...@gmail.com>
Authored: Sun Jan 3 21:17:51 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sun Jan 3 21:17:51 2016 +1100
----------------------------------------------------------------------
docs/container/_supported_providers.rst | 2 +-
docs/container/drivers/joyent.rst | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/92744501/docs/container/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_providers.rst b/docs/container/_supported_providers.rst
index da86a80..114af32 100644
--- a/docs/container/_supported_providers.rst
+++ b/docs/container/_supported_providers.rst
@@ -4,7 +4,7 @@
Provider Documentation Provider constant Module Class Name
=================================== ======================================== ================= ======================================== ===============================
`Docker`_ :doc:`Click </container/drivers/docker>` DOCKER :mod:`libcloud.container.drivers.docker` :class:`DockerContainerDriver`
-`Amazon Elastic Container Service`_ ECS :mod:`libcloud.container.drivers.ecs` :class:`ElasticContainerDriver`
+`Amazon Elastic Container Service`_ :doc:`Click </container/drivers/ecs>` ECS :mod:`libcloud.container.drivers.ecs` :class:`ElasticContainerDriver`
`Joyent`_ :doc:`Click </container/drivers/joyent>` JOYENT :mod:`libcloud.container.drivers.joyent` :class:`JoyentContainerDriver`
=================================== ======================================== ================= ======================================== ===============================
http://git-wip-us.apache.org/repos/asf/libcloud/blob/92744501/docs/container/drivers/joyent.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/joyent.rst b/docs/container/drivers/joyent.rst
index 776ac93..a8b29d3 100644
--- a/docs/container/drivers/joyent.rst
+++ b/docs/container/drivers/joyent.rst
@@ -1,7 +1,7 @@
Joyent Triton Container Driver Documentation
============================================
-`Joyent Triton`_ is a Docker hosting service, provided by service provider `Joyent`_.
+`Joyent Triton`_ is a Docker hosting service, provided by service provider Joyent.
Docker-native tools and elastic hosts make deploying on Triton as easy as running Docker on your laptop.
There is no special software to install or configure.
Mix Docker containers with container-native Linux to extend the benefits of containerization to legacy applications and stateful services.
@@ -62,4 +62,3 @@ API Docs
.. _`Joyent Triton`: https://www.joyent.com/blog/understanding-triton-containers
-.. _`Joyent`: https://www.joyent.com/
\ No newline at end of file
[21/50] libcloud git commit: removed local junk from example code,
included real fixtures from actual API
Posted by an...@apache.org.
removed local junk from example code, included real fixtures from actual API
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/4bde5af3
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/4bde5af3
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/4bde5af3
Branch: refs/heads/trunk
Commit: 4bde5af3e2ead0e81763805eadeacc0451f334f2
Parents: 9507a63
Author: anthony-shaw <an...@gmail.com>
Authored: Sun Jan 3 20:50:43 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sun Jan 3 20:50:43 2016 +1100
----------------------------------------------------------------------
.../container/ecs/instantiate_driver.py | 10 +--
.../container/fixtures/ecs/describetasks.json | 75 +++++++++-----------
libcloud/test/container/test_ecs.py | 10 +--
3 files changed, 42 insertions(+), 53 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/4bde5af3/docs/examples/container/ecs/instantiate_driver.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/ecs/instantiate_driver.py b/docs/examples/container/ecs/instantiate_driver.py
index a854745..19400db 100644
--- a/docs/examples/container/ecs/instantiate_driver.py
+++ b/docs/examples/container/ecs/instantiate_driver.py
@@ -1,12 +1,12 @@
from libcloud.container.types import Provider
from libcloud.container.providers import get_driver
-import libcloud.security
-libcloud.security.VERIFY_SSL_CERT = False
-
cls = get_driver(Provider.ECS)
conn = cls(access_id='AKIAI7OR4GWEEPRIFBBA', secret='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', region='ap-southeast-2')
-conn.connection.set_http_proxy(proxy_url='http://localhost:8888')
-print(conn.list_containers())
+for container in conn.list_containers():
+ print(container.name)
+
+for cluster in conn.list_clusters():
+ print(cluster.name)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/4bde5af3/libcloud/test/container/fixtures/ecs/describetasks.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/describetasks.json b/libcloud/test/container/fixtures/ecs/describetasks.json
index d8e0624..1dd5f1b 100644
--- a/libcloud/test/container/fixtures/ecs/describetasks.json
+++ b/libcloud/test/container/fixtures/ecs/describetasks.json
@@ -1,46 +1,35 @@
{
- "failures": [],
- "tasks": [
- {
- "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/default",
- "containerInstanceArn": "arn:aws:ecs:us-east-1:012345678910:container-instance/84818520-995f-4d94-9d70-7714bacc2953",
- "containers": [
- {
- "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/76c980a8-2454-4a9c-acc4-9eb103117273",
- "lastStatus": "RUNNING",
- "name": "mysql",
- "networkBindings": [],
- "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe"
- },
- {
- "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/e3c69b8f-f15e-4d33-8093-282c2d2325e9",
- "lastStatus": "RUNNING",
- "name": "wordpress",
- "networkBindings": [
- {
- "bindIP": "0.0.0.0",
- "containerPort": 80,
- "hostPort": 80
- }
- ],
- "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe"
+ "failures": [],
+ "tasks": [{
+ "clusterArn": "arn:aws:ecs:ap-southeast-2:647433528374:cluster/default",
+ "containerInstanceArn": "arn:aws:ecs:ap-southeast-2:647433528374:container-instance/13b83f4b-d557-48a6-a4d7-2b0e8068e62b",
+ "containers": [{
+ "containerArn": "arn:aws:ecs:ap-southeast-2:647433528374:container/d56d4e2c-9804-42a7-9f2a-6029cb50d4a2",
+ "lastStatus": "RUNNING",
+ "name": "simple-app",
+ "networkBindings": [{
+ "bindIP": "0.0.0.0",
+ "containerPort": 80,
+ "hostPort": 80,
+ "protocol": "tcp"
+ }
+ ],
+ "taskArn": "arn:aws:ecs:ap-southeast-2:647433528374:task/c15bcab8-39e6-4c28-a47d-27b433269e5c"
+ }
+ ],
+ "createdAt": 1.451468104403E9,
+ "desiredStatus": "RUNNING",
+ "lastStatus": "RUNNING",
+ "overrides": {
+ "containerOverrides": [{
+ "name": "simple-app"
+ }
+ ]
+ },
+ "startedAt": 1.45146812139E9,
+ "startedBy": "ecs-svc/9223370585386692588",
+ "taskArn": "arn:aws:ecs:ap-southeast-2:647433528374:task/c15bcab8-39e6-4c28-a47d-27b433269e5c",
+ "taskDefinitionArn": "arn:aws:ecs:ap-southeast-2:647433528374:task-definition/console-sample-app-static:1"
}
- ],
- "desiredStatus": "RUNNING",
- "lastStatus": "RUNNING",
- "overrides": {
- "containerOverrides": [
- {
- "name": "mysql"
- },
- {
- "name": "wordpress"
- }
- ]
- },
- "startedBy": "ecs-svc/9223370606521064774",
- "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe",
- "taskDefinitionArn": "arn:aws:ecs:us-east-1:012345678910:task-definition/hello_world:10"
- }
- ]
+ ]
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/4bde5af3/libcloud/test/container/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_ecs.py b/libcloud/test/container/test_ecs.py
index 86b715e..f0e8937 100644
--- a/libcloud/test/container/test_ecs.py
+++ b/libcloud/test/container/test_ecs.py
@@ -55,12 +55,12 @@ class ElasticContainerDriverTestCase(unittest.TestCase):
def test_list_containers(self):
containers = self.driver.list_containers()
- self.assertEqual(len(containers), 2)
+ self.assertEqual(len(containers), 1)
def test_list_containers_for_cluster(self):
cluster = self.driver.list_clusters()[0]
containers = self.driver.list_containers(cluster=cluster)
- self.assertEqual(len(containers), 2)
+ self.assertEqual(len(containers), 1)
def test_deploy_container(self):
container = self.driver.deploy_container(
@@ -79,9 +79,9 @@ class ElasticContainerDriverTestCase(unittest.TestCase):
container = self.driver.get_container(
'arn:aws:ecs:us-east-1:012345678910:container/76c980a8-2454-4a9c-acc4-9eb103117273'
)
- self.assertEqual(container.id, 'arn:aws:ecs:us-east-1:012345678910:container/76c980a8-2454-4a9c-acc4-9eb103117273')
- self.assertEqual(container.name, 'mysql')
- self.assertEqual(container.image.name, 'mysql')
+ self.assertEqual(container.id, 'arn:aws:ecs:ap-southeast-2:647433528374:container/d56d4e2c-9804-42a7-9f2a-6029cb50d4a2')
+ self.assertEqual(container.name, 'simple-app')
+ self.assertEqual(container.image.name, 'simple-app')
def test_start_container(self):
container = self.driver.start_container(
[30/50] libcloud git commit: Merge branch 'trunk' into
LIBCLOUD-781_containers
Posted by an...@apache.org.
Merge branch 'trunk' into LIBCLOUD-781_containers
# Conflicts:
# CHANGES.rst
# contrib/generate_provider_feature_matrix_table.py
# docs/index.rst
# docs/supported_providers.rst
# libcloud/test/file_fixtures.py
# setup.py
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/f909e6b3
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/f909e6b3
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/f909e6b3
Branch: refs/heads/trunk
Commit: f909e6b33ab5ac52303259d358c364b5e306684c
Parents: db7d8f0 9a7556f
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Jan 6 21:39:33 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Jan 6 21:39:33 2016 +1100
----------------------------------------------------------------------
.travis.yml | 2 +-
CHANGES.rst | 19 +
.../generate_provider_feature_matrix_table.py | 35 +-
.../images/provider_logos/cloudflare.png | Bin 0 -> 19863 bytes
docs/backup/_supported_methods.rst | 13 +
docs/backup/_supported_providers.rst | 13 +
docs/backup/api.rst | 22 +
docs/backup/drivers/dimensiondata.rst | 66 +++
docs/backup/drivers/index.rst | 12 +
docs/backup/examples.rst | 16 +
docs/backup/index.rst | 40 ++
docs/backup/supported_providers.rst | 14 +
docs/conf.py | 9 +-
docs/dns/_supported_providers.rst | 2 +-
docs/dns/drivers/cloudflare.rst | 30 ++
docs/examples/backup/create_backup_from_node.py | 41 ++
.../dns/cloudflare/instantiate_driver.py | 5 +
docs/index.rst | 4 +
docs/supported_providers.rst | 28 +-
libcloud/backup/__init__.py | 0
libcloud/backup/base.py | 489 +++++++++++++++++++
libcloud/backup/drivers/__init__.py | 0
libcloud/backup/drivers/dimensiondata.py | 487 ++++++++++++++++++
libcloud/backup/drivers/dummy.py | 41 ++
libcloud/backup/drivers/ebs.py | 422 ++++++++++++++++
libcloud/backup/drivers/gce.py | 478 ++++++++++++++++++
libcloud/backup/providers.py | 37 ++
libcloud/backup/types.py | 63 +++
libcloud/common/base.py | 35 ++
libcloud/compute/drivers/dimensiondata.py | 11 +-
libcloud/compute/drivers/gce.py | 63 ++-
libcloud/loadbalancer/drivers/dimensiondata.py | 10 +-
libcloud/test/backup/__init__.py | 36 ++
...745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml | 49 ++
...ead52_692f_4314_8725_c8a4f4d13a87_backup.xml | 18 +
...8a4f4d13a87_backup_client_schedulePolicy.xml | 5 +
...c8a4f4d13a87_backup_client_storagePolicy.xml | 6 +
...314_8725_c8a4f4d13a87_backup_client_type.xml | 6 +
...92f_4314_8725_c8a4f4d13a87_backup_modify.xml | 7 +
.../dimensiondata/oec_0_9_myaccount.xml | 26 +
libcloud/test/backup/test_base.py | 29 ++
libcloud/test/backup/test_dimensiondata.py | 159 ++++++
libcloud/test/common/test_base.py | 44 ++
libcloud/test/file_fixtures.py | 12 +-
setup.py | 6 +-
tox.ini | 12 +-
46 files changed, 2866 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f909e6b3/CHANGES.rst
----------------------------------------------------------------------
diff --cc CHANGES.rst
index c14ce78,3270266..d14076c
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@@ -7,9 -7,24 +7,28 @@@ Changes with current version of Apache
General
~~~~~~~
+- Introduction of container based drivers for Docker, Rkt and Container-as-a-service
+ providers
+ (LIBCLOUD-781, GITHUB-666)
++
+ - Introduced a Backup API driver
+ (GITHUB-621)
+ [Anthony Shaw]
+
+ Compute
+ ~~~~~~~
+
+ - Add LazyObject class that provides lazy-loading, see `GCELicense` for usage
+ (LIBCLOUD-786, GITHUB-665)
+ [Scott Crunkleton]
+
+ - Added t2.nano instance type to EC2 Compute driver
+ (GITHUB-663)
+ [Anthony Shaw]
+
+ - Support for passing the image ID as a string instead of an instance of image when
+ creating nodes in Dimension Data driver.
+ (GITHUB-664)
[Anthony Shaw]
Changes with Apache Libcloud 0.20.0
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f909e6b3/contrib/generate_provider_feature_matrix_table.py
----------------------------------------------------------------------
diff --cc contrib/generate_provider_feature_matrix_table.py
index f5ccb2c,b806434..43e6bfb
--- a/contrib/generate_provider_feature_matrix_table.py
+++ b/contrib/generate_provider_feature_matrix_table.py
@@@ -45,10 -45,10 +45,17 @@@ from libcloud.dns.providers import get_
from libcloud.dns.providers import DRIVERS as DNS_DRIVERS
from libcloud.dns.types import Provider as DNSProvider
++<<<<<<< HEAD
+from libcloud.container.base import ContainerDriver
+from libcloud.container.providers import get_driver as get_container_driver
+from libcloud.container.providers import DRIVERS as CONTAINER_DRIVERS
+from libcloud.container.types import Provider as ContainerProvider
++=======
+ from libcloud.backup.base import BackupDriver
+ from libcloud.backup.providers import get_driver as get_backup_driver
+ from libcloud.backup.providers import DRIVERS as BACKUP_DRIVERS
+ from libcloud.backup.types import Provider as BackupProvider
++>>>>>>> trunk
REQUIRED_DEPENDENCIES = [
'pysphere'
@@@ -94,11 -94,10 +101,15 @@@ BASE_API_METHODS =
'dns': ['list_zones', 'list_records', 'iterate_zones', 'iterate_records',
'create_zone', 'update_zone', 'create_record', 'update_record',
'delete_zone', 'delete_record'],
+ 'container': ['install_image', 'list_images', 'deploy_container',
+ 'get_container', 'start_container', 'stop_container',
+ 'restart_container', 'destroy_container', 'list_containers',
+ 'list_locations', 'create_cluster', 'destroy_cluster',
- 'list_clusters']
++ 'list_clusters'],
+ 'backup': ['get_supported_target_types', 'list_targets', 'create_target', 'create_target_from_node',
+ 'create_target_from_storage_container', 'update_target', 'delete_target', 'list_recovery_points',
+ 'recover_target', 'recover_target_out_of_place', 'list_target_jobs', 'create_target_job',
+ 'resume_target_job', 'suspend_target_job', 'cancel_target_job']
}
FRIENDLY_METHODS_NAMES = {
@@@ -170,21 -169,23 +181,38 @@@
'delete_zone': 'delete zone',
'delete_record': 'delete record'
},
+ 'container': {
+ 'install_image': 'install image',
+ 'list_images': 'list images',
+ 'deploy_container': 'deploy container',
+ 'get_container': 'get container',
+ 'list_containers': 'list containers',
+ 'start_container': 'start container',
+ 'stop_container': 'stop container',
+ 'restart_container': 'restart container',
+ 'destroy_container': 'destroy container',
+ 'list_locations': 'list locations',
+ 'create_cluster': 'create cluster',
+ 'destroy_cluster': 'destroy cluster',
+ 'list_clusters': 'list clusters'
++ },
+ 'backup': {
+ 'get_supported_target_types': 'get supported target types',
+ 'list_targets': 'list targets',
+ 'create_target': 'create target',
+ 'create_target_from_node': 'create target from node',
+ 'create_target_from_storage_container': 'create target from storage container',
+ 'update_target': 'update target',
+ 'delete_target': 'delete target',
+ 'list_recovery_points': 'list recovery points',
+ 'recover_target': 'recover target',
+ 'recover_target_out_of_place': 'recover target out of place',
+ 'list_target_jobs': 'list target jobs',
+ 'create_target_job': 'create target job',
+ 'resume_target_job': 'resume target job',
+ 'suspend_target_job': 'suspend target job',
+ 'cancel_target_job': 'cancel target job'
- },
+ }
}
IGNORED_PROVIDERS = [
@@@ -228,11 -229,11 +256,16 @@@ def generate_providers_table(api)
drivers = DNS_DRIVERS
provider = DNSProvider
get_driver_method = get_dns_driver
+ elif api == 'container':
+ driver = ContainerDriver
+ drivers = CONTAINER_DRIVERS
+ provider = ContainerProvider
+ get_driver_method = get_container_driver
+ elif api == 'backup':
+ driver = BackupDriver
+ drivers = BACKUP_DRIVERS
+ provider = BackupProvider
+ get_driver_method = get_backup_driver
else:
raise Exception('Invalid api: %s' % (api))
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f909e6b3/docs/conf.py
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f909e6b3/docs/index.rst
----------------------------------------------------------------------
diff --cc docs/index.rst
index 6c0c7fc,929151c..aeba4a1
--- a/docs/index.rst
+++ b/docs/index.rst
@@@ -13,7 -13,8 +13,10 @@@ Resource you can manage with Libcloud a
Rackspace CloudFiles
* :doc:`Load Balancers as a Service </loadbalancer/index>` - services such as Amazon Elastic Load Balancer and GoGrid LoadBalancers
* :doc:`DNS as a Service </dns/index>` - services such as Amazon Route 53 and Zerigo
+* :doc:`Container Services </container/index>` - container virtualization like Docker and Rkt as well as container based services
+ * :doc:`Backup as a Service </backup/index>` - services such as Amazon EBS and OpenStack Freezer
+
++>>>>>>> trunk
.. figure:: /_static/images/supported_providers.png
:align: center
@@@ -37,7 -38,7 +40,8 @@@ Mai
storage/index
loadbalancer/index
dns/index
+ container/index
+ backup/index
troubleshooting
api_docs
faq
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f909e6b3/docs/supported_providers.rst
----------------------------------------------------------------------
diff --cc docs/supported_providers.rst
index 756d4d1,f4735e6..f7f2464
--- a/docs/supported_providers.rst
+++ b/docs/supported_providers.rst
@@@ -57,29 -57,28 +57,41 @@@ Supported Methods (CDN
.. include:: storage/_supported_methods_cdn.rst
--DNS
-----
++Container
++---------
Provider Matrix
~~~~~~~~~~~~~~~
--.. include:: dns/_supported_providers.rst
++.. include:: container/_supported_providers.rst
Supported Methods
~~~~~~~~~~~~~~~~~
--.. include:: dns/_supported_methods.rst
++.. include:: container/_supported_methods.rst
+ Backup
----
++------
- Container
- ---------
+ Provider Matrix
+ ~~~~~~~~~~~~~~~
+
+ .. include:: backup/_supported_providers.rst
+
+ Supported Methods
+ ~~~~~~~~~~~~~~~~~
+
-.. include:: backup/_supported_methods.rst
++.. include:: backup/_supported_methods.rst
++
++DNS
++---
+
+Provider Matrix
+~~~~~~~~~~~~~~~
+
- .. include:: container/_supported_providers.rst
++.. include:: dns/_supported_providers.rst
+
+Supported Methods
+~~~~~~~~~~~~~~~~~
+
- .. include:: container/_supported_methods.rst
++.. include:: dns/_supported_methods.rst
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f909e6b3/libcloud/common/base.py
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f909e6b3/libcloud/test/file_fixtures.py
----------------------------------------------------------------------
diff --cc libcloud/test/file_fixtures.py
index 8b5b343,60d4358..59f8e2e
--- a/libcloud/test/file_fixtures.py
+++ b/libcloud/test/file_fixtures.py
@@@ -27,8 -27,8 +27,9 @@@ FIXTURES_ROOT =
'storage': 'storage/fixtures',
'loadbalancer': 'loadbalancer/fixtures',
'dns': 'dns/fixtures',
+ 'backup': 'backup/fixtures',
'openstack': 'compute/fixtures/openstack',
+ 'container': 'container/fixtures'
}
@@@ -83,7 -84,7 +85,13 @@@ class OpenStackFixtures(FileFixtures)
sub_dir=sub_dir)
+class ContainerFileFixtures(FileFixtures):
+ def __init__(self, sub_dir=''):
+ super(ContainerFileFixtures, self).__init__(fixtures_type='container',
+ sub_dir=sub_dir)
++
++
+ class BackupFileFixtures(FileFixtures):
+ def __init__(self, sub_dir=''):
+ super(BackupFileFixtures, self).__init__(fixtures_type='backup',
+ sub_dir=sub_dir)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f909e6b3/setup.py
----------------------------------------------------------------------
diff --cc setup.py
index 1ea444a,7daac52..e8cc1bf
--- a/setup.py
+++ b/setup.py
@@@ -48,11 -48,11 +48,13 @@@ HTML_VIEWSOURCE_BASE = 'https://svn.apa
PROJECT_BASE_DIR = 'http://libcloud.apache.org'
TEST_PATHS = ['libcloud/test', 'libcloud/test/common', 'libcloud/test/compute',
'libcloud/test/storage', 'libcloud/test/loadbalancer',
- 'libcloud/test/dns', 'libcloud/test/container']
- 'libcloud/test/dns', 'libcloud/test/backup']
++ 'libcloud/test/dns', 'libcloud/test/container',
++ 'libcloud/test/backup']
DOC_TEST_MODULES = ['libcloud.compute.drivers.dummy',
'libcloud.storage.drivers.dummy',
'libcloud.dns.drivers.dummy',
- 'libcloud.container.drivers.dummy']
++ 'libcloud.container.drivers.dummy',
+ 'libcloud.backup.drivers.dummy']
SUPPORTED_VERSIONS = ['2.5', '2.6', '2.7', 'PyPy', '3.x']
[16/50] libcloud git commit: Further implementation details to the
ECS driver
Posted by an...@apache.org.
Further implementation details to the ECS driver
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/a1adaae2
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/a1adaae2
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/a1adaae2
Branch: refs/heads/trunk
Commit: a1adaae2df83ec7731a64eccbbcdbebd163a875e
Parents: f4c1e2e
Author: anthony-shaw <an...@gmail.com>
Authored: Tue Dec 29 21:57:57 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Tue Dec 29 21:57:57 2015 +1100
----------------------------------------------------------------------
libcloud/container/base.py | 1 +
libcloud/container/drivers/ecs.py | 157 +++++++++++++++----
.../test/container/fixtures/ecs/listtasks.json | 8 +
.../fixtures/ecs/registertaskdefinition.json | 26 +++
.../test/container/fixtures/ecs/runtask.json | 37 +++++
.../test/container/fixtures/ecs/stoptask.json | 42 +++++
libcloud/test/container/test_ecs.py | 79 +++++++++-
7 files changed, 317 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a1adaae2/libcloud/container/base.py
----------------------------------------------------------------------
diff --git a/libcloud/container/base.py b/libcloud/container/base.py
index b9750d4..48ee573 100644
--- a/libcloud/container/base.py
+++ b/libcloud/container/base.py
@@ -22,6 +22,7 @@ __all__ = [
'Container',
'ContainerImage',
'ContainerCluster',
+ 'ClusterLocation',
'ContainerDriver'
]
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a1adaae2/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index e3a356f..9aa98d3 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -71,7 +71,6 @@ class ElasticContainerDriver(ContainerDriver):
params = {'Action': 'DescribeClusters'}
data = self.connection.request(
ROOT,
- params=params,
headers=self._get_headers(params['Action'])
).object
return self._to_clusters(data)
@@ -92,7 +91,6 @@ class ElasticContainerDriver(ContainerDriver):
request = {'clusterName': name}
response = self.connection.request(
ROOT,
- params=params,
data=request,
headers=self._get_headers(params['Action'])
).object
@@ -109,7 +107,6 @@ class ElasticContainerDriver(ContainerDriver):
request = {'cluster': cluster.id}
data = self.connection.request(
ROOT,
- params=params,
data=request,
headers=self._get_headers(params['Action'])
).object
@@ -129,7 +126,8 @@ class ElasticContainerDriver(ContainerDriver):
def list_images(self):
"""
- List the installed container images
+ List the installed container images, in ECS these are
+ equivalent to the containers within task definitions.
:rtype: ``list`` of :class:`ContainerImage`
"""
@@ -148,25 +146,26 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: ``list`` of :class:`Container`
"""
- params = {'Action': 'DescribeTasks'}
request = None
if cluster is not None:
request = {'cluster': cluster.id}
- response = self.connection.request(
+ if image is not None:
+ request['family'] = image.name
+ list_response = self.connection.request(
ROOT,
- params=params,
data=request,
- headers=self._get_headers(params['Action'])
+ headers=self._get_headers('ListTasks')
).object
- containers = []
- for task in response['tasks']:
- containers.extend(self._to_containers(task))
+ containers = self.ex_list_containers_for_task(
+ list_response['taskArns'])
return containers
def deploy_container(self, name, image, cluster=None,
- parameters=None, start=True):
+ parameters=None, start=True, ex_cpu=10, ex_memory=500,
+ ex_container_port=None, ex_host_port=None):
"""
- Deploy an installed container image
+ Creates a task definition from a container image that can be run
+ in a cluster.
:param name: The name of the new container
:type name: ``str``
@@ -185,8 +184,47 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: :class:`Container`
"""
- raise NotImplementedError(
- 'deploy_container not implemented for this driver')
+ data = {}
+ data['containerDefinitions'] = [
+ {
+ "mountPoints": [],
+ "name": name,
+ "image": image.name,
+ "cpu": ex_cpu,
+ "environment": [],
+ "memory": ex_memory,
+ "portMappings": [
+ {
+ "containerPort": ex_container_port,
+ "hostPort": ex_host_port
+ }
+ ],
+ "essential": True,
+ "volumesFrom": []
+ }
+ ]
+ data['family'] = name
+ response = self.connection.request(
+ ROOT,
+ data=data,
+ headers=self._get_headers('RegisterTaskDefinition')
+ ).object
+ if start:
+ return self.ex_start_task(
+ response['taskDefinition']['taskDefinitionArn'])[0]
+ else:
+ return Container(
+ id=None,
+ name=name,
+ image=image,
+ state=ContainerState.RUNNING,
+ ip_addresses=[],
+ extra={
+ 'taskDefinitionArn':
+ response['taskDefinition']['taskDefinitionArn']
+ },
+ driver=self.connection.driver
+ )
def get_container(self, id):
"""
@@ -197,20 +235,22 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: :class:`Container`
"""
- raise NotImplementedError(
- 'get_container not implemented for this driver')
+ containers = self.ex_list_containers_for_task([id])
+ return containers[0]
- def start_container(self, container):
+ def start_container(self, container, count=1):
"""
- Start a deployed container
+ Start a deployed task
:param container: The container to start
:type container: :class:`Container`
+ :param count: Number of containers to start
+ :type count: ``int``
+
:rtype: :class:`Container`
"""
- raise NotImplementedError(
- 'start_container not implemented for this driver')
+ return self.ex_start_task(container.extra['taskDefinitionArn'], count)
def stop_container(self, container):
"""
@@ -221,8 +261,17 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: :class:`Container`
"""
- raise NotImplementedError(
- 'stop_container not implemented for this driver')
+ request = {'task': container.extra['taskArn']}
+ response = self.connection.request(
+ ROOT,
+ data=request,
+ headers=self._get_headers('StopTask')
+ ).object
+ containers = []
+ containers.extend(self._to_containers(
+ response['task'],
+ container.extra['taskDefinitionArn']))
+ return containers
def restart_container(self, container):
"""
@@ -233,8 +282,8 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: :class:`Container`
"""
- raise NotImplementedError(
- 'restart_container not implemented for this driver')
+ self.stop_container(container)
+ return self.start_container(container)
def destroy_container(self, container):
"""
@@ -245,8 +294,53 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: :class:`Container`
"""
- raise NotImplementedError(
- 'destroy_container not implemented for this driver')
+ return self.stop_container(container)
+
+ def ex_start_task(self, task_arn, count=1):
+ """
+ Run a task definition and get the containers
+
+ :param task_arn: The task ARN to Run
+ :type task_arn: ``str``
+
+ :param count: The number of containers to start
+ :type count: ``int``
+
+ :rtype: ``list`` of :class:`Container`
+ """
+ request = None
+ request = {'count': count,
+ 'taskDefinition': task_arn}
+ response = self.connection.request(
+ ROOT,
+ data=request,
+ headers=self._get_headers('RunTask')
+ ).object
+ containers = []
+ for task in response['tasks']:
+ containers.extend(self._to_containers(task, task_arn))
+ return containers
+
+ def ex_list_containers_for_task(self, task_arns):
+ """
+ Get a list of containers by ID collection (ARN)
+
+ :param task_arns: The list of ARNs
+ :type task_arns: ``list`` of ``str``
+
+ :rtype: ``list`` of :class:`Container`
+ """
+ describe_request = {'tasks': task_arns}
+ descripe_response = self.connection.request(
+ ROOT,
+ data=describe_request,
+ headers=self._get_headers('DescribeTasks')
+ ).object
+ containers = []
+ for task in descripe_response['tasks']:
+ containers.extend(self._to_containers(
+ task, task['taskDefinitionArn']))
+ return containers
def _get_headers(self, action):
return {'x-amz-target': '%s.%s' %
@@ -265,13 +359,13 @@ class ElasticContainerDriver(ContainerDriver):
driver=self.connection.driver
)
- def _to_containers(self, data):
+ def _to_containers(self, data, task_definition_arn):
clusters = []
for cluster in data['containers']:
- clusters.append(self._to_container(cluster))
+ clusters.append(self._to_container(cluster, task_definition_arn))
return clusters
- def _to_container(self, data):
+ def _to_container(self, data, task_definition_arn):
return Container(
id=data['containerArn'],
name=data['name'],
@@ -285,7 +379,8 @@ class ElasticContainerDriver(ContainerDriver):
ip_addresses=None,
state=self.status_map.get(data['lastStatus'], None),
extra={
- 'taskArn': data['taskArn']
+ 'taskArn': data['taskArn'],
+ 'taskDefinitionArn': task_definition_arn
},
driver=self.connection.driver
)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a1adaae2/libcloud/test/container/fixtures/ecs/listtasks.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/listtasks.json b/libcloud/test/container/fixtures/ecs/listtasks.json
new file mode 100644
index 0000000..644ff73
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/listtasks.json
@@ -0,0 +1,8 @@
+{
+ "taskArns": [
+ "arn:aws:ecs:us-east-1:012345678910:task/0b69d5c0-d655-4695-98cd-5d2d526d9d5a",
+ "arn:aws:ecs:us-east-1:012345678910:task/51a01bdf-d00e-487e-ab14-7645330b6207",
+ "arn:aws:ecs:us-east-1:012345678910:task/b0b28bb8-2be3-4810-b52b-88df129d893c",
+ "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe"
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a1adaae2/libcloud/test/container/fixtures/ecs/registertaskdefinition.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/registertaskdefinition.json b/libcloud/test/container/fixtures/ecs/registertaskdefinition.json
new file mode 100644
index 0000000..163061d
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/registertaskdefinition.json
@@ -0,0 +1,26 @@
+{
+ "taskDefinition": {
+ "containerDefinitions": [
+ {
+ "cpu": 10,
+ "environment": [
+ {
+ "name": "MYSQL_ROOT_PASSWORD",
+ "value": "password"
+ }
+ ],
+ "essential": true,
+ "image": "mysql",
+ "memory": 500,
+ "mountPoints": [],
+ "name": "mysql",
+ "portMappings": [],
+ "volumesFrom": []
+ }
+ ],
+ "family": "jim",
+ "revision": 11,
+ "taskDefinitionArn": "arn:aws:ecs:us-east-1:012345678910:task-definition/hello_world:11",
+ "volumes": []
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a1adaae2/libcloud/test/container/fixtures/ecs/runtask.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/runtask.json b/libcloud/test/container/fixtures/ecs/runtask.json
new file mode 100644
index 0000000..70896e5
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/runtask.json
@@ -0,0 +1,37 @@
+{
+ "failures": [],
+ "tasks": [
+ {
+ "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/default",
+ "containerInstanceArn": "arn:aws:ecs:us-east-1:012345678910:container-instance/cf447635-790d-477d-be24-58a9cb819d45",
+ "containers": [
+ {
+ "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/e1ed7aac-d9b2-4315-8726-d2432bf11868",
+ "lastStatus": "PENDING",
+ "name": "wordpress",
+ "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/d8c67b3c-ac87-4ffe-a847-4785bc3a8b55"
+ },
+ {
+ "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/4b69fabd-991d-4781-bbf9-7efa03c754aa",
+ "lastStatus": "PENDING",
+ "name": "mysql",
+ "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/d8c67b3c-ac87-4ffe-a847-4785bc3a8b55"
+ }
+ ],
+ "desiredStatus": "RUNNING",
+ "lastStatus": "PENDING",
+ "overrides": {
+ "containerOverrides": [
+ {
+ "name": "wordpress"
+ },
+ {
+ "name": "mysql"
+ }
+ ]
+ },
+ "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/d8c67b3c-ac87-4ffe-a847-4785bc3a8b55",
+ "taskDefinitionArn": "arn:aws:ecs:us-east-1:012345678910:task-definition/hello_world:11"
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a1adaae2/libcloud/test/container/fixtures/ecs/stoptask.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/stoptask.json b/libcloud/test/container/fixtures/ecs/stoptask.json
new file mode 100644
index 0000000..72b5ebb
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/stoptask.json
@@ -0,0 +1,42 @@
+{
+ "task": {
+ "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/default",
+ "containerInstanceArn": "arn:aws:ecs:us-east-1:012345678910:container-instance/8db248d6-16a7-42b5-b9f9-43d3b1ad9430",
+ "containers": [
+ {
+ "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/05a5528c-77f6-4e5b-8f9a-2b0a1928a926",
+ "lastStatus": "RUNNING",
+ "name": "mysql",
+ "networkBindings": [],
+ "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/a126249b-b7e4-4b06-9d8f-1b56e75a99b5"
+ },
+ {
+ "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/37234a82-77f6-41d7-b54b-591f1e278093",
+ "lastStatus": "RUNNING",
+ "name": "wordpress",
+ "networkBindings": [
+ {
+ "bindIP": "0.0.0.0",
+ "containerPort": 80,
+ "hostPort": 80
+ }
+ ],
+ "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/a126249b-b7e4-4b06-9d8f-1b56e75a99b5"
+ }
+ ],
+ "desiredStatus": "STOPPED",
+ "lastStatus": "RUNNING",
+ "overrides": {
+ "containerOverrides": [
+ {
+ "name": "mysql"
+ },
+ {
+ "name": "wordpress"
+ }
+ ]
+ },
+ "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/a126249b-b7e4-4b06-9d8f-1b56e75a99b5",
+ "taskDefinitionArn": "arn:aws:ecs:us-east-1:012345678910:task-definition/hello_world:11"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/a1adaae2/libcloud/test/container/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_ecs.py b/libcloud/test/container/test_ecs.py
index 81bdf09..1a4af3d 100644
--- a/libcloud/test/container/test_ecs.py
+++ b/libcloud/test/container/test_ecs.py
@@ -17,7 +17,7 @@ import sys
from libcloud.test import unittest
-from libcloud.container.base import ContainerCluster
+from libcloud.container.base import ContainerCluster, ContainerImage, Container
from libcloud.container.drivers.ecs import ElasticContainerDriver
from libcloud.utils.py3 import httplib
@@ -62,6 +62,77 @@ class ElasticContainerDriverTestCase(unittest.TestCase):
containers = self.driver.list_containers(cluster=cluster)
self.assertEqual(len(containers), 2)
+ def test_deploy_container(self):
+ container = self.driver.deploy_container(
+ name='jim',
+ image=ContainerImage(
+ id=None,
+ name='mysql',
+ path='mysql',
+ version=None,
+ driver=self.driver
+ )
+ )
+ self.assertEqual(container.id, 'arn:aws:ecs:us-east-1:012345678910:container/e1ed7aac-d9b2-4315-8726-d2432bf11868')
+
+ def test_get_container(self):
+ container = self.driver.get_container(
+ 'arn:aws:ecs:us-east-1:012345678910:container/76c980a8-2454-4a9c-acc4-9eb103117273'
+ )
+ self.assertEqual(container.id, 'arn:aws:ecs:us-east-1:012345678910:container/76c980a8-2454-4a9c-acc4-9eb103117273')
+ self.assertEqual(container.name, 'mysql')
+ self.assertEqual(container.image.name, 'mysql')
+
+ def test_start_container(self):
+ container = self.driver.start_container(
+ Container(
+ id=None,
+ name=None,
+ image=None,
+ state=None,
+ ip_addresses=None,
+ driver=self.driver,
+ extra={
+ 'taskDefinitionArn': ''
+ }
+ )
+ )
+ self.assertFalse(container is None)
+
+ def test_stop_container(self):
+ container = self.driver.stop_container(
+ Container(
+ id=None,
+ name=None,
+ image=None,
+ state=None,
+ ip_addresses=None,
+ driver=self.driver,
+ extra={
+ 'taskArn': '12345',
+ 'taskDefinitionArn': '123556'
+ }
+ )
+ )
+ self.assertFalse(container is None)
+
+ def test_restart_container(self):
+ container = self.driver.restart_container(
+ Container(
+ id=None,
+ name=None,
+ image=None,
+ state=None,
+ ip_addresses=None,
+ driver=self.driver,
+ extra={
+ 'taskArn': '12345',
+ 'taskDefinitionArn': '123556'
+ }
+ )
+ )
+ self.assertFalse(container is None)
+
class ECSMockHttp(MockHttp):
fixtures = ContainerFileFixtures('ecs')
@@ -69,7 +140,11 @@ class ECSMockHttp(MockHttp):
'DescribeClusters': 'describeclusters.json',
'CreateCluster': 'createcluster.json',
'DeleteCluster': 'deletecluster.json',
- 'DescribeTasks': 'describetasks.json'
+ 'DescribeTasks': 'describetasks.json',
+ 'ListTasks': 'listtasks.json',
+ 'RegisterTaskDefinition': 'registertaskdefinition.json',
+ 'RunTask': 'runtask.json',
+ 'StopTask': 'stoptask.json'
}
def _2014_11_13(
[11/50] libcloud git commit: Merge branch 'trunk' into
LIBCLOUD-781_containers
Posted by an...@apache.org.
Merge branch 'trunk' into LIBCLOUD-781_containers
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/69cd184a
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/69cd184a
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/69cd184a
Branch: refs/heads/trunk
Commit: 69cd184adffab9edb3e566eaa952eca4ae71ee20
Parents: edb1265 60b5661
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Dec 28 21:19:04 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Dec 28 21:19:04 2015 +1100
----------------------------------------------------------------------
libcloud/compute/drivers/ec2.py | 2 --
libcloud/data/pricing.json | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
----------------------------------------------------------------------
[13/50] libcloud git commit: corrected indentation
Posted by an...@apache.org.
corrected indentation
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/d51dd3dc
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/d51dd3dc
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/d51dd3dc
Branch: refs/heads/trunk
Commit: d51dd3dca88d103c1b8327edc1b6e1931efa9964
Parents: 7c27da6
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Dec 28 21:27:36 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Dec 28 21:27:36 2015 +1100
----------------------------------------------------------------------
libcloud/container/drivers/ecs.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/d51dd3dc/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index c4ea82a..12b544f 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -73,7 +73,7 @@ class ElasticContainerDriver(ContainerDriver):
ROOT,
params=params,
headers=self._get_headers(params['Action'])
- ).object
+ ).object
return self._to_clusters(data)
def create_cluster(self, name, location=None):
@@ -95,7 +95,7 @@ class ElasticContainerDriver(ContainerDriver):
params=params,
data=request,
headers=self._get_headers(params['Action'])
- ).object
+ ).object
return self._to_cluster(response['cluster'])
def destroy_cluster(self, cluster):
@@ -112,7 +112,7 @@ class ElasticContainerDriver(ContainerDriver):
params=params,
data=request,
headers=self._get_headers(params['Action'])
- ).object
+ ).object
return data['cluster']['status'] == 'INACTIVE'
def install_image(self, path):
@@ -157,7 +157,7 @@ class ElasticContainerDriver(ContainerDriver):
params=params,
data=request,
headers=self._get_headers(params['Action'])
- ).object
+ ).object
containers = []
for task in response['tasks']:
containers.extend(self._to_containers(task))
[18/50] libcloud git commit: Tell the Mock HTTP object to use the
method name 'root' when the path contains nothing,
which in every ECS case it does
Posted by an...@apache.org.
Tell the Mock HTTP object to use the method name 'root' when the path contains nothing, which in every ECS case it does
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/54737715
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/54737715
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/54737715
Branch: refs/heads/trunk
Commit: 547377153134b94e417fad1705b62c822f475b02
Parents: b64d2fa
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Dec 30 21:41:30 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Dec 30 21:41:30 2015 +1100
----------------------------------------------------------------------
libcloud/container/drivers/ecs.py | 6 ++----
libcloud/test/__init__.py | 3 +++
libcloud/test/container/test_ecs.py | 2 +-
3 files changed, 6 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/54737715/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index 6485b10..1485027 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -83,13 +83,12 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: :class:`ContainerCluster`
"""
- params = {'Action': 'CreateCluster'}
request = {'clusterName': name}
response = self.connection.request(
ROOT,
method='POST',
data=request,
- headers=self._get_headers(params['Action'])
+ headers=self._get_headers('CreateCluster')
).object
return self._to_cluster(response['cluster'])
@@ -100,13 +99,12 @@ class ElasticContainerDriver(ContainerDriver):
:return: ``True`` if the destroy was successful, otherwise ``False``.
:rtype: ``bool``
"""
- params = {'Action': 'DeleteCluster'}
request = {'cluster': cluster.id}
data = self.connection.request(
ROOT,
method='POST',
data=request,
- headers=self._get_headers(params['Action'])
+ headers=self._get_headers('DeleteCluster')
).object
return data['cluster']['status'] == 'INACTIVE'
http://git-wip-us.apache.org/repos/asf/libcloud/blob/54737715/libcloud/test/__init__.py
----------------------------------------------------------------------
diff --git a/libcloud/test/__init__.py b/libcloud/test/__init__.py
index a168630..efc89c2 100644
--- a/libcloud/test/__init__.py
+++ b/libcloud/test/__init__.py
@@ -123,6 +123,9 @@ class BaseMockHttpObject(object):
param = qs[use_param][0].replace('.', '_').replace('-', '_')
meth_name = '%s_%s' % (meth_name, param)
+ if meth_name == '':
+ meth_name = 'root'
+
return meth_name
http://git-wip-us.apache.org/repos/asf/libcloud/blob/54737715/libcloud/test/container/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_ecs.py b/libcloud/test/container/test_ecs.py
index 1a4af3d..86b715e 100644
--- a/libcloud/test/container/test_ecs.py
+++ b/libcloud/test/container/test_ecs.py
@@ -147,7 +147,7 @@ class ECSMockHttp(MockHttp):
'StopTask': 'stoptask.json'
}
- def _2014_11_13(
+ def root(
self, method, url, body, headers):
target = headers['x-amz-target']
if target is not None:
[42/50] libcloud git commit: Fix the path for the doc example
Posted by an...@apache.org.
Fix the path for the doc example
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/621ec713
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/621ec713
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/621ec713
Branch: refs/heads/trunk
Commit: 621ec7134ae3e55c25a0f4e1af1864655748e293
Parents: f00a9b7
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Jan 11 15:24:58 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Jan 11 15:24:58 2016 +1100
----------------------------------------------------------------------
docs/container/drivers/ecs.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/621ec713/docs/container/drivers/ecs.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/ecs.rst b/docs/container/drivers/ecs.rst
index 4dc3912..40274d1 100644
--- a/docs/container/drivers/ecs.rst
+++ b/docs/container/drivers/ecs.rst
@@ -44,7 +44,7 @@ Docker Registry API Client :class:`~libcloud.container.utils.docker.RegistryClie
You can use a factory method to generate an instance of RegsitryClient from the ECS driver. This will request a 12 hour token from the Amazon API and instantiate a :class:`~libcloud.container.utils.docker.RegistryClient`
object with those credentials.
-.. literalinclude:: /examples/container/container_registry.py
+.. literalinclude:: /examples/container/ecs/container_registry.py
:language: python
API Docs
[15/50] libcloud git commit: Update provider table
Posted by an...@apache.org.
Update provider table
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/f4c1e2e8
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/f4c1e2e8
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/f4c1e2e8
Branch: refs/heads/trunk
Commit: f4c1e2e82789789b9ea05cd2ecead6df65dc3544
Parents: c82230f
Author: anthony-shaw <an...@gmail.com>
Authored: Tue Dec 29 19:58:26 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Tue Dec 29 19:58:26 2015 +1100
----------------------------------------------------------------------
contrib/generate_provider_feature_matrix_table.py | 8 ++++----
docs/compute/_supported_methods_block_storage.rst | 2 ++
docs/compute/_supported_methods_image_management.rst | 2 ++
.../_supported_methods_key_pair_management.rst | 2 ++
docs/compute/_supported_methods_main.rst | 2 ++
docs/compute/_supported_providers.rst | 2 ++
docs/container/_supported_methods.rst | 14 ++++++++------
docs/container/_supported_providers.rst | 14 ++++++++------
libcloud/container/providers.py | 2 ++
libcloud/container/types.py | 1 +
10 files changed, 33 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/contrib/generate_provider_feature_matrix_table.py
----------------------------------------------------------------------
diff --git a/contrib/generate_provider_feature_matrix_table.py b/contrib/generate_provider_feature_matrix_table.py
index 3995eb2..f5ccb2c 100755
--- a/contrib/generate_provider_feature_matrix_table.py
+++ b/contrib/generate_provider_feature_matrix_table.py
@@ -96,8 +96,8 @@ BASE_API_METHODS = {
'delete_zone', 'delete_record'],
'container': ['install_image', 'list_images', 'deploy_container',
'get_container', 'start_container', 'stop_container',
- 'restart_container', 'delete_container', 'list_containers',
- 'list_locations', 'create_cluster', 'delete_cluster',
+ 'restart_container', 'destroy_container', 'list_containers',
+ 'list_locations', 'create_cluster', 'destroy_cluster',
'list_clusters']
}
@@ -179,10 +179,10 @@ FRIENDLY_METHODS_NAMES = {
'start_container': 'start container',
'stop_container': 'stop container',
'restart_container': 'restart container',
- 'delete_container': 'delete container',
+ 'destroy_container': 'destroy container',
'list_locations': 'list locations',
'create_cluster': 'create cluster',
- 'delete_cluster': 'delete cluster',
+ 'destroy_cluster': 'destroy cluster',
'list_clusters': 'list clusters'
}
}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/docs/compute/_supported_methods_block_storage.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_block_storage.rst b/docs/compute/_supported_methods_block_storage.rst
index f7e8c69..e2f34ed 100644
--- a/docs/compute/_supported_methods_block_storage.rst
+++ b/docs/compute/_supported_methods_block_storage.rst
@@ -13,6 +13,7 @@ Provider list volumes create volume destroy volume
`CloudStack`_ yes yes yes yes yes no yes
`Cloudwatt`_ yes yes yes yes yes yes yes
`DigitalOcean`_ no no no no no no no
+`DimensionData`_ no no no no no no no
`Amazon EC2`_ yes yes yes yes yes yes yes
`Amazon EC2 (ap-northeast-1)`_ yes yes yes yes yes yes yes
`Amazon EC2 (ap-southeast-1)`_ yes yes yes yes yes yes yes
@@ -84,6 +85,7 @@ Provider list volumes create volume destroy volume
.. _`CloudStack`: http://cloudstack.org/
.. _`Cloudwatt`: https://www.cloudwatt.com/
.. _`DigitalOcean`: https://www.digitalocean.com
+.. _`DimensionData`: http://www.dimensiondata.com/
.. _`Amazon EC2`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-northeast-1)`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-southeast-1)`: http://aws.amazon.com/ec2/
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/docs/compute/_supported_methods_image_management.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_image_management.rst b/docs/compute/_supported_methods_image_management.rst
index 7c60f7a..bcd6d6b 100644
--- a/docs/compute/_supported_methods_image_management.rst
+++ b/docs/compute/_supported_methods_image_management.rst
@@ -13,6 +13,7 @@ Provider list images get image create image delete
`CloudStack`_ yes no no no no
`Cloudwatt`_ yes yes yes yes no
`DigitalOcean`_ yes yes yes yes no
+`DimensionData`_ yes no no no no
`Amazon EC2`_ yes yes yes yes yes
`Amazon EC2 (ap-northeast-1)`_ yes yes yes yes yes
`Amazon EC2 (ap-southeast-1)`_ yes yes yes yes yes
@@ -84,6 +85,7 @@ Provider list images get image create image delete
.. _`CloudStack`: http://cloudstack.org/
.. _`Cloudwatt`: https://www.cloudwatt.com/
.. _`DigitalOcean`: https://www.digitalocean.com
+.. _`DimensionData`: http://www.dimensiondata.com/
.. _`Amazon EC2`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-northeast-1)`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-southeast-1)`: http://aws.amazon.com/ec2/
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/docs/compute/_supported_methods_key_pair_management.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_key_pair_management.rst b/docs/compute/_supported_methods_key_pair_management.rst
index d39e3cf..b0cfce4 100644
--- a/docs/compute/_supported_methods_key_pair_management.rst
+++ b/docs/compute/_supported_methods_key_pair_management.rst
@@ -13,6 +13,7 @@ Provider list key pairs get key pair create key pai
`CloudStack`_ yes yes yes yes no yes
`Cloudwatt`_ yes yes yes yes no yes
`DigitalOcean`_ yes yes yes no no yes
+`DimensionData`_ no no no no no no
`Amazon EC2`_ yes yes yes yes no yes
`Amazon EC2 (ap-northeast-1)`_ yes yes yes yes no yes
`Amazon EC2 (ap-southeast-1)`_ yes yes yes yes no yes
@@ -84,6 +85,7 @@ Provider list key pairs get key pair create key pai
.. _`CloudStack`: http://cloudstack.org/
.. _`Cloudwatt`: https://www.cloudwatt.com/
.. _`DigitalOcean`: https://www.digitalocean.com
+.. _`DimensionData`: http://www.dimensiondata.com/
.. _`Amazon EC2`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-northeast-1)`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-southeast-1)`: http://aws.amazon.com/ec2/
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/docs/compute/_supported_methods_main.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_main.rst b/docs/compute/_supported_methods_main.rst
index 1ad3620..67c8966 100644
--- a/docs/compute/_supported_methods_main.rst
+++ b/docs/compute/_supported_methods_main.rst
@@ -13,6 +13,7 @@ Provider list nodes create node reboot node destroy
`CloudStack`_ yes yes yes yes yes yes yes
`Cloudwatt`_ yes yes yes yes yes yes yes
`DigitalOcean`_ yes yes yes yes yes yes no
+`DimensionData`_ yes yes yes yes yes yes yes
`Amazon EC2`_ yes yes yes yes yes yes yes
`Amazon EC2 (ap-northeast-1)`_ yes yes yes yes yes yes yes
`Amazon EC2 (ap-southeast-1)`_ yes yes yes yes yes yes yes
@@ -84,6 +85,7 @@ Provider list nodes create node reboot node destroy
.. _`CloudStack`: http://cloudstack.org/
.. _`Cloudwatt`: https://www.cloudwatt.com/
.. _`DigitalOcean`: https://www.digitalocean.com
+.. _`DimensionData`: http://www.dimensiondata.com/
.. _`Amazon EC2`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-northeast-1)`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-southeast-1)`: http://aws.amazon.com/ec2/
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/docs/compute/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_providers.rst b/docs/compute/_supported_providers.rst
index 337bcef..ab7b9d9 100644
--- a/docs/compute/_supported_providers.rst
+++ b/docs/compute/_supported_providers.rst
@@ -13,6 +13,7 @@ Provider Documentation
`CloudStack`_ :doc:`Click </compute/drivers/cloudstack>` CLOUDSTACK :mod:`libcloud.compute.drivers.cloudstack` :class:`CloudStackNodeDriver`
`Cloudwatt`_ :doc:`Click </compute/drivers/cloudwatt>` CLOUDWATT :mod:`libcloud.compute.drivers.cloudwatt` :class:`CloudwattNodeDriver`
`DigitalOcean`_ :doc:`Click </compute/drivers/digital_ocean>` DIGITAL_OCEAN :mod:`libcloud.compute.drivers.digitalocean` :class:`DigitalOceanNodeDriver`
+`DimensionData`_ :doc:`Click </compute/drivers/dimensiondata>` DIMENSIONDATA :mod:`libcloud.compute.drivers.dimensiondata` :class:`DimensionDataNodeDriver`
`Amazon EC2`_ :doc:`Click </compute/drivers/ec2>` EC2 :mod:`libcloud.compute.drivers.ec2` :class:`EC2NodeDriver`
`Amazon EC2 (ap-northeast-1)`_ EC2_AP_NORTHEAST :mod:`libcloud.compute.drivers.ec2` :class:`EC2APNENodeDriver`
`Amazon EC2 (ap-southeast-1)`_ EC2_AP_SOUTHEAST :mod:`libcloud.compute.drivers.ec2` :class:`EC2APSENodeDriver`
@@ -84,6 +85,7 @@ Provider Documentation
.. _`CloudStack`: http://cloudstack.org/
.. _`Cloudwatt`: https://www.cloudwatt.com/
.. _`DigitalOcean`: https://www.digitalocean.com
+.. _`DimensionData`: http://www.dimensiondata.com/
.. _`Amazon EC2`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-northeast-1)`: http://aws.amazon.com/ec2/
.. _`Amazon EC2 (ap-southeast-1)`: http://aws.amazon.com/ec2/
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/docs/container/_supported_methods.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_methods.rst b/docs/container/_supported_methods.rst
index 1a8c963..a62a8e5 100644
--- a/docs/container/_supported_methods.rst
+++ b/docs/container/_supported_methods.rst
@@ -1,11 +1,13 @@
.. NOTE: This file has been generated automatically using generate_provider_feature_matrix_table.py script, don't manually edit it
-========= ============= =========== ================ ============= =============== ============== ================= ================ =============== ============== ============== ============== =============
-Provider install image list images deploy container get container start container stop container restart container delete container list containers list locations create cluster delete cluster list clusters
-========= ============= =========== ================ ============= =============== ============== ================= ================ =============== ============== ============== ============== =============
-`Docker`_ yes yes yes yes yes yes yes yes yes no no no no
-`Joyent`_ yes yes yes yes yes yes yes yes yes no no no no
-========= ============= =========== ================ ============= =============== ============== ================= ================ =============== ============== ============== ============== =============
+=================================== ============= =========== ================ ============= =============== ============== ================= ================= =============== ============== ============== =============== =============
+Provider install image list images deploy container get container start container stop container restart container destroy container list containers list locations create cluster destroy cluster list clusters
+=================================== ============= =========== ================ ============= =============== ============== ================= ================= =============== ============== ============== =============== =============
+`Docker`_ yes yes yes yes yes yes yes yes yes no no no no
+`Amazon Elastic Container Service`_ yes yes yes yes yes yes yes yes yes no yes yes yes
+`Joyent`_ yes yes yes yes yes yes yes yes yes no no no no
+=================================== ============= =========== ================ ============= =============== ============== ================= ================= =============== ============== ============== =============== =============
.. _`Docker`: http://docker.io
+.. _`Amazon Elastic Container Service`: https://aws.amazon.com/ecs/details/
.. _`Joyent`: http://joyent.com
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/docs/container/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/container/_supported_providers.rst b/docs/container/_supported_providers.rst
index 26f4755..da86a80 100644
--- a/docs/container/_supported_providers.rst
+++ b/docs/container/_supported_providers.rst
@@ -1,11 +1,13 @@
.. NOTE: This file has been generated automatically using generate_provider_feature_matrix_table.py script, don't manually edit it
-========= ======================================== ================= ======================================== ==============================
-Provider Documentation Provider constant Module Class Name
-========= ======================================== ================= ======================================== ==============================
-`Docker`_ :doc:`Click </container/drivers/docker>` DOCKER :mod:`libcloud.container.drivers.docker` :class:`DockerContainerDriver`
-`Joyent`_ :doc:`Click </container/drivers/joyent>` JOYENT :mod:`libcloud.container.drivers.joyent` :class:`JoyentContainerDriver`
-========= ======================================== ================= ======================================== ==============================
+=================================== ======================================== ================= ======================================== ===============================
+Provider Documentation Provider constant Module Class Name
+=================================== ======================================== ================= ======================================== ===============================
+`Docker`_ :doc:`Click </container/drivers/docker>` DOCKER :mod:`libcloud.container.drivers.docker` :class:`DockerContainerDriver`
+`Amazon Elastic Container Service`_ ECS :mod:`libcloud.container.drivers.ecs` :class:`ElasticContainerDriver`
+`Joyent`_ :doc:`Click </container/drivers/joyent>` JOYENT :mod:`libcloud.container.drivers.joyent` :class:`JoyentContainerDriver`
+=================================== ======================================== ================= ======================================== ===============================
.. _`Docker`: http://docker.io
+.. _`Amazon Elastic Container Service`: https://aws.amazon.com/ecs/details/
.. _`Joyent`: http://joyent.com
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/libcloud/container/providers.py
----------------------------------------------------------------------
diff --git a/libcloud/container/providers.py b/libcloud/container/providers.py
index 45daa88..458eae8 100644
--- a/libcloud/container/providers.py
+++ b/libcloud/container/providers.py
@@ -24,6 +24,8 @@ DRIVERS = {
('libcloud.container.drivers.docker', 'DockerContainerDriver'),
Provider.JOYENT:
('libcloud.container.drivers.joyent', 'JoyentContainerDriver'),
+ Provider.ECS:
+ ('libcloud.container.drivers.ecs', 'ElasticContainerDriver'),
}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f4c1e2e8/libcloud/container/types.py
----------------------------------------------------------------------
diff --git a/libcloud/container/types.py b/libcloud/container/types.py
index 559d779..6236468 100644
--- a/libcloud/container/types.py
+++ b/libcloud/container/types.py
@@ -43,6 +43,7 @@ class Provider(object):
DUMMY = 'dummy'
DOCKER = 'docker'
JOYENT = 'joyent'
+ ECS = 'ecs'
class ContainerState(Type):
[09/50] libcloud git commit: Merge commit
'6ddd2bd81c8a79fb5456ba857f265ef16ac11910' into LIBCLOUD-781_containers
Posted by an...@apache.org.
Merge commit '6ddd2bd81c8a79fb5456ba857f265ef16ac11910' into LIBCLOUD-781_containers
# Conflicts:
# CHANGES.rst
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c8024ade
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c8024ade
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c8024ade
Branch: refs/heads/trunk
Commit: c8024adef46a19f6c058ee83e987f6f1e07c8614
Parents: f1674de 6ddd2bd
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Dec 28 20:58:50 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Dec 28 20:58:50 2015 +1100
----------------------------------------------------------------------
docs/compute/_supported_methods_block_storage.rst | 2 --
docs/compute/_supported_methods_image_management.rst | 2 --
docs/compute/_supported_methods_key_pair_management.rst | 2 --
docs/compute/_supported_methods_main.rst | 2 --
docs/compute/_supported_providers.rst | 2 --
libcloud/compute/drivers/dimensiondata.py | 7 ++++---
libcloud/compute/drivers/ec2.py | 10 ++++++++++
libcloud/test/dns/fixtures/cloudflare/nul.json | 10 ----------
libcloud/test/dns/fixtures/cloudflare/nul_.json | 10 ++++++++++
libcloud/test/dns/test_cloudflare.py | 3 ++-
10 files changed, 26 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
[23/50] libcloud git commit: Use triton PNG instead of SVG image as
logo
Posted by an...@apache.org.
Use triton PNG instead of SVG image as logo
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/83c06fee
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/83c06fee
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/83c06fee
Branch: refs/heads/trunk
Commit: 83c06fee7a4df2a0461eaf31b0aa27899d6b91fb
Parents: 57a0ca9
Author: anthony-shaw <an...@gmail.com>
Authored: Sun Jan 3 21:06:31 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sun Jan 3 21:06:31 2016 +1100
----------------------------------------------------------------------
docs/_static/images/provider_logos/triton.png | Bin 0 -> 14866 bytes
docs/_static/images/provider_logos/triton.svg | 107 -------------------
docs/container/drivers/ecs.rst | 2 +-
docs/container/drivers/joyent.rst | 2 +-
.../container/ecs/instantiate_driver.py | 4 +-
5 files changed, 5 insertions(+), 110 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/83c06fee/docs/_static/images/provider_logos/triton.png
----------------------------------------------------------------------
diff --git a/docs/_static/images/provider_logos/triton.png b/docs/_static/images/provider_logos/triton.png
new file mode 100644
index 0000000..6a20129
Binary files /dev/null and b/docs/_static/images/provider_logos/triton.png differ
http://git-wip-us.apache.org/repos/asf/libcloud/blob/83c06fee/docs/_static/images/provider_logos/triton.svg
----------------------------------------------------------------------
diff --git a/docs/_static/images/provider_logos/triton.svg b/docs/_static/images/provider_logos/triton.svg
deleted file mode 100644
index 505257e..0000000
--- a/docs/_static/images/provider_logos/triton.svg
+++ /dev/null
@@ -1,107 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="298.2px" height="62.8px" viewBox="0 0 298.2 62.8" enable-background="new 0 0 298.2 62.8" xml:space="preserve">
-<g>
- <g id="XMLID_35277_">
- <path id="XMLID_35290_" fill-rule="evenodd" clip-rule="evenodd" fill="#3E3E3F" d="M99.1,15.8c0.4,0.3,0.8,0.5,1.3,0.5
- c0.8,0,1-0.5,1-1.2V9.4h0.9v4.7c0,0.4,0,0.9,0,1.3c0,1.1-0.6,1.7-1.9,1.7c-0.9,0-1.5-0.4-1.8-0.6L99.1,15.8z M107.7,14.1
- c0-1.4-0.4-2.3-1.5-2.3c-1.1,0-1.6,0.9-1.6,2.1c0,1.1,0.2,2.4,1.5,2.4C107.2,16.4,107.7,15.4,107.7,14.1z M106.2,11.1
- c0.8,0,2.3,0.2,2.3,2.8c0,2.2-1.1,3.1-2.5,3.1c-1.4,0-2.3-1-2.3-3C103.7,11.7,105.1,11.1,106.2,11.1 M114,16.7v-5.4h-0.9v3.4
- c0,0.8-0.5,1.3-1.4,1.3c-1.2,0-1.3-0.7-1.3-1.5v-3.2h-0.9v3.4c0,1.3,0.6,1.8,1.6,1.9c-0.6,0.4-1.2,1-1.2,1.9
- c0,0.9,0.6,1.4,1.7,1.4c1.2,0,1.9-0.6,2.2-1.7C113.9,17.9,114,17.2,114,16.7z M111.7,19.3c1,0,1.4-0.9,1.4-2.1v-1
- c-1.4,0.6-2.3,1.2-2.3,2.3C110.8,19,111.1,19.3,111.7,19.3z M117.6,11.1c-1.7,0-2.6,1.4-2.6,3.1c0,1.7,0.7,2.9,2.5,2.9
- c0.9,0,1.6-0.4,1.8-0.6l-0.3-0.6c-0.2,0.2-0.7,0.5-1.5,0.5c-1.2,0-1.7-1-1.7-1.9c0.1,0,0.2,0,0.3,0c1.1,0,3.1-0.3,3.1-1.9
- C119.3,11.7,118.7,11.1,117.6,11.1z M117.6,11.8c-1.2,0-1.7,1.1-1.7,2c0.1,0,0.1,0,0.2,0c0.8,0,2.4-0.2,2.4-1.2
- C118.5,12.1,118.1,11.8,117.6,11.8z M121.3,16.9v-3.7c0-0.7,0.7-1.4,1.5-1.4c1,0,1.1,0.7,1.1,1.5v3.6h0.9v-3.8
- c0-1.3-0.6-1.9-1.8-1.9c-0.7,0-1.4,0.3-1.8,1l-0.1-0.8h-0.8l0.1,0.9v4.8H121.3z M126.2,9v6.3c0,0.8,0,1.7,1.6,1.7
- c0.5,0,1-0.1,1.3-0.4l-0.3-0.6c-0.2,0.1-0.5,0.3-0.9,0.3c-0.5,0-0.8-0.2-0.8-1V12h1.6v-0.8h-1.6V9H126.2z"/>
- <g id="XMLID_35316_">
- <g>
- <path id="XMLID_112_" fill="#3E3E3F" d="M98,23.4h31.5V30h-10.8v22.9h-9.8V30H98V23.4z"/>
- <path id="XMLID_109_" fill="#3E3E3F" d="M132.4,23.4H156c7.2,0,9.9,3.3,9.9,8.2c0,3.9-2.1,6.1-4.7,6.7v0.1
- c1.9,0.6,3.3,2.1,3.6,5.3c0.5,5.8,0.6,7.7,1.9,9.2h-10.8c-0.5-1.3-0.6-3-0.6-4.4c0-4.6-1.5-5.5-4-5.5h-9v9.8h-9.8V23.4z
- M142.2,36.4h9.5c2.4,0,3.7-1.2,3.7-3.3c0-1.9-1.3-3.2-3.7-3.2h-9.5V36.4z"/>
- <path id="XMLID_107_" fill="#3E3E3F" d="M170,23.4h9.8v29.5H170V23.4z"/>
- <path id="XMLID_105_" fill="#3E3E3F" d="M182.9,23.4h31.5V30h-10.8v22.9h-9.8V30h-10.8V23.4z"/>
- <path id="XMLID_102_" fill="#3E3E3F" d="M233.3,22.5c10.4,0,19.2,3.4,19.2,15.7c0,12.2-8.8,15.7-19.2,15.7
- c-10.4,0-19.2-3.4-19.2-15.7C214.1,25.9,222.9,22.5,233.3,22.5z M233.3,47.2c5.3,0,8.8-2.9,8.8-9.1c0-6.2-3.5-9.1-8.8-9.1
- c-5.2,0-8.8,2.9-8.8,9.1C224.5,44.3,228.1,47.2,233.3,47.2z"/>
- <path id="XMLID_100_" fill="#3E3E3F" d="M254.5,23.4h11.3l13.7,18.5h0.1V23.4h9.5v29.5h-10.9l-14.1-18.6H264v18.6h-9.5V23.4z"/>
- </g>
- </g>
- <g id="XMLID_35331_">
- <path id="XMLID_35332_" fill="#3E3E3F" d="M294.4,23.9h-0.9v2.5H293v-2.5h-0.9v-0.4h2.3V23.9z M298.2,26.4h-0.5V24h0l-0.9,2.4
- h-0.3l-0.9-2.4h0v2.4H295v-2.9h0.7l0.9,2.2l0.8-2.2h0.7V26.4z"/>
- </g>
- </g>
- <g id="XMLID_34924_">
- <g id="XMLID_34928_" opacity="0.5">
- <polygon id="XMLID_34929_" fill="#3B5967" points="42.8,42.8 42.8,44.7 58.1,60.1 60.1,60.1 60.1,58.1 44.7,42.8 "/>
- </g>
- <path id="XMLID_34930_" fill="#C42C28" d="M42.8,21.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1-0.1-0.1c0,0,0-0.1-0.1-0.1
- c-0.1-0.1-0.1-0.1-0.2-0.2l-20-20c-0.1-0.1-0.1-0.1-0.2-0.2c0,0-0.1,0-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1,0-0.1,0
- c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.3,0h-20C1.3,0,1.2,0,1.1,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0.1c0,0-0.1,0-0.1,0.1
- C0.5,0.3,0.3,0.5,0.2,0.6c0,0,0,0.1-0.1,0.1c0,0-0.1,0.1-0.1,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.1,0,0.2,0,0.3v20
- c0,0.1,0,0.2,0,0.3c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0.1,0.1c0,0,0,0.1,0.1,0.1c0.1,0.1,0.1,0.1,0.2,0.2l20,20
- c0.1,0.1,0.1,0.1,0.2,0.2c0,0,0.1,0,0.1,0.1c0,0,0.1,0.1,0.1,0.1c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0.1,0,0.2,0,0.3,0h20
- c0.8,0,1.4-0.6,1.4-1.4v-20C42.8,21.3,42.8,21.2,42.8,21.1z M2.7,4.7L20,22v16.1L2.7,20.8V4.7z M22,20L4.7,2.7h16.1L38.1,20H22z
- M22.8,40.1V22.8h17.3v17.3H22.8z"/>
- <g id="XMLID_34935_" opacity="0.5">
- <polygon id="XMLID_34936_" fill="#C52B27" points="22.8,22.8 22.8,24.7 38.1,40.1 40.1,40.1 40.1,38.1 24.7,22.8 "/>
- <polygon id="XMLID_34937_" fill="#C52B27" points="20,2.7 20,18.1 22,20 22.8,20 22.8,4.7 20.8,2.7 "/>
- <polygon id="XMLID_34938_" fill="#C52B27" points="18.1,20 2.7,20 2.7,20.8 4.7,22.8 20,22.8 20,22 "/>
- <path id="XMLID_34940_" fill="#C52B27" d="M41.8,42.7c0,0,0.1,0,0.1,0C41.9,42.7,41.9,42.7,41.8,42.7z"/>
- <path id="XMLID_34941_" fill="#C52B27" d="M42.6,42.1c0,0,0,0.1-0.1,0.1C42.6,42.2,42.6,42.1,42.6,42.1z"/>
- <path id="XMLID_34942_" fill="#C52B27" d="M42.7,41.8c0,0,0,0.1,0,0.1C42.7,41.9,42.7,41.9,42.7,41.8z"/>
- <path id="XMLID_34944_" fill="#C52B27" d="M42.8,41.4c0,0.1,0,0.2,0,0.3C42.8,41.6,42.8,41.5,42.8,41.4z"/>
- <path id="XMLID_34946_" fill="#C52B27" d="M41.4,42.8c0.1,0,0.2,0,0.3,0C41.6,42.8,41.5,42.8,41.4,42.8z"/>
- <path id="XMLID_34947_" fill="#C52B27" d="M42.1,42.6c0,0,0.1,0,0.1-0.1C42.2,42.6,42.1,42.6,42.1,42.6z"/>
- </g>
- <path id="XMLID_34948_" fill="#F16323" d="M62.8,21.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1-0.1-0.1c0,0,0-0.1-0.1-0.1
- c-0.1-0.1-0.1-0.1-0.2-0.2l-20-20c-0.1-0.1-0.1-0.1-0.2-0.2c0,0-0.1,0-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1,0-0.1,0
- c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.3,0h-20c0.1,0,0.2,0,0.3,0h0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0h0c0.1,0,0.1,0.1,0.2,0.1
- c0,0,0,0,0,0l0,0c0.1,0.1,0.1,0.1,0.2,0.2l2.3,2.3h16.1L58.1,20H42l0.4,0.4c0.1,0.1,0.1,0.1,0.2,0.2c0,0,0,0.1,0.1,0.1
- c0,0,0.1,0.1,0.1,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.1,0,0.2,0,0.3v1.4h17.3v17.3H42.8v1.4c0,0.1,0,0.2,0,0.3
- c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0,0,0.1-0.1,0.1c0,0,0,0.1-0.1,0.1c-0.1,0.2-0.2,0.3-0.4,0.4c0,0-0.1,0-0.1,0.1
- c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.3,0h20c0.8,0,1.4-0.6,1.4-1.4v-20
- C62.8,21.3,62.8,21.2,62.8,21.1z"/>
- <path fill="#BDBEC0" d="M41.4,42.8h-1.4v17.3H22.8V42.8h-1.4c-0.1,0-0.2,0-0.3,0c0,0-0.1,0-0.1,0c0,0-0.1,0-0.1,0
- c0,0-0.1,0-0.1-0.1c0,0-0.1,0-0.1-0.1c-0.1-0.1-0.1-0.1-0.2-0.2L20,42v16.1L2.7,40.9V24.7l-2.3-2.3c-0.1-0.1-0.1-0.1-0.2-0.2l0,0
- c0,0,0,0,0-0.1c0-0.1-0.1-0.2-0.1-0.3c0,0,0,0,0-0.1l0,0C0,21.7,0,21.5,0,21.4v20c0,0.1,0,0.2,0,0.3c0,0,0,0.1,0,0.1
- c0,0,0,0.1,0,0.1c0,0,0,0.1,0.1,0.1c0,0,0,0.1,0.1,0.1c0.1,0.1,0.1,0.1,0.2,0.2l20,20c0.1,0.1,0.1,0.1,0.2,0.2c0,0,0.1,0,0.1,0.1
- c0,0,0.1,0.1,0.1,0.1c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0.1,0,0.2,0,0.3,0h20c0.8,0,1.4-0.6,1.4-1.4V42.8H41.4z"/>
- <g id="XMLID_34949_">
- <polygon id="XMLID_34950_" opacity="0.5" fill="#F16323" points="42.8,20 42.8,4.7 40.9,2.7 40.1,2.7 40.1,18.1 42,20 "/>
- <polygon id="XMLID_34951_" opacity="0.5" fill="#F16323" points="42.8,22.8 42.8,24.7 58.1,40.1 60.1,40.1 60.1,38.1 44.7,22.8
- "/>
- <path id="XMLID_34952_" opacity="0.5" fill="#F16323" d="M41.8,0.1c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0.1c0,0,0.1,0,0.1,0.1
- c0.1,0.1,0.1,0.1,0.2,0.2l0,0c-0.2-0.3-0.6-0.4-1-0.4c0.1,0,0.2,0,0.3,0C41.7,0,41.8,0.1,41.8,0.1z"/>
- </g>
- <g id="XMLID_34953_" opacity="0.5">
- <path id="XMLID_34954_" fill="#F19922" d="M62,0.1c0,0,0.1,0,0.1,0.1c0,0,0,0,0.1,0C62.1,0.2,62.1,0.1,62,0.1z"/>
- <path id="XMLID_34955_" fill="#F19922" d="M62.4,0.4c-0.1-0.1-0.1-0.1-0.2-0.2C62.3,0.3,62.4,0.3,62.4,0.4z"/>
- <polygon id="XMLID_34956_" fill="#F19922" points="60.1,2.7 60.1,18.1 62,20 62.8,20 62.8,4.7 60.9,2.7 "/>
- <path id="XMLID_34957_" fill="#F19922" d="M61.8,0.1C61.9,0.1,61.9,0.1,61.8,0.1c0,0-0.1,0-0.1,0C61.8,0,61.8,0.1,61.8,0.1z"/>
- <polygon id="XMLID_34958_" fill="#F19922" points="62.8,22.8 62.8,24.7 78.2,40.1 80.1,40.1 80.1,38.1 64.8,22.8 "/>
- </g>
- <polygon id="XMLID_34959_" opacity="0.5" fill="#83D2E6" points="64.8,42.8 62.8,42.8 62.8,44.7 78.2,60.1 80.1,60.1 80.1,58.1
- "/>
- <path id="XMLID_34960_" fill="#83D2E6" d="M81.5,42.8h-1.4v17.3H62.8v1.4c0,0.8-0.6,1.4-1.4,1.4h20c0.8,0,1.4-0.6,1.4-1.4v-20
- C82.9,42.2,82.2,42.8,81.5,42.8z"/>
- <path id="XMLID_34961_" fill="#5A88A9" d="M61.5,42.8h-1.4v17.3H42.8v1.4c0,0.8-0.6,1.4-1.4,1.4h20c0.8,0,1.4-0.6,1.4-1.4V42.8
- H61.5z"/>
- <g id="XMLID_34962_" opacity="0.5">
- <polygon id="XMLID_34963_" fill="#BDBEC0" points="38.1,60.1 40.1,60.1 40.1,58.2 24.7,42.8 22.8,42.8 22.8,44.8 "/>
- <polygon id="XMLID_34964_" fill="#BDBEC0" points="2.7,40.9 4.7,42.8 20,42.8 20,42 18.1,40.1 2.7,40.1 "/>
- </g>
- <path id="XMLID_34965_" fill="#F19922" d="M82.8,21.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1-0.1-0.1c0,0,0-0.1-0.1-0.1
- c-0.1-0.1-0.1-0.1-0.2-0.2l-20-20c-0.1-0.1-0.1-0.1-0.2-0.2c0,0-0.1,0-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0,0-0.1,0-0.1,0
- c0,0-0.1,0-0.1,0c-0.1,0-0.2,0-0.3,0h-20c0.1,0,0.2,0,0.3,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0.1c0,0,0.1,0,0.1,0.1
- c0.1,0.1,0.1,0.1,0.2,0.2l2.3,2.3h16.1L78.2,20H62l0.4,0.4c0.1,0.1,0.1,0.1,0.2,0.2c0,0,0,0.1,0.1,0.1c0,0,0.1,0.1,0.1,0.1
- c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.1,0,0.2,0,0.3v1.4h17.3v17.3H62.8v1.4c0,0.8-0.6,1.4-1.4,1.4h20c0.8,0,1.4-0.6,1.4-1.4v-20
- C82.9,21.3,82.8,21.2,82.8,21.1z"/>
- </g>
-</g>
-</svg>
http://git-wip-us.apache.org/repos/asf/libcloud/blob/83c06fee/docs/container/drivers/ecs.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/ecs.rst b/docs/container/drivers/ecs.rst
index 089fae6..138eceb 100644
--- a/docs/container/drivers/ecs.rst
+++ b/docs/container/drivers/ecs.rst
@@ -3,7 +3,7 @@ Amazon Elastic Container Service Documentation
Elastic Container Service is a container-as-a-service feature of `AWS`_.
-.. figure:: /_static/images/provider_logos/aws.svg
+.. figure:: /_static/images/provider_logos/aws.png
:align: center
:width: 300
:target: http://aws.amazon.com/
http://git-wip-us.apache.org/repos/asf/libcloud/blob/83c06fee/docs/container/drivers/joyent.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/joyent.rst b/docs/container/drivers/joyent.rst
index f0e3da7..776ac93 100644
--- a/docs/container/drivers/joyent.rst
+++ b/docs/container/drivers/joyent.rst
@@ -6,7 +6,7 @@ Docker-native tools and elastic hosts make deploying on Triton as easy as runnin
There is no special software to install or configure.
Mix Docker containers with container-native Linux to extend the benefits of containerization to legacy applications and stateful services.
-.. figure:: /_static/images/provider_logos/triton.svg
+.. figure:: /_static/images/provider_logos/triton.png
:align: center
:width: 300
:target: http://joyent.com/
http://git-wip-us.apache.org/repos/asf/libcloud/blob/83c06fee/docs/examples/container/ecs/instantiate_driver.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/ecs/instantiate_driver.py b/docs/examples/container/ecs/instantiate_driver.py
index 19400db..d053c79 100644
--- a/docs/examples/container/ecs/instantiate_driver.py
+++ b/docs/examples/container/ecs/instantiate_driver.py
@@ -3,7 +3,9 @@ from libcloud.container.providers import get_driver
cls = get_driver(Provider.ECS)
-conn = cls(access_id='AKIAI7OR4GWEEPRIFBBA', secret='xiKazLqsAgMQ4c3rC2RSXHBJrJTqNZmjYcXHsYXO', region='ap-southeast-2')
+conn = cls(access_id='AKIAI7OR4GWEEPRIFBBA',
+ secret='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',
+ region='ap-southeast-2')
for container in conn.list_containers():
print(container.name)
[33/50] libcloud git commit: install graphviz via easy_install
Posted by an...@apache.org.
install graphviz via easy_install
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c6a57a82
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c6a57a82
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c6a57a82
Branch: refs/heads/trunk
Commit: c6a57a8207471589cff87457464afb748dfd90cd
Parents: 88390ae
Author: anthony-shaw <an...@gmail.com>
Authored: Thu Jan 7 20:48:15 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Thu Jan 7 20:48:15 2016 +1100
----------------------------------------------------------------------
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c6a57a82/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index 8ace6bd..ae5b19d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,7 +26,7 @@ matrix:
env: ENV=docs
before_script: TOX_ENV=docs-travis
before_install:
- - sudo apt-get -qq install graphviz > /dev/null
+ - easy_install graphviz
install:
- TOX_ENV=py$TRAVIS_PYTHON_VERSION
[08/50] libcloud git commit: An additional driver to demonstrate the
cluster capabilities. driver is WIP. The Amazon ECS driver
Posted by an...@apache.org.
An additional driver to demonstrate the cluster capabilities. driver is WIP. The Amazon ECS driver
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/f1674deb
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/f1674deb
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/f1674deb
Branch: refs/heads/trunk
Commit: f1674debdea969a3ef037c50200fe6451d23ad29
Parents: 6a4a772
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Dec 28 20:57:09 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Dec 28 20:57:09 2015 +1100
----------------------------------------------------------------------
libcloud/container/base.py | 15 +-
libcloud/container/drivers/docker.py | 2 +-
libcloud/container/drivers/ecs.py | 291 +++++++++++++++++++
.../container/fixtures/ecs/createcluster.json | 11 +
.../container/fixtures/ecs/deletecluster.json | 11 +
.../fixtures/ecs/describeclusters.json | 14 +
.../container/fixtures/ecs/describetasks.json | 46 +++
libcloud/test/container/test_ecs.py | 88 ++++++
libcloud/test/secrets.py-dist | 1 +
9 files changed, 471 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f1674deb/libcloud/container/base.py
----------------------------------------------------------------------
diff --git a/libcloud/container/base.py b/libcloud/container/base.py
index ec28308..b70f1bd 100644
--- a/libcloud/container/base.py
+++ b/libcloud/container/base.py
@@ -341,17 +341,17 @@ class ContainerDriver(BaseDriver):
raise NotImplementedError(
'restart_container not implemented for this driver')
- def delete_container(self, container):
+ def destroy_container(self, container):
"""
- Delete a deployed container
+ Destroy a deployed container
- :param container: The container to delete
+ :param container: The container to destroy
:type container: :class:`Container`
:rtype: :class:`Container`
"""
raise NotImplementedError(
- 'delete_container not implemented for this driver')
+ 'destroy_container not implemented for this driver')
def list_locations(self):
"""
@@ -377,14 +377,15 @@ class ContainerDriver(BaseDriver):
raise NotImplementedError(
'create_cluster not implemented for this driver')
- def delete_cluster(self, cluster):
+ def destroy_cluster(self, cluster):
"""
Delete a cluster
- :rtype: ``list`` of :class:`ClusterLocation`
+ :return: ``True`` if the destroy was successful, otherwise ``False``.
+ :rtype: ``bool``
"""
raise NotImplementedError(
- 'delete_cluster not implemented for this driver')
+ 'destroy_cluster not implemented for this driver')
def list_clusters(self, location=None):
"""
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f1674deb/libcloud/container/drivers/docker.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/docker.py b/libcloud/container/drivers/docker.py
index 9d60d20..981411a 100644
--- a/libcloud/container/drivers/docker.py
+++ b/libcloud/container/drivers/docker.py
@@ -451,7 +451,7 @@ class DockerContainerDriver(ContainerDriver):
raise DockerException(result.status,
'failed to restart container')
- def delete_container(self, container):
+ def destroy_container(self, container):
"""
Remove a container
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f1674deb/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
new file mode 100644
index 0000000..c4ea82a
--- /dev/null
+++ b/libcloud/container/drivers/ecs.py
@@ -0,0 +1,291 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+__all__ = [
+ 'ElasticContainerDriver'
+]
+
+
+from libcloud.container.base import (ContainerDriver, Container,
+ ContainerCluster, ContainerImage)
+from libcloud.container.types import ContainerState
+from libcloud.common.base import JsonResponse
+from libcloud.common.aws import SignedAWSConnection
+
+
+VERSION = '2014-11-13'
+HOST = 'ecs.%s.amazonaws.com'
+ROOT = '/%s/' % (VERSION)
+TARGET_BASE = 'AmazonEC2ContainerServiceV%s' % (VERSION.replace('-', ''))
+
+
+class ECSResponse(JsonResponse):
+ """
+ Amazon ECS response class.
+ ECS API uses JSON unlike the s3, elb drivers
+ """
+
+
+class ECSConnection(SignedAWSConnection):
+ version = VERSION
+ host = HOST
+ responseCls = ECSResponse
+ service_name = 'ecs'
+
+
+class ElasticContainerDriver(ContainerDriver):
+ name = 'Amazon Elastic Container Service'
+ website = 'https://aws.amazon.com/ecs/details/'
+ connectionCls = ECSConnection
+ supports_clusters = False
+ status_map = {
+ 'RUNNING': ContainerState.RUNNING
+ }
+
+ def __init__(self, access_id, secret, region):
+ super(ElasticContainerDriver, self).__init__(access_id, secret)
+ self.region = region
+ self.connection.host = HOST % (region)
+
+ def list_clusters(self):
+ """
+ Get a list of potential locations to deploy clusters into
+
+ :param location: The location to search in
+ :type location: :class:`ClusterLocation`
+
+ :rtype: ``list`` of :class:`ContainerCluster`
+ """
+ params = {'Action': 'DescribeClusters'}
+ data = self.connection.request(
+ ROOT,
+ params=params,
+ headers=self._get_headers(params['Action'])
+ ).object
+ return self._to_clusters(data)
+
+ def create_cluster(self, name, location=None):
+ """
+ Create a container cluster
+
+ :param name: The name of the cluster
+ :type name: ``str``
+
+ :param location: The location to create the cluster in
+ :type location: :class:`ClusterLocation`
+
+ :rtype: :class:`ContainerCluster`
+ """
+ params = {'Action': 'CreateCluster'}
+ request = {'clusterName': name}
+ response = self.connection.request(
+ ROOT,
+ params=params,
+ data=request,
+ headers=self._get_headers(params['Action'])
+ ).object
+ return self._to_cluster(response['cluster'])
+
+ def destroy_cluster(self, cluster):
+ """
+ Delete a cluster
+
+ :return: ``True`` if the destroy was successful, otherwise ``False``.
+ :rtype: ``bool``
+ """
+ params = {'Action': 'DeleteCluster'}
+ request = {'cluster': cluster.id}
+ data = self.connection.request(
+ ROOT,
+ params=params,
+ data=request,
+ headers=self._get_headers(params['Action'])
+ ).object
+ return data['cluster']['status'] == 'INACTIVE'
+
+ def install_image(self, path):
+ """
+ Install a container image from a remote path.
+
+ :param path: Path to the container image
+ :type path: ``str``
+
+ :rtype: :class:`ContainerImage`
+ """
+ raise NotImplementedError(
+ 'install_image not implemented for this driver')
+
+ def list_images(self):
+ """
+ List the installed container images
+
+ :rtype: ``list`` of :class:`ContainerImage`
+ """
+ raise NotImplementedError(
+ 'list_images not implemented for this driver')
+
+ def list_containers(self, image=None, cluster=None):
+ """
+ List the deployed container images
+
+ :param image: Filter to containers with a certain image
+ :type image: :class:`ContainerImage`
+
+ :param cluster: Filter to containers in a cluster
+ :type cluster: :class:`ContainerCluster`
+
+ :rtype: ``list`` of :class:`Container`
+ """
+ params = {'Action': 'DescribeTasks'}
+ request = None
+ if cluster is not None:
+ request = {'cluster': cluster.id}
+ response = self.connection.request(
+ ROOT,
+ params=params,
+ data=request,
+ headers=self._get_headers(params['Action'])
+ ).object
+ containers = []
+ for task in response['tasks']:
+ containers.extend(self._to_containers(task))
+ return containers
+
+ def deploy_container(self, name, image, cluster=None,
+ parameters=None, start=True):
+ """
+ Deploy an installed container image
+
+ :param name: The name of the new container
+ :type name: ``str``
+
+ :param image: The container image to deploy
+ :type image: :class:`ContainerImage`
+
+ :param cluster: The cluster to deploy to, None is default
+ :type cluster: :class:`ContainerCluster`
+
+ :param parameters: Container Image parameters
+ :type parameters: ``str``
+
+ :param start: Start the container on deployment
+ :type start: ``bool``
+
+ :rtype: :class:`Container`
+ """
+ raise NotImplementedError(
+ 'deploy_container not implemented for this driver')
+
+ def get_container(self, id):
+ """
+ Get a container by ID
+
+ :param id: The ID of the container to get
+ :type id: ``str``
+
+ :rtype: :class:`Container`
+ """
+ raise NotImplementedError(
+ 'get_container not implemented for this driver')
+
+ def start_container(self, container):
+ """
+ Start a deployed container
+
+ :param container: The container to start
+ :type container: :class:`Container`
+
+ :rtype: :class:`Container`
+ """
+ raise NotImplementedError(
+ 'start_container not implemented for this driver')
+
+ def stop_container(self, container):
+ """
+ Stop a deployed container
+
+ :param container: The container to stop
+ :type container: :class:`Container`
+
+ :rtype: :class:`Container`
+ """
+ raise NotImplementedError(
+ 'stop_container not implemented for this driver')
+
+ def restart_container(self, container):
+ """
+ Restart a deployed container
+
+ :param container: The container to restart
+ :type container: :class:`Container`
+
+ :rtype: :class:`Container`
+ """
+ raise NotImplementedError(
+ 'restart_container not implemented for this driver')
+
+ def destroy_container(self, container):
+ """
+ Destroy a deployed container
+
+ :param container: The container to destroy
+ :type container: :class:`Container`
+
+ :rtype: :class:`Container`
+ """
+ raise NotImplementedError(
+ 'destroy_container not implemented for this driver')
+
+ def _get_headers(self, action):
+ return {'x-amz-target': '%s.%s' %
+ (TARGET_BASE, action)}
+
+ def _to_clusters(self, data):
+ clusters = []
+ for cluster in data['clusters']:
+ clusters.append(self._to_cluster(cluster))
+ return clusters
+
+ def _to_cluster(self, data):
+ return ContainerCluster(
+ id=data['clusterArn'],
+ name=data['clusterName'],
+ driver=self.connection.driver
+ )
+
+ def _to_containers(self, data):
+ clusters = []
+ for cluster in data['containers']:
+ clusters.append(self._to_container(cluster))
+ return clusters
+
+ def _to_container(self, data):
+ return Container(
+ id=data['containerArn'],
+ name=data['name'],
+ image=ContainerImage(
+ id=None,
+ name=data['name'],
+ path=None,
+ version=None,
+ driver=self.connection.driver
+ ),
+ ip_addresses=None,
+ state=self.status_map.get(data['lastStatus'], None),
+ extra={
+ 'taskArn': data['taskArn']
+ },
+ driver=self.connection.driver
+ )
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f1674deb/libcloud/test/container/fixtures/ecs/createcluster.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/createcluster.json b/libcloud/test/container/fixtures/ecs/createcluster.json
new file mode 100644
index 0000000..1fb35e6
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/createcluster.json
@@ -0,0 +1,11 @@
+{
+ "cluster": {
+ "activeServicesCount": 0,
+ "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/jim",
+ "clusterName": "jim",
+ "pendingTasksCount": 0,
+ "registeredContainerInstancesCount": 0,
+ "runningTasksCount": 0,
+ "status": "ACTIVE"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f1674deb/libcloud/test/container/fixtures/ecs/deletecluster.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/deletecluster.json b/libcloud/test/container/fixtures/ecs/deletecluster.json
new file mode 100644
index 0000000..94d5aa2
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/deletecluster.json
@@ -0,0 +1,11 @@
+{
+ "cluster": {
+ "activeServicesCount": 0,
+ "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/jim",
+ "clusterName": "jim",
+ "pendingTasksCount": 0,
+ "registeredContainerInstancesCount": 0,
+ "runningTasksCount": 0,
+ "status": "INACTIVE"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f1674deb/libcloud/test/container/fixtures/ecs/describeclusters.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/describeclusters.json b/libcloud/test/container/fixtures/ecs/describeclusters.json
new file mode 100644
index 0000000..1e89426
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/describeclusters.json
@@ -0,0 +1,14 @@
+{
+ "clusters": [
+ {
+ "activeServicesCount": 1,
+ "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/default",
+ "clusterName": "default",
+ "pendingTasksCount": 0,
+ "registeredContainerInstancesCount": 0,
+ "runningTasksCount": 0,
+ "status": "ACTIVE"
+ }
+ ],
+ "failures": []
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f1674deb/libcloud/test/container/fixtures/ecs/describetasks.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/describetasks.json b/libcloud/test/container/fixtures/ecs/describetasks.json
new file mode 100644
index 0000000..d8e0624
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/describetasks.json
@@ -0,0 +1,46 @@
+{
+ "failures": [],
+ "tasks": [
+ {
+ "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/default",
+ "containerInstanceArn": "arn:aws:ecs:us-east-1:012345678910:container-instance/84818520-995f-4d94-9d70-7714bacc2953",
+ "containers": [
+ {
+ "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/76c980a8-2454-4a9c-acc4-9eb103117273",
+ "lastStatus": "RUNNING",
+ "name": "mysql",
+ "networkBindings": [],
+ "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe"
+ },
+ {
+ "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/e3c69b8f-f15e-4d33-8093-282c2d2325e9",
+ "lastStatus": "RUNNING",
+ "name": "wordpress",
+ "networkBindings": [
+ {
+ "bindIP": "0.0.0.0",
+ "containerPort": 80,
+ "hostPort": 80
+ }
+ ],
+ "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe"
+ }
+ ],
+ "desiredStatus": "RUNNING",
+ "lastStatus": "RUNNING",
+ "overrides": {
+ "containerOverrides": [
+ {
+ "name": "mysql"
+ },
+ {
+ "name": "wordpress"
+ }
+ ]
+ },
+ "startedBy": "ecs-svc/9223370606521064774",
+ "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe",
+ "taskDefinitionArn": "arn:aws:ecs:us-east-1:012345678910:task-definition/hello_world:10"
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f1674deb/libcloud/test/container/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_ecs.py b/libcloud/test/container/test_ecs.py
new file mode 100644
index 0000000..81bdf09
--- /dev/null
+++ b/libcloud/test/container/test_ecs.py
@@ -0,0 +1,88 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+
+from libcloud.test import unittest
+
+from libcloud.container.base import ContainerCluster
+from libcloud.container.drivers.ecs import ElasticContainerDriver
+
+from libcloud.utils.py3 import httplib
+from libcloud.test.secrets import CONTAINER_PARAMS_ECS
+from libcloud.test.file_fixtures import ContainerFileFixtures
+from libcloud.test import MockHttp
+
+
+class ElasticContainerDriverTestCase(unittest.TestCase):
+
+ def setUp(self):
+ ElasticContainerDriver.connectionCls.conn_classes = (
+ ECSMockHttp, ECSMockHttp)
+ ECSMockHttp.type = None
+ ECSMockHttp.use_param = 'a'
+ self.driver = ElasticContainerDriver(*CONTAINER_PARAMS_ECS)
+
+ def test_list_clusters(self):
+ clusters = self.driver.list_clusters()
+ self.assertEqual(len(clusters), 1)
+ self.assertEqual(clusters[0].id, 'arn:aws:ecs:us-east-1:012345678910:cluster/default')
+ self.assertEqual(clusters[0].name, 'default')
+
+ def test_create_cluster(self):
+ cluster = self.driver.create_cluster('jim')
+ self.assertEqual(cluster.name, 'jim')
+
+ def test_destroy_cluster(self):
+ self.assertTrue(
+ self.driver.destroy_cluster(
+ ContainerCluster(
+ id='arn:aws:ecs:us-east-1:012345678910:cluster/jim',
+ name='jim',
+ driver=self.driver)))
+
+ def test_list_containers(self):
+ containers = self.driver.list_containers()
+ self.assertEqual(len(containers), 2)
+
+ def test_list_containers_for_cluster(self):
+ cluster = self.driver.list_clusters()[0]
+ containers = self.driver.list_containers(cluster=cluster)
+ self.assertEqual(len(containers), 2)
+
+
+class ECSMockHttp(MockHttp):
+ fixtures = ContainerFileFixtures('ecs')
+ fixture_map = {
+ 'DescribeClusters': 'describeclusters.json',
+ 'CreateCluster': 'createcluster.json',
+ 'DeleteCluster': 'deletecluster.json',
+ 'DescribeTasks': 'describetasks.json'
+ }
+
+ def _2014_11_13(
+ self, method, url, body, headers):
+ target = headers['x-amz-target']
+ if target is not None:
+ type = target.split('.')[-1]
+ if type is None or self.fixture_map.get(type) is None:
+ raise AssertionError('Unsupported request type %s' % (target))
+ body = self.fixtures.load(self.fixture_map.get(type))
+ else:
+ raise AssertionError('Unsupported method')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f1674deb/libcloud/test/secrets.py-dist
----------------------------------------------------------------------
diff --git a/libcloud/test/secrets.py-dist b/libcloud/test/secrets.py-dist
index dad7724..608fdbd 100644
--- a/libcloud/test/secrets.py-dist
+++ b/libcloud/test/secrets.py-dist
@@ -83,3 +83,4 @@ DNS_PARAMS_CLOUDFLARE = ('user@example.com', 'key')
# Container
CONTAINER_PARAMS_DOCKER = ('user', 'password')
+CONTAINER_PARAMS_ECS = ('user', 'password', 'region')
[36/50] libcloud git commit: removed stray merge tag
Posted by an...@apache.org.
removed stray merge tag
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/5aa34e10
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/5aa34e10
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/5aa34e10
Branch: refs/heads/trunk
Commit: 5aa34e10d1dd01a972c8248faa2e1ea5d3618a83
Parents: 3280fc3
Author: anthony-shaw <an...@gmail.com>
Authored: Sat Jan 9 16:35:49 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sat Jan 9 16:35:49 2016 +1100
----------------------------------------------------------------------
docs/index.rst | 2 --
1 file changed, 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/5aa34e10/docs/index.rst
----------------------------------------------------------------------
diff --git a/docs/index.rst b/docs/index.rst
index aeba4a1..d44bc36 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -16,8 +16,6 @@ Resource you can manage with Libcloud are divided in the following categories:
* :doc:`Container Services </container/index>` - container virtualization like Docker and Rkt as well as container based services
* :doc:`Backup as a Service </backup/index>` - services such as Amazon EBS and OpenStack Freezer
->>>>>>> trunk
-
.. figure:: /_static/images/supported_providers.png
:align: center
[34/50] libcloud git commit: travis containers can't install deps,
so had to turn that off
Posted by an...@apache.org.
travis containers can't install deps, so had to turn that off
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/5e6b38f1
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/5e6b38f1
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/5e6b38f1
Branch: refs/heads/trunk
Commit: 5e6b38f1eba3107e25e478a58df6814c379716aa
Parents: c6a57a8
Author: anthony-shaw <an...@gmail.com>
Authored: Thu Jan 7 20:55:47 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Thu Jan 7 20:55:47 2016 +1100
----------------------------------------------------------------------
.travis.yml | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/5e6b38f1/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index ae5b19d..df48842 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,10 +8,8 @@ python:
- 3.4
- 3.5
- "pypy"
-sudo: false
os:
- linux
- - osx
env:
matrix:
@@ -26,7 +24,8 @@ matrix:
env: ENV=docs
before_script: TOX_ENV=docs-travis
before_install:
- - easy_install graphviz
+ - sudo apt-get update -qq
+ - sudo apt-get install -y graphviz
install:
- TOX_ENV=py$TRAVIS_PYTHON_VERSION
[17/50] libcloud git commit: Extend the API ECS driver to support
'services', updated methods to POST. Working on POST signatures for v4,
which is required in the ECS API
Posted by an...@apache.org.
Extend the API ECS driver to support 'services', updated methods to POST. Working on POST signatures for v4, which is required in the ECS API
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/b64d2fa0
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/b64d2fa0
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/b64d2fa0
Branch: refs/heads/trunk
Commit: b64d2fa0e03b4d5a59caa302a481edb108494c32
Parents: a1adaae
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Dec 30 21:19:59 2015 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Dec 30 21:19:59 2015 +1100
----------------------------------------------------------------------
libcloud/common/aws.py | 12 ++-
libcloud/container/drivers/ecs.py | 137 +++++++++++++++++++++++++++++----
2 files changed, 132 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b64d2fa0/libcloud/common/aws.py
----------------------------------------------------------------------
diff --git a/libcloud/common/aws.py b/libcloud/common/aws.py
index c0ac9b8..4d7523e 100644
--- a/libcloud/common/aws.py
+++ b/libcloud/common/aws.py
@@ -26,6 +26,7 @@ except ImportError:
from xml.etree import ElementTree as ET
from libcloud.common.base import ConnectionUserAndKey, XmlResponse, BaseDriver
+from libcloud.common.base import JsonResponse
from libcloud.common.types import InvalidCredsError, MalformedResponseError
from libcloud.utils.py3 import b, httplib, urlquote
from libcloud.utils.xml import findtext, findall
@@ -250,8 +251,8 @@ class AWSRequestSignerAlgorithmV4(AWSRequestSigner):
def _get_authorization_v4_header(self, params, headers, dt, method='GET',
path='/'):
- assert method == 'GET', 'AWS Signature V4 not implemented for ' \
- 'other methods than GET'
+ assert method in ['GET', 'POST'], 'AWS Signature V4 not implemented for ' \
+ 'other methods than GET and POST'
credentials_scope = self._get_credential_scope(dt=dt)
signed_headers = self._get_signed_headers(headers=headers)
@@ -368,6 +369,13 @@ class SignedAWSConnection(AWSTokenConnection):
return params, headers
+class AWSJsonResponse(JsonResponse):
+ """
+ Amazon ECS response class.
+ ECS API uses JSON unlike the s3, elb drivers
+ """
+
+
def _sign(key, msg, hex=False):
if hex:
return hmac.new(b(key), b(msg), hashlib.sha256).hexdigest()
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b64d2fa0/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index 9aa98d3..6485b10 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -21,34 +21,25 @@ __all__ = [
from libcloud.container.base import (ContainerDriver, Container,
ContainerCluster, ContainerImage)
from libcloud.container.types import ContainerState
-from libcloud.common.base import JsonResponse
-from libcloud.common.aws import SignedAWSConnection
-
+from libcloud.common.aws import SignedAWSConnection, AWSJsonResponse
VERSION = '2014-11-13'
HOST = 'ecs.%s.amazonaws.com'
-ROOT = '/%s/' % (VERSION)
+ROOT = '/'
TARGET_BASE = 'AmazonEC2ContainerServiceV%s' % (VERSION.replace('-', ''))
-class ECSResponse(JsonResponse):
- """
- Amazon ECS response class.
- ECS API uses JSON unlike the s3, elb drivers
- """
-
-
-class ECSConnection(SignedAWSConnection):
+class ECSJsonConnection(SignedAWSConnection):
version = VERSION
host = HOST
- responseCls = ECSResponse
+ responseCls = AWSJsonResponse
service_name = 'ecs'
class ElasticContainerDriver(ContainerDriver):
name = 'Amazon Elastic Container Service'
website = 'https://aws.amazon.com/ecs/details/'
- connectionCls = ECSConnection
+ connectionCls = ECSJsonConnection
supports_clusters = False
status_map = {
'RUNNING': ContainerState.RUNNING
@@ -57,8 +48,12 @@ class ElasticContainerDriver(ContainerDriver):
def __init__(self, access_id, secret, region):
super(ElasticContainerDriver, self).__init__(access_id, secret)
self.region = region
+ self.region_name = region
self.connection.host = HOST % (region)
+ def _ex_connection_class_kwargs(self):
+ return {'signature_version': '4'}
+
def list_clusters(self):
"""
Get a list of potential locations to deploy clusters into
@@ -71,6 +66,7 @@ class ElasticContainerDriver(ContainerDriver):
params = {'Action': 'DescribeClusters'}
data = self.connection.request(
ROOT,
+ method='POST',
headers=self._get_headers(params['Action'])
).object
return self._to_clusters(data)
@@ -91,6 +87,7 @@ class ElasticContainerDriver(ContainerDriver):
request = {'clusterName': name}
response = self.connection.request(
ROOT,
+ method='POST',
data=request,
headers=self._get_headers(params['Action'])
).object
@@ -107,6 +104,7 @@ class ElasticContainerDriver(ContainerDriver):
request = {'cluster': cluster.id}
data = self.connection.request(
ROOT,
+ method='POST',
data=request,
headers=self._get_headers(params['Action'])
).object
@@ -153,6 +151,7 @@ class ElasticContainerDriver(ContainerDriver):
request['family'] = image.name
list_response = self.connection.request(
ROOT,
+ method='POST',
data=request,
headers=self._get_headers('ListTasks')
).object
@@ -206,6 +205,7 @@ class ElasticContainerDriver(ContainerDriver):
data['family'] = name
response = self.connection.request(
ROOT,
+ method='POST',
data=data,
headers=self._get_headers('RegisterTaskDefinition')
).object
@@ -264,6 +264,7 @@ class ElasticContainerDriver(ContainerDriver):
request = {'task': container.extra['taskArn']}
response = self.connection.request(
ROOT,
+ method='POST',
data=request,
headers=self._get_headers('StopTask')
).object
@@ -313,6 +314,7 @@ class ElasticContainerDriver(ContainerDriver):
'taskDefinition': task_arn}
response = self.connection.request(
ROOT,
+ method='POST',
data=request,
headers=self._get_headers('RunTask')
).object
@@ -333,6 +335,7 @@ class ElasticContainerDriver(ContainerDriver):
describe_request = {'tasks': task_arns}
descripe_response = self.connection.request(
ROOT,
+ method='POST',
data=describe_request,
headers=self._get_headers('DescribeTasks')
).object
@@ -342,9 +345,113 @@ class ElasticContainerDriver(ContainerDriver):
task, task['taskDefinitionArn']))
return containers
+ def ex_create_service(self, name, cluster,
+ task_definition, desired_count=1):
+ """
+ Runs and maintains a desired number of tasks from a specified
+ task definition. If the number of tasks running in a service
+ drops below desired_count, Amazon ECS spawns another
+ instantiation of the task in the specified cluster.
+
+ :param name: the name of the service
+ :type name: ``str``
+
+ :param cluster: The cluster to run the service on
+ :type cluster: :class:`ContainerCluster`
+
+ :param task_definition: The task definition name or ARN for the
+ service
+ :type task_definition: ``str``
+
+ :param desired_count: The desired number of tasks to be running
+ at any one time
+ :type desired_count: ``int``
+
+ :rtype: ``object`` The service object
+ """
+ request = {
+ 'serviceName': name,
+ 'taskDefinition': task_definition,
+ 'desiredCount': desired_count,
+ 'cluster': cluster.id}
+ response = self.connection.request(
+ ROOT,
+ method='POST',
+ data=request,
+ headers=self._get_headers('CreateService')
+ ).object
+ return response
+
+ def ex_list_service_arns(self, cluster=None):
+ """
+ List the services
+
+ :param cluster: The cluster hosting the services
+ :type cluster: :class:`ContainerCluster`
+
+ :rtype: ``list`` of ``str``
+ """
+ request = {}
+ if cluster is not None:
+ request['cluster'] = cluster.id
+ response = self.connection.request(
+ ROOT,
+ method='POST',
+ data=request,
+ headers=self._get_headers('ListServices')
+ ).object
+ return response['serviceArns']
+
+ def ex_describe_service(self, cluster, service_arn):
+ """
+ Get the details of a service
+
+ :param cluster: The hosting cluster
+ :type cluster: :class:`ContainerCluster`
+
+ :param service_arn: The service ARN to describe
+ :type service_arn: ``str``
+
+ :return: The service object
+ :rtype: ``object``
+ """
+ request = {'services': [service_arn]}
+ if cluster is not None:
+ request['cluster'] = cluster.id
+ response = self.connection.request(
+ ROOT,
+ method='POST',
+ data=request,
+ headers=self._get_headers('DescribeServices')
+ ).object
+ return response['services'][0]
+
+ def ex_destroy_service(self, cluster, service_arn):
+ """
+ Deletes a service
+
+ :param cluster: The target cluster
+ :type cluster: :class:`ContainerCluster`
+
+ :param service_arn: The service ARN to destroy
+ :type service_arn: ``str``
+ """
+ request = {
+ 'service': service_arn,
+ 'cluster': cluster.id}
+ response = self.connection.request(
+ ROOT,
+ method='POST',
+ data=request,
+ headers=self._get_headers('DeleteService')
+ ).object
+ return response
+
def _get_headers(self, action):
return {'x-amz-target': '%s.%s' %
- (TARGET_BASE, action)}
+ (TARGET_BASE, action),
+ 'Content-Type': 'application/x-amz-json-1.1'
+ }
def _to_clusters(self, data):
clusters = []
[49/50] libcloud git commit: Merge branch 'trunk' into
LIBCLOUD-781_containers
Posted by an...@apache.org.
Merge branch 'trunk' into LIBCLOUD-781_containers
# Conflicts:
# .travis.yml
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/65bc1ddf
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/65bc1ddf
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/65bc1ddf
Branch: refs/heads/trunk
Commit: 65bc1ddff16a6a229d30cf839f753abe60340a4b
Parents: c8c6c2f 99d6bce
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Jan 20 10:15:08 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Jan 20 10:15:08 2016 +1100
----------------------------------------------------------------------
.travis.yml | 13 +-
CHANGES.rst | 21 +
contrib/scrape-ec2-prices.py | 2 +
.../_static/images/provider_logos/backblaze.png | Bin 0 -> 6864 bytes
docs/dns/drivers/auroradns.rst | 19 +
.../dns/auroradns/enable_disable_record.py | 2 +-
docs/examples/dns/auroradns/health_checks.py | 21 +
.../storage/backblaze_b2/instantiate.py | 8 +
docs/other/ssl-certificate-validation.rst | 43 ++
docs/storage/_supported_methods_cdn.rst | 2 +
docs/storage/_supported_methods_main.rst | 2 +
docs/storage/_supported_providers.rst | 2 +
docs/storage/drivers/auroraobjects.rst | 3 -
docs/storage/drivers/backblaze_b2.rst | 40 ++
libcloud/compute/drivers/ec2.py | 42 ++
libcloud/data/pricing.json | 34 +-
libcloud/dns/drivers/auroradns.py | 385 +++++++++++++++-
libcloud/httplib_ssl.py | 68 ++-
libcloud/storage/drivers/backblaze_b2.py | 462 +++++++++++++++++++
libcloud/storage/providers.py | 2 +
libcloud/storage/types.py | 1 +
.../dns/fixtures/auroradns/zone_create.json | 11 +
.../fixtures/auroradns/zone_example_com.json | 11 +
.../zone_example_com_health_check.json | 14 +
.../zone_example_com_health_checks.json | 44 ++
.../zone_example_com_record_localhost.json | 12 +
.../auroradns/zone_example_com_records.json | 38 ++
.../test/dns/fixtures/auroradns/zone_list.json | 24 +
libcloud/test/dns/test_auroradns.py | 231 +++++++++-
.../fixtures/backblaze_b2/b2_create_bucket.json | 6 +
.../fixtures/backblaze_b2/b2_delete_bucket.json | 6 +
.../backblaze_b2/b2_delete_file_version.json | 4 +
.../backblaze_b2/b2_get_upload_url.json | 5 +
.../fixtures/backblaze_b2/b2_hide_file.json | 7 +
.../fixtures/backblaze_b2/b2_list_buckets.json | 22 +
.../backblaze_b2/b2_list_file_names.json | 34 ++
.../backblaze_b2/b2_list_file_versions.json | 69 +++
.../fixtures/backblaze_b2/b2_upload_file.json | 10 +
libcloud/test/storage/test_backblaze_b2.py | 213 +++++++++
libcloud/test/test_httplib_ssl.py | 37 ++
40 files changed, 1915 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/65bc1ddf/.travis.yml
----------------------------------------------------------------------
diff --cc .travis.yml
index af0690d,a48465f..5a635be
--- a/.travis.yml
+++ b/.travis.yml
@@@ -8,27 -8,26 +8,28 @@@ python
- 3.4
- 3.5
- "pypy"
-sudo: false
os:
- linux
- - osx
+ # Note: OS X has been broken on Travis for a long time
+ #- osx
env:
matrix:
fast_finish: true
-- allow_failures:
-- - os: osx
include:
- - python: 2.7
+ - sudo: required
+ python: 2.7
env: ENV=lint
before_script: TOX_ENV=lint
- - python: 2.7
+ - sudo: required
+ python: 2.7
env: ENV=docs
before_script: TOX_ENV=docs-travis
+ before_install:
+ - sudo apt-get update -qq
+ - sudo apt-get install -y graphviz
+ # Trigger ReadTheDocs build
+ after_success: ./contrib/trigger_rtd_build.py 8284
install:
- TOX_ENV=py$TRAVIS_PYTHON_VERSION
http://git-wip-us.apache.org/repos/asf/libcloud/blob/65bc1ddf/CHANGES.rst
----------------------------------------------------------------------
diff --cc CHANGES.rst
index 68aa8de,a6fffb3..4cbf09f
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@@ -46,8 -58,12 +63,12 @@@ DN
(GITHUB-675)
[Wido den Hollander]
+ - Improve unit tests of Aurora DNS driver
+ (GITHUB-679)
+ [Wido den Hollander]
+
Changes with Apache Libcloud 0.20.0
------------------------------------
+-------------------------------------------
General
~~~~~~~
[26/50] libcloud git commit: Updated fixtures for ECS from further
field testing. updated docs with an example of how to deploy.
Posted by an...@apache.org.
Updated fixtures for ECS from further field testing. updated docs with an example of how to deploy.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c5edd3a2
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c5edd3a2
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c5edd3a2
Branch: refs/heads/trunk
Commit: c5edd3a2513c370648f8540c16a173a09adc1b26
Parents: 9274450
Author: anthony-shaw <an...@gmail.com>
Authored: Sun Jan 3 21:41:05 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Sun Jan 3 21:41:05 2016 +1100
----------------------------------------------------------------------
docs/container/drivers/ecs.rst | 6 +++
docs/examples/container/ecs/deploy_container.py | 20 +++++++
libcloud/container/drivers/ecs.py | 50 +++++++----------
.../container/fixtures/ecs/createcluster.json | 18 +++----
.../container/fixtures/ecs/deletecluster.json | 18 +++----
.../container/fixtures/ecs/listclusters.json | 1 +
.../fixtures/ecs/registertaskdefinition.json | 41 +++++++-------
.../test/container/fixtures/ecs/runtask.json | 57 ++++++++------------
libcloud/test/container/test_ecs.py | 7 +--
9 files changed, 109 insertions(+), 109 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5edd3a2/docs/container/drivers/ecs.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/ecs.rst b/docs/container/drivers/ecs.rst
index 138eceb..20ab400 100644
--- a/docs/container/drivers/ecs.rst
+++ b/docs/container/drivers/ecs.rst
@@ -17,6 +17,12 @@ Instantiating the driver
.. literalinclude:: /examples/container/ecs/instantiate_driver.py
:language: python
+
+Deploying a container
+---------------------
+
+.. literalinclude:: /examples/container/ecs/deploy_container.py
+ :language: python
API Docs
--------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5edd3a2/docs/examples/container/ecs/deploy_container.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/ecs/deploy_container.py b/docs/examples/container/ecs/deploy_container.py
new file mode 100644
index 0000000..f9bc9df
--- /dev/null
+++ b/docs/examples/container/ecs/deploy_container.py
@@ -0,0 +1,20 @@
+from libcloud.container.base import ContainerImage
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+
+cls = get_driver(Provider.ECS)
+
+conn = cls(access_id='AKIAI7OR4GWEEPRIFBBA',
+ secret='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',
+ region='ap-southeast-2')
+
+container = conn.deploy_container(
+ name='my-simple-app',
+ image=ContainerImage(
+ id=None,
+ name='simple-app',
+ path='simple-app',
+ version=None,
+ driver=conn
+ )
+)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5edd3a2/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index 746c176..d390201 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -68,12 +68,18 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: ``list`` of :class:`ContainerCluster`
"""
- params = {'Action': 'DescribeClusters'}
- data = self.connection.request(
+ listdata = self.connection.request(
ROOT,
method='POST',
data=json.dumps({}),
- headers=self._get_headers(params['Action'])
+ headers=self._get_headers('ListClusters')
+ ).object
+ request = {'clusters': listdata['clusterArns']}
+ data = self.connection.request(
+ ROOT,
+ method='POST',
+ data=json.dumps(request),
+ headers=self._get_headers('DescribeClusters')
).object
return self._to_clusters(data)
@@ -114,28 +120,6 @@ class ElasticContainerDriver(ContainerDriver):
).object
return data['cluster']['status'] == 'INACTIVE'
- def install_image(self, path):
- """
- Install a container image from a remote path.
-
- :param path: Path to the container image
- :type path: ``str``
-
- :rtype: :class:`ContainerImage`
- """
- raise NotImplementedError(
- 'install_image not implemented for this driver')
-
- def list_images(self):
- """
- List the installed container images, in ECS these are
- equivalent to the containers within task definitions.
-
- :rtype: ``list`` of :class:`ContainerImage`
- """
- raise NotImplementedError(
- 'list_images not implemented for this driver')
-
def list_containers(self, image=None, cluster=None):
"""
List the deployed container images
@@ -188,6 +172,15 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: :class:`Container`
"""
data = {}
+ if ex_container_port is None and ex_host_port is None:
+ port_maps = []
+ else:
+ port_maps = [
+ {
+ "containerPort": ex_container_port,
+ "hostPort": ex_host_port
+ }
+ ]
data['containerDefinitions'] = [
{
"mountPoints": [],
@@ -196,12 +189,7 @@ class ElasticContainerDriver(ContainerDriver):
"cpu": ex_cpu,
"environment": [],
"memory": ex_memory,
- "portMappings": [
- {
- "containerPort": ex_container_port,
- "hostPort": ex_host_port
- }
- ],
+ "portMappings": port_maps,
"essential": True,
"volumesFrom": []
}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5edd3a2/libcloud/test/container/fixtures/ecs/createcluster.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/createcluster.json b/libcloud/test/container/fixtures/ecs/createcluster.json
index 1fb35e6..eb6ced3 100644
--- a/libcloud/test/container/fixtures/ecs/createcluster.json
+++ b/libcloud/test/container/fixtures/ecs/createcluster.json
@@ -1,11 +1,11 @@
{
- "cluster": {
- "activeServicesCount": 0,
- "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/jim",
- "clusterName": "jim",
- "pendingTasksCount": 0,
- "registeredContainerInstancesCount": 0,
- "runningTasksCount": 0,
- "status": "ACTIVE"
- }
+ "cluster": {
+ "activeServicesCount": 0,
+ "clusterArn": "arn:aws:ecs:ap-southeast-2:647433528374:cluster/my-cluster",
+ "clusterName": "my-cluster",
+ "pendingTasksCount": 0,
+ "registeredContainerInstancesCount": 0,
+ "runningTasksCount": 0,
+ "status": "ACTIVE"
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5edd3a2/libcloud/test/container/fixtures/ecs/deletecluster.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/deletecluster.json b/libcloud/test/container/fixtures/ecs/deletecluster.json
index 94d5aa2..9c8c0cd 100644
--- a/libcloud/test/container/fixtures/ecs/deletecluster.json
+++ b/libcloud/test/container/fixtures/ecs/deletecluster.json
@@ -1,11 +1,11 @@
{
- "cluster": {
- "activeServicesCount": 0,
- "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/jim",
- "clusterName": "jim",
- "pendingTasksCount": 0,
- "registeredContainerInstancesCount": 0,
- "runningTasksCount": 0,
- "status": "INACTIVE"
- }
+ "cluster": {
+ "activeServicesCount": 0,
+ "clusterArn": "arn:aws:ecs:ap-southeast-2:647433528374:cluster/my-cluster",
+ "clusterName": "my-cluster",
+ "pendingTasksCount": 0,
+ "registeredContainerInstancesCount": 0,
+ "runningTasksCount": 0,
+ "status": "INACTIVE"
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5edd3a2/libcloud/test/container/fixtures/ecs/listclusters.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/listclusters.json b/libcloud/test/container/fixtures/ecs/listclusters.json
new file mode 100644
index 0000000..11c0d0e
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/listclusters.json
@@ -0,0 +1 @@
+{"clusterArns":["arn:aws:ecs:ap-southeast-2:647433528374:cluster/my-cluster","arn:aws:ecs:ap-southeast-2:647433528374:cluster/default"]}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5edd3a2/libcloud/test/container/fixtures/ecs/registertaskdefinition.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/registertaskdefinition.json b/libcloud/test/container/fixtures/ecs/registertaskdefinition.json
index 163061d..fd53f9d 100644
--- a/libcloud/test/container/fixtures/ecs/registertaskdefinition.json
+++ b/libcloud/test/container/fixtures/ecs/registertaskdefinition.json
@@ -1,26 +1,21 @@
{
- "taskDefinition": {
- "containerDefinitions": [
- {
- "cpu": 10,
- "environment": [
- {
- "name": "MYSQL_ROOT_PASSWORD",
- "value": "password"
- }
+ "taskDefinition": {
+ "containerDefinitions": [{
+ "cpu": 10,
+ "environment": [],
+ "essential": true,
+ "image": "simple-app",
+ "memory": 500,
+ "mountPoints": [],
+ "name": "my-simple-app",
+ "portMappings": [],
+ "volumesFrom": []
+ }
],
- "essential": true,
- "image": "mysql",
- "memory": 500,
- "mountPoints": [],
- "name": "mysql",
- "portMappings": [],
- "volumesFrom": []
- }
- ],
- "family": "jim",
- "revision": 11,
- "taskDefinitionArn": "arn:aws:ecs:us-east-1:012345678910:task-definition/hello_world:11",
- "volumes": []
- }
+ "family": "my-simple-app",
+ "revision": 1,
+ "status": "ACTIVE",
+ "taskDefinitionArn": "arn:aws:ecs:ap-southeast-2:647433528374:task-definition/my-simple-app:1",
+ "volumes": []
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5edd3a2/libcloud/test/container/fixtures/ecs/runtask.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/runtask.json b/libcloud/test/container/fixtures/ecs/runtask.json
index 70896e5..d53c97a 100644
--- a/libcloud/test/container/fixtures/ecs/runtask.json
+++ b/libcloud/test/container/fixtures/ecs/runtask.json
@@ -1,37 +1,26 @@
{
- "failures": [],
- "tasks": [
- {
- "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/default",
- "containerInstanceArn": "arn:aws:ecs:us-east-1:012345678910:container-instance/cf447635-790d-477d-be24-58a9cb819d45",
- "containers": [
- {
- "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/e1ed7aac-d9b2-4315-8726-d2432bf11868",
- "lastStatus": "PENDING",
- "name": "wordpress",
- "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/d8c67b3c-ac87-4ffe-a847-4785bc3a8b55"
- },
- {
- "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/4b69fabd-991d-4781-bbf9-7efa03c754aa",
- "lastStatus": "PENDING",
- "name": "mysql",
- "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/d8c67b3c-ac87-4ffe-a847-4785bc3a8b55"
+ "failures": [],
+ "tasks": [{
+ "clusterArn": "arn:aws:ecs:ap-southeast-2:647433528374:cluster/default",
+ "containerInstanceArn": "arn:aws:ecs:ap-southeast-2:647433528374:container-instance/13b83f4b-d557-48a6-a4d7-2b0e8068e62b",
+ "containers": [{
+ "containerArn": "arn:aws:ecs:ap-southeast-2:647433528374:container/e443d10f-dea3-481e-8a1e-966b9ad4e498",
+ "lastStatus": "PENDING",
+ "name": "my-simple-app",
+ "taskArn": "arn:aws:ecs:ap-southeast-2:647433528374:task/b7c76236-b96f-4de1-93c8-9da3c30ccc23"
+ }
+ ],
+ "createdAt": 1.45181726008E9,
+ "desiredStatus": "RUNNING",
+ "lastStatus": "PENDING",
+ "overrides": {
+ "containerOverrides": [{
+ "name": "my-simple-app"
+ }
+ ]
+ },
+ "taskArn": "arn:aws:ecs:ap-southeast-2:647433528374:task/b7c76236-b96f-4de1-93c8-9da3c30ccc23",
+ "taskDefinitionArn": "arn:aws:ecs:ap-southeast-2:647433528374:task-definition/my-simple-app:1"
}
- ],
- "desiredStatus": "RUNNING",
- "lastStatus": "PENDING",
- "overrides": {
- "containerOverrides": [
- {
- "name": "wordpress"
- },
- {
- "name": "mysql"
- }
- ]
- },
- "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/d8c67b3c-ac87-4ffe-a847-4785bc3a8b55",
- "taskDefinitionArn": "arn:aws:ecs:us-east-1:012345678910:task-definition/hello_world:11"
- }
- ]
+ ]
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5edd3a2/libcloud/test/container/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_ecs.py b/libcloud/test/container/test_ecs.py
index f0e8937..e2fdb3f 100644
--- a/libcloud/test/container/test_ecs.py
+++ b/libcloud/test/container/test_ecs.py
@@ -42,8 +42,8 @@ class ElasticContainerDriverTestCase(unittest.TestCase):
self.assertEqual(clusters[0].name, 'default')
def test_create_cluster(self):
- cluster = self.driver.create_cluster('jim')
- self.assertEqual(cluster.name, 'jim')
+ cluster = self.driver.create_cluster('my-cluster')
+ self.assertEqual(cluster.name, 'my-cluster')
def test_destroy_cluster(self):
self.assertTrue(
@@ -73,7 +73,7 @@ class ElasticContainerDriverTestCase(unittest.TestCase):
driver=self.driver
)
)
- self.assertEqual(container.id, 'arn:aws:ecs:us-east-1:012345678910:container/e1ed7aac-d9b2-4315-8726-d2432bf11868')
+ self.assertEqual(container.id, 'arn:aws:ecs:ap-southeast-2:647433528374:container/e443d10f-dea3-481e-8a1e-966b9ad4e498')
def test_get_container(self):
container = self.driver.get_container(
@@ -142,6 +142,7 @@ class ECSMockHttp(MockHttp):
'DeleteCluster': 'deletecluster.json',
'DescribeTasks': 'describetasks.json',
'ListTasks': 'listtasks.json',
+ 'ListClusters': 'listclusters.json',
'RegisterTaskDefinition': 'registertaskdefinition.json',
'RunTask': 'runtask.json',
'StopTask': 'stoptask.json'
[41/50] libcloud git commit: Extended the ECS driver to support the
new container registry API, with tests and doc examples
Posted by an...@apache.org.
Extended the ECS driver to support the new container registry API, with tests and doc examples
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/f00a9b75
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/f00a9b75
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/f00a9b75
Branch: refs/heads/trunk
Commit: f00a9b7599cb01e5885f160f2e7e31e24c0598be
Parents: d29629d
Author: anthony-shaw <an...@gmail.com>
Authored: Mon Jan 11 15:19:24 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Jan 11 15:19:24 2016 +1100
----------------------------------------------------------------------
docs/container/drivers/ecs.rst | 13 ++
.../container/ecs/container_registry.py | 30 +++++
libcloud/common/aws.py | 3 +-
libcloud/container/drivers/ecs.py | 123 +++++++++++++++----
libcloud/container/utils/docker.py | 8 +-
.../container/fixtures/ecs/createservice.json | 30 +++++
.../container/fixtures/ecs/deleteservice.json | 30 +++++
.../fixtures/ecs/describerepositories.json | 8 ++
.../fixtures/ecs/describeservices.json | 33 +++++
.../fixtures/ecs/getauthorizationtoken.json | 9 ++
.../test/container/fixtures/ecs/listimages.json | 7 ++
.../container/fixtures/ecs/listservices.json | 6 +
libcloud/test/container/test_ecs.py | 41 ++++++-
13 files changed, 309 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/docs/container/drivers/ecs.rst
----------------------------------------------------------------------
diff --git a/docs/container/drivers/ecs.rst b/docs/container/drivers/ecs.rst
index fbde93f..4dc3912 100644
--- a/docs/container/drivers/ecs.rst
+++ b/docs/container/drivers/ecs.rst
@@ -34,6 +34,19 @@ You can use this class for fetching images to deploy to services like ECS
.. literalinclude:: /examples/container/docker_hub.py
:language: python
+Deploying a container from Amazon Elastic Container Registry (ECR)
+------------------------------------------------------------------
+
+Amazon ECR is a combination of the Docker Registry V2 API and a proprietary API. The ECS driver includes methods for talking to both APIs.
+
+Docker Registry API Client :class:`~libcloud.container.utils.docker.RegistryClient` is a shared utility class for interfacing to the public Docker Hub Service.
+
+You can use a factory method to generate an instance of RegsitryClient from the ECS driver. This will request a 12 hour token from the Amazon API and instantiate a :class:`~libcloud.container.utils.docker.RegistryClient`
+object with those credentials.
+
+.. literalinclude:: /examples/container/container_registry.py
+ :language: python
+
API Docs
--------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/docs/examples/container/ecs/container_registry.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/ecs/container_registry.py b/docs/examples/container/ecs/container_registry.py
new file mode 100644
index 0000000..2003d5b
--- /dev/null
+++ b/docs/examples/container/ecs/container_registry.py
@@ -0,0 +1,30 @@
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+
+cls = get_driver(Provider.ECS)
+
+# Connect to AWS
+conn = cls(access_id='SDHFISJDIFJSIDFJ',
+ secret='THIS_IS)+_MY_SECRET_KEY+I6TVkv68o4H',
+ region='ap-southeast-2')
+
+# Get a Registry API client for an existing repository
+client = conn.ex_get_registry_client('my-image')
+
+# List all the images
+for image in client.list_images('my-image'):
+ print(image.name)
+
+# Get a specific image
+image = client.get_image('my-image', '14.04')
+
+print(image.path)
+# >> 647433528374.dkr.ecr.region.amazonaws.com/my-images:14.04
+
+# Deploy that image
+cluster = conn.list_clusters()[0]
+container = conn.deploy_container(
+ cluster=cluster,
+ name='my-simple-app',
+ image=image
+)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/common/aws.py
----------------------------------------------------------------------
diff --git a/libcloud/common/aws.py b/libcloud/common/aws.py
index b7153e3..2cc1d4b 100644
--- a/libcloud/common/aws.py
+++ b/libcloud/common/aws.py
@@ -394,8 +394,7 @@ class AWSJsonResponse(JsonResponse):
def parse_error(self):
response = json.loads(self.body)
code = response['__type']
- message = response['Message']
-
+ message = response.get('Message', response['message'])
return ('%s: %s' % (code, message))
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/container/drivers/ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/container/drivers/ecs.py b/libcloud/container/drivers/ecs.py
index 7f6faf3..36c5be3 100644
--- a/libcloud/container/drivers/ecs.py
+++ b/libcloud/container/drivers/ecs.py
@@ -21,6 +21,7 @@ except ImportError:
from libcloud.container.base import (ContainerDriver, Container,
ContainerCluster, ContainerImage)
from libcloud.container.types import ContainerState
+from libcloud.container.utils.docker import RegistryClient
from libcloud.common.aws import SignedAWSConnection, AWSJsonResponse
__all__ = [
@@ -56,6 +57,7 @@ class ECRJsonConnection(SignedAWSConnection):
class ElasticContainerDriver(ContainerDriver):
name = 'Amazon Elastic Container Service'
website = 'https://aws.amazon.com/ecs/details/'
+ ecr_repository_host = '%s.dkr.ecr.%s.amazonaws.com'
connectionCls = ECSJsonConnection
ecrConnectionClass = ECRJsonConnection
supports_clusters = False
@@ -80,7 +82,7 @@ class ElasticContainerDriver(ContainerDriver):
def _ex_connection_class_kwargs(self):
return {'signature_version': '4'}
- def list_images(self, ex_repository_name=None):
+ def list_images(self, ex_repository_name):
"""
List the images in an ECR repository
@@ -91,14 +93,19 @@ class ElasticContainerDriver(ContainerDriver):
:return: a list of images
:rtype: ``list`` of :class:`libcloud.container.base.ContainerImage`
"""
- request = {'repositoryName': 'default'}
+ request = {}
+ request['repositoryName'] = ex_repository_name
list_response = self.ecr_connection.request(
ROOT,
method='POST',
data=json.dumps(request),
headers=self._get_ecr_headers('ListImages')
).object
- return self._to_images(list_response)
+ repository_id = self.ex_get_repository_id(ex_repository_name)
+ host = self._get_ecr_host(repository_id)
+ return self._to_images(list_response['imageIds'],
+ host,
+ ex_repository_name)
def list_clusters(self):
"""
@@ -415,7 +422,7 @@ class ElasticContainerDriver(ContainerDriver):
data=json.dumps(request),
headers=self._get_headers('CreateService')
).object
- return response
+ return response['service']
def ex_list_service_arns(self, cluster=None):
"""
@@ -437,7 +444,7 @@ class ElasticContainerDriver(ContainerDriver):
).object
return response['serviceArns']
- def ex_describe_service(self, cluster, service_arn):
+ def ex_describe_service(self, service_arn):
"""
Get the details of a service
@@ -451,8 +458,6 @@ class ElasticContainerDriver(ContainerDriver):
:rtype: ``object``
"""
request = {'services': [service_arn]}
- if cluster is not None:
- request['cluster'] = cluster.id
response = self.connection.request(
ROOT,
method='POST',
@@ -461,7 +466,7 @@ class ElasticContainerDriver(ContainerDriver):
).object
return response['services'][0]
- def ex_destroy_service(self, cluster, service_arn):
+ def ex_destroy_service(self, service_arn):
"""
Deletes a service
@@ -472,37 +477,96 @@ class ElasticContainerDriver(ContainerDriver):
:type service_arn: ``str``
"""
request = {
- 'service': service_arn,
- 'cluster': cluster.id}
+ 'service': service_arn}
response = self.connection.request(
ROOT,
method='POST',
data=json.dumps(request),
headers=self._get_headers('DeleteService')
).object
- return response
+ return response['service']
+
+ def ex_get_registry_client(self, repository_name):
+ """
+ Get a client for an ECR repository
+
+ :param repository_name: The unique name of the repository
+ :type repository_name: ``str``
+
+ :return: a docker registry API client
+ :rtype: :class:`libcloud.container.utils.docker.RegistryClient`
+ """
+ repository_id = self.ex_get_repository_id(repository_name)
+ token = self.ex_get_repository_token(repository_id)
+ host = self._get_ecr_host(repository_id)
+ return RegistryClient(
+ host=host,
+ username='AWS',
+ password=token
+ )
+
+ def ex_get_repository_token(self, repository_id):
+ """
+ Get the authorization token (12 hour expiry) for a repository
+
+ :param repository_id: The ID of the repository
+ :type repository_id: ``str``
+
+ :return: A token for login
+ :rtype: ``str``
+ """
+ request = {'RegistryIds': [repository_id]}
+ response = self.ecr_connection.request(
+ ROOT,
+ method='POST',
+ data=json.dumps(request),
+ headers=self._get_ecr_headers('GetAuthorizationToken')
+ ).object
+ return response['authorizationData'][0]['authorizationToken']
+
+ def ex_get_repository_id(self, repository_name):
+ """
+ Get the ID of a repository
+
+ :param repository_name: The unique name of the repository
+ :type repository_name: ``str``
+
+ :return: The repository ID
+ :rtype: ``str``
+ """
+ request = {'repositoryNames': [repository_name]}
+ list_response = self.ecr_connection.request(
+ ROOT,
+ method='POST',
+ data=json.dumps(request),
+ headers=self._get_ecr_headers('DescribeRepositories')
+ ).object
+ repository_id = list_response['repositories'][0]['registryId']
+ return repository_id
+
+ def _get_ecr_host(self, repository_id):
+ return self.ecr_repository_host % (
+ repository_id,
+ self.region)
def _get_headers(self, action):
+ """
+ Get the default headers for a request to the ECS API
+ """
return {'x-amz-target': '%s.%s' %
(ECS_TARGET_BASE, action),
'Content-Type': 'application/x-amz-json-1.1'
}
def _get_ecr_headers(self, action):
+ """
+ Get the default headers for a request to the ECR API
+ """
return {'x-amz-target': '%s.%s' %
(ECR_TARGET_BASE, action),
'Content-Type': 'application/x-amz-json-1.1'
}
- def ex_docker_hub_image(self, name):
- return ContainerImage(
- id=None,
- name=name,
- path=None,
- version=None,
- driver=self.connection.driver
- )
-
def _to_clusters(self, data):
clusters = []
for cluster in data['clusters']:
@@ -542,17 +606,22 @@ class ElasticContainerDriver(ContainerDriver):
driver=self.connection.driver
)
- def _to_images(self, data):
+ def _to_images(self, data, host, repository_name):
images = []
- for image in data['images']:
- images.append(self._to_image(image))
+ for image in data:
+ images.append(self._to_image(image, host, repository_name))
return images
- def _to_image(self, data):
+ def _to_image(self, data, host, repository_name):
+ path = '%s/%s:%s' % (
+ host,
+ repository_name,
+ data['imageTag']
+ )
return ContainerImage(
id=None,
- name=data['name'],
- path=None,
- version=None,
+ name=path,
+ path=path,
+ version=data['imageTag'],
driver=self.connection.driver
)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/container/utils/docker.py
----------------------------------------------------------------------
diff --git a/libcloud/container/utils/docker.py b/libcloud/container/utils/docker.py
index 9e9703c..a8a544a 100644
--- a/libcloud/container/utils/docker.py
+++ b/libcloud/container/utils/docker.py
@@ -63,7 +63,10 @@ class RegistryClient(object):
:param password: (optional) Your hub account password
:type password: ``str``
"""
- self.connection = DockerHubConnection(host, username, password, **kwargs)
+ self.connection = DockerHubConnection(host,
+ username,
+ password,
+ **kwargs)
def list_images(self, repository_name, namespace='library', max_count=100):
"""
@@ -161,4 +164,5 @@ class HubClient(RegistryClient):
:param password: (optional) Your hub account password
:type password: ``str``
"""
- self.connection = DockerHubConnection(self.host, username, password, **kwargs)
+ self.connection = DockerHubConnection(self.host, username,
+ password, **kwargs)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/test/container/fixtures/ecs/createservice.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/createservice.json b/libcloud/test/container/fixtures/ecs/createservice.json
new file mode 100644
index 0000000..2f9d421
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/createservice.json
@@ -0,0 +1,30 @@
+{
+ "service": {
+ "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/default",
+ "deploymentConfiguration": {
+ "maximumPercent": 200,
+ "minimumHealthyPercent": 100
+ },
+ "deployments": [
+ {
+ "createdAt": 1430326887.362,
+ "desiredCount": 10,
+ "id": "ecs-svc/9223370606527888445",
+ "pendingCount": 0,
+ "runningCount": 0,
+ "status": "PRIMARY",
+ "taskDefinition": "arn:aws:ecs:us-east-1:012345678910:task-definition/ecs-demo:1",
+ "updatedAt": 1430326887.362
+ }
+ ],
+ "desiredCount": 10,
+ "events": [],
+ "loadBalancers": [],
+ "pendingCount": 0,
+ "runningCount": 0,
+ "serviceArn": "arn:aws:ecs:us-east-1:012345678910:service/test",
+ "serviceName": "test",
+ "status": "ACTIVE",
+ "taskDefinition": "arn:aws:ecs:us-east-1:012345678910:task-definition/ecs-demo:1"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/test/container/fixtures/ecs/deleteservice.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/deleteservice.json b/libcloud/test/container/fixtures/ecs/deleteservice.json
new file mode 100644
index 0000000..d89d323
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/deleteservice.json
@@ -0,0 +1,30 @@
+{
+ "service": {
+ "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/default",
+ "deploymentConfiguration": {
+ "maximumPercent": 200,
+ "minimumHealthyPercent": 100
+ },
+ "deployments": [
+ {
+ "createdAt": 1430320735.285,
+ "desiredCount": 0,
+ "id": "ecs-svc/9223370606534040511",
+ "pendingCount": 0,
+ "runningCount": 0,
+ "status": "PRIMARY",
+ "taskDefinition": "arn:aws:ecs:us-east-1:012345678910:task-definition/sleep360:27",
+ "updatedAt": 1430320735.285
+ }
+ ],
+ "desiredCount": 0,
+ "events": [],
+ "loadBalancers": [],
+ "pendingCount": 0,
+ "runningCount": 0,
+ "serviceArn": "arn:aws:ecs:us-east-1:012345678910:service/test",
+ "serviceName": "test",
+ "status": "DRAINING",
+ "taskDefinition": "arn:aws:ecs:us-east-1:012345678910:task-definition/sleep360:27"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/test/container/fixtures/ecs/describerepositories.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/describerepositories.json b/libcloud/test/container/fixtures/ecs/describerepositories.json
new file mode 100644
index 0000000..c794005
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/describerepositories.json
@@ -0,0 +1,8 @@
+{
+ "repositories": [{
+ "registryId": "647433528374",
+ "repositoryArn": "arn:aws:ecr:us-east-1:647433528374:repository/my-images",
+ "repositoryName": "my-images"
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/test/container/fixtures/ecs/describeservices.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/describeservices.json b/libcloud/test/container/fixtures/ecs/describeservices.json
new file mode 100644
index 0000000..76acc75
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/describeservices.json
@@ -0,0 +1,33 @@
+{
+ "failures": [],
+ "services": [
+ {
+ "clusterArn": "arn:aws:ecs:us-west-2:012345678910:cluster/telemetry",
+ "deploymentConfiguration": {
+ "maximumPercent": 200,
+ "minimumHealthyPercent": 100
+ },
+ "deployments": [
+ {
+ "createdAt": 1432829320.611,
+ "desiredCount": 4,
+ "id": "ecs-svc/9223370604025455196",
+ "pendingCount": 0,
+ "runningCount": 4,
+ "status": "PRIMARY",
+ "taskDefinition": "arn:aws:ecs:us-west-2:012345678910:task-definition/hpcc-t2-medium:1",
+ "updatedAt": 1432829320.611
+ }
+ ],
+ "desiredCount": 4,
+ "events": [],
+ "loadBalancers": [],
+ "pendingCount": 0,
+ "runningCount": 4,
+ "serviceArn": "arn:aws:ecs:us-west-2:012345678910:service/bunker-buster",
+ "serviceName": "test",
+ "status": "ACTIVE",
+ "taskDefinition": "arn:aws:ecs:us-west-2:012345678910:task-definition/hpcc-t2-medium:1"
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/test/container/fixtures/ecs/getauthorizationtoken.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/getauthorizationtoken.json b/libcloud/test/container/fixtures/ecs/getauthorizationtoken.json
new file mode 100644
index 0000000..469c9ef
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/getauthorizationtoken.json
@@ -0,0 +1,9 @@
+{
+ "authorizationData": [
+ {
+ "authorizationToken": "QVdTOkNpQzErSHF1ZXZPcUR...",
+ "expiresAt": 1448878779.809,
+ "proxyEndpoint": "https://012345678910.dkr.ecr.us-east-1.amazonaws.com"
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/test/container/fixtures/ecs/listimages.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/listimages.json b/libcloud/test/container/fixtures/ecs/listimages.json
new file mode 100644
index 0000000..ae598f0
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/listimages.json
@@ -0,0 +1,7 @@
+{
+ "imageIds": [{
+ "imageDigest": "sha256:9bacaf947ed397fcc9afb7359a1a8eaa1f6944ba8cd4ddca1c69bdcf4acf12a2",
+ "imageTag": "latest"
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/test/container/fixtures/ecs/listservices.json
----------------------------------------------------------------------
diff --git a/libcloud/test/container/fixtures/ecs/listservices.json b/libcloud/test/container/fixtures/ecs/listservices.json
new file mode 100644
index 0000000..62a3cf5
--- /dev/null
+++ b/libcloud/test/container/fixtures/ecs/listservices.json
@@ -0,0 +1,6 @@
+{
+ "serviceArns": [
+ "arn:aws:ecs:us-east-1:012345678910:service/hello_world",
+ "arn:aws:ecs:us-east-1:012345678910:service/ecs-simple-service"
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/f00a9b75/libcloud/test/container/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/container/test_ecs.py b/libcloud/test/container/test_ecs.py
index 518daae..73a35b3 100644
--- a/libcloud/test/container/test_ecs.py
+++ b/libcloud/test/container/test_ecs.py
@@ -19,6 +19,7 @@ from libcloud.test import unittest
from libcloud.container.base import ContainerCluster, ContainerImage, Container
from libcloud.container.drivers.ecs import ElasticContainerDriver
+from libcloud.container.utils.docker import RegistryClient
from libcloud.utils.py3 import httplib
from libcloud.test.secrets import CONTAINER_PARAMS_ECS
@@ -136,6 +137,37 @@ class ElasticContainerDriverTestCase(unittest.TestCase):
)
self.assertFalse(container is None)
+ def test_list_images(self):
+ images = self.driver.list_images('my-images')
+ self.assertEqual(len(images), 1)
+ self.assertEqual(images[0].name, '647433528374.dkr.ecr.region.amazonaws.com/my-images:latest')
+
+ def test_ex_create_service(self):
+ cluster = self.driver.list_clusters()[0]
+ task_definition = self.driver.list_containers()[0].extra['taskDefinitionArn']
+ service = self.driver.ex_create_service(cluster=cluster,
+ name='jim',
+ task_definition=task_definition)
+ self.assertEqual(service['serviceName'], 'test')
+
+ def test_ex_list_service_arns(self):
+ arns = self.driver.ex_list_service_arns()
+ self.assertEqual(len(arns), 2)
+
+ def test_ex_describe_service(self):
+ arn = self.driver.ex_list_service_arns()[0]
+ service = self.driver.ex_describe_service(arn)
+ self.assertEqual(service['serviceName'], 'test')
+
+ def test_ex_destroy_service(self):
+ arn = self.driver.ex_list_service_arns()[0]
+ service = self.driver.ex_destroy_service(arn)
+ self.assertEqual(service['status'], 'DRAINING')
+
+ def test_ex_get_registry_client(self):
+ client = self.driver.ex_get_registry_client('my-images')
+ self.assertIsInstance(client, RegistryClient)
+
class ECSMockHttp(MockHttp):
fixtures = ContainerFileFixtures('ecs')
@@ -148,7 +180,14 @@ class ECSMockHttp(MockHttp):
'ListClusters': 'listclusters.json',
'RegisterTaskDefinition': 'registertaskdefinition.json',
'RunTask': 'runtask.json',
- 'StopTask': 'stoptask.json'
+ 'StopTask': 'stoptask.json',
+ 'ListImages': 'listimages.json',
+ 'DescribeRepositories': 'describerepositories.json',
+ 'CreateService': 'createservice.json',
+ 'ListServices': 'listservices.json',
+ 'DescribeServices': 'describeservices.json',
+ 'DeleteService': 'deleteservice.json',
+ 'GetAuthorizationToken': 'getauthorizationtoken.json'
}
def root(
[29/50] libcloud git commit: Added graphviz to the sphinx extensions,
added some graphs for the container docs to better explain how it
works
Posted by an...@apache.org.
Added graphviz to the sphinx extensions, added some graphs for the container docs to better explain how it works
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/db7d8f09
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/db7d8f09
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/db7d8f09
Branch: refs/heads/trunk
Commit: db7d8f09ed54a2a10ce87cafba4c0ca6631b64bc
Parents: c188d32
Author: anthony-shaw <an...@gmail.com>
Authored: Wed Jan 6 21:30:12 2016 +1100
Committer: anthony-shaw <an...@gmail.com>
Committed: Wed Jan 6 21:30:12 2016 +1100
----------------------------------------------------------------------
docs/conf.py | 2 +-
docs/container/index.rst | 73 +++++++++++++++++++-
.../container/docker/deploy_container.py | 10 +++
docs/examples/container/ecs/deploy_container.py | 25 ++++---
4 files changed, 98 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/db7d8f09/docs/conf.py
----------------------------------------------------------------------
diff --git a/docs/conf.py b/docs/conf.py
index f1e53d8..2b17ca5 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -40,7 +40,7 @@ sys.path.insert(0, os.path.abspath('../'))
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx',
- 'sphinx.ext.viewcode']
+ 'sphinx.ext.viewcode', 'sphinx.ext.graphviz']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
http://git-wip-us.apache.org/repos/asf/libcloud/blob/db7d8f09/docs/container/index.rst
----------------------------------------------------------------------
diff --git a/docs/container/index.rst b/docs/container/index.rst
index 01c9203..4f5fb66 100644
--- a/docs/container/index.rst
+++ b/docs/container/index.rst
@@ -9,6 +9,46 @@ Container API allows users to install and deploy containers onto container based
on-premise installations of software like Docker as well as interfacing with Cloud Service Providers that offer Container-as-a-Service APIs.
+.. graphviz::
+
+ digraph G {
+ graph [ fontname = "Roboto Slab",
+ fontsize = 18,
+ label = "Using the driver to deploy containers with or without clusters" ];
+
+ subgraph noncluster {
+ style=filled;
+ color=lightgrey;
+ node [style=filled,color=white];
+ list_images -> install_image -> deploy_container;
+ label = "Non-Cluster Container Driver";
+ }
+
+ subgraph cluster {
+ node [style=filled];
+ list_locations -> list_clusters -> create_cluster;
+ label = "Cluster supported Container Driver";
+ color=blue
+ }
+ __init__ -> list_images;
+ __init__ -> list_locations;
+ create_cluster -> list_images;
+ deploy_container -> end;
+
+ __init__ [shape=square];
+ end [shape=squae];
+ }
+
+For a working example of the container driver with cluster support, see the example for Amazon's Elastic Container Service:
+
+.. literalinclude:: /examples/container/ecs/deploy_container.py
+ :language: python
+
+For an example of the simple container support, see the Docker example:
+
+.. literalinclude:: /examples/container/docker/deploy_container.py
+ :language: python
+
Drivers
-------
Container-as-a-Service providers will implement the `ContainerDriver` class to provide functionality for :
@@ -40,7 +80,38 @@ clusters may be listed, created and destroyed. When containers are deployed, the
* :class:`~libcloud.container.base.ContainerCluster` - Represents a deployed container image running on a container host
* :class:`~libcloud.container.base.ClusterLocation` - Represents a location for clusters to be deployed
-
+Bootstrapping Docker with Compute Drivers
+-----------------------------------------
+
+The compute and container drivers can be combined using the :doc:`deployment </compute/deployment>` feature of the compute driver to bootstrap an installation of a container virtualization provider like Docker.
+Then using the Container driver, you can connect to that API and install images and deploy containers.
+
+.. graphviz::
+
+ digraph G2 {
+
+ subgraph compute {
+ style=filled;
+ color=lightgrey;
+ node [style=filled,color=white];
+ create_node -> deploy_node;
+ label = "Compute API";
+ }
+
+ subgraph container {
+ node [style=filled];
+ __init__ -> install_image -> deploy_container;
+ label = "Container API";
+ color=blue
+ }
+ start -> create_node;
+ deploy_node -> __init__;
+ deploy_container -> end;
+
+ start [shape=Mdiamond];
+ end [shape=Msquare];
+ }
+
Supported Providers
-------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/db7d8f09/docs/examples/container/docker/deploy_container.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/docker/deploy_container.py b/docs/examples/container/docker/deploy_container.py
new file mode 100644
index 0000000..7d643c2
--- /dev/null
+++ b/docs/examples/container/docker/deploy_container.py
@@ -0,0 +1,10 @@
+from libcloud.container.types import Provider
+from libcloud.container.providers import get_driver
+
+cls = get_driver(Provider.DOCKER)
+
+driver = cls(host='https://198.61.239.128', port=4243,
+ key_file='key.pem', cert_file='cert.pem')
+
+image = driver.install_image('tomcat:8.0')
+container = driver.deploy_container('tomcat', image)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/db7d8f09/docs/examples/container/ecs/deploy_container.py
----------------------------------------------------------------------
diff --git a/docs/examples/container/ecs/deploy_container.py b/docs/examples/container/ecs/deploy_container.py
index f9bc9df..2dd6662 100644
--- a/docs/examples/container/ecs/deploy_container.py
+++ b/docs/examples/container/ecs/deploy_container.py
@@ -8,13 +8,18 @@ conn = cls(access_id='AKIAI7OR4GWEEPRIFBBA',
secret='xiKazLqsAgMQ4c3rC2RSXHBJrJTqNZmjYcXHsYXO',
region='ap-southeast-2')
-container = conn.deploy_container(
- name='my-simple-app',
- image=ContainerImage(
- id=None,
- name='simple-app',
- path='simple-app',
- version=None,
- driver=conn
- )
-)
+
+for cluster in conn.list_clusters():
+ print(cluster.name)
+ if cluster.name == 'default':
+ container = conn.deploy_container(
+ cluster=cluster,
+ name='my-simple-app',
+ image=ContainerImage(
+ id=None,
+ name='simple-app',
+ path='simple-app',
+ version=None,
+ driver=conn
+ )
+ )