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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions dcr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ __author__ = 'thatcher'
import sys
from docker_container_runner import utils
from docker_container_runner.manager import Application, DockerDaemon, Hipache
import pkg_resources # part of setuptools


# try:
Expand Down Expand Up @@ -31,7 +32,7 @@ def initialize():
containers = application.get_containers()

for name, container in containers.items():
print container.status
status = container.status

return application

Expand Down Expand Up @@ -66,6 +67,8 @@ def print_usage():

options:

version: show current dcr version

Managing the containers
-----------------------

Expand All @@ -88,8 +91,13 @@ def print_usage():
try:
stream = open(sys.argv[1])
except:
print_usage()
sys.exit(1)
try:
if sys.argv[1] == "version":
print "dcr version: {}".format(pkg_resources.require("dcr")[0].version)
sys.exit(0)
except IndexError:
print_usage()
sys.exit(1)

directives = utils.read_appconfig(sys.argv[1])

Expand Down
107 changes: 67 additions & 40 deletions docker_container_runner/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,45 @@ def __init__(self, host, registry_login, ssh_user, ssh=True):
except ValueError:
hostname = host

self.host_name, self.host_port = hostname.split(":")
self.host = host
self.registry_login = registry_login
self.ssh_user = ssh_user

if ssh:
forwarder = create_tunnel(self.host_name, self.host_port, ssh_user)
entrypoint = "http://{}".format(forwarder.bind_string)
if protocol == "http:":
self.host_name, self.host_port = hostname.split(":")
self.host = host
self.registry_login = registry_login
self.ssh_user = ssh_user

if ssh:
forwarder = create_tunnel(self.host_name, self.host_port, ssh_user)
entrypoint = "http://{}".format(forwarder.bind_string)
else:
entrypoint = "http://{}:{}".format(self.host_name, self.host_port)
elif protocol == "unix:":
entrypoint = host
self.host_name = "local"
else:
entrypoint = "http://{}:{}".format(self.host_name, self.host_port)
print "Docker access protocol not recognized"
sys.exit(1)

self.connection = docker.Client(base_url=entrypoint, version="1.7")

def login(self):
"""
Logs in to the registry
"""
if not self.registry_login:
# sys.exit("Cannot login, no registry settings set")
print "login: No registry settings found, trying to connect anonymously"
return

try:
username, password, email = self.registry_login.split(":")
except BaseException as ex:
sys.exit("error parsing registry_settings: {}".format(ex))
sys.exit("error parsing registry_settings, were they set in your environment?, {}".format(ex))

print "trying to login to the public index using user {}".format(username)
print "login: trying to login to the public index using user {}".format(username)

result = self.connection.login(username=username, password=password, email=email)

# print result
print "login: {}".format(result[u'Status'])
return result


Expand Down Expand Up @@ -76,7 +88,6 @@ def details(self):
details = self.daemon.connection.inspect_container(self.config['release_name'])
return details
except APIError as ex:
print ex
return None
except ConnectionError as ex:
print "Failed to connect to daemon ", ex
Expand All @@ -87,33 +98,39 @@ def status(self):
try:
running = self.details['State']['Running']
if running:
print "status: Status of '{}' on host '{}' is running \n with ports: {}".format(
self.config['release_name'],
self.daemon.host_name,
self.details[u'NetworkSettings']['Ports']
)
status = "running"
else:
print "status: container {} on host {} is stopped".format(self.config['release_name'], self.daemon.host_name)
status = "stopped"
except Exception:
status = "doesnotexist"
print "status: container {} on host {} does not exist".format(self.config['release_name'], self.daemon.host_name)

return status

def pull(self):
repository = self.config['image']
print "starting to pull {} on {}".format(repository, self.daemon.host_name)
print "pull: Starting to pull {} on {}".format(repository, self.daemon.host_name)

try:
self.daemon.login()
result = self.daemon.connection.pull(repository, tag=None)
print result
print "pull: {}".format(result)
print "pull: Pull complete"
return result
except APIError as ex:
print ex
return ex

print "pull complete"

def get_image(self):
return self.daemon.connection.images(name=self.config['image'])

def create(self):
print "creating container on {}".format(self.daemon.host_name)
print "create: creating container on {}".format(self.daemon.host_name)
try:
self.daemon.connection.create_container(self.config['image'],
self.config['command'],
Expand All @@ -123,28 +140,30 @@ def create(self):
detach=True,
name=self.config['release_name'])
except APIError as ex:
print "failed to create container: ", ex
print "create: failed to create container: ", ex
return 1, "Failed to create container", ex


def start(self):
"""
starts one of the containers of this application
"""
print "starting container on {}".format(self.daemon.host_name)
print "start: starting container on {}".format(self.daemon.host_name)

if self.details is None:
return None
if not self.details['State']['Running'] is True:
result = self.daemon.connection.start(self.config['release_name'],
port_bindings=self.config['s_ports'],
binds=self.config['binds'],
links=self.config['links'])
return result
else:
return None
if not self.details['State']['Running'] is True:
result = self.daemon.connection.start(self.config['release_name'],
port_bindings=self.config['s_ports'],
binds=self.config['binds'],
links=self.config['links'])
return result
else:
return None

def stop(self):
print "stopping container on {}".format(self.daemon.host_name)
print "stop: stopping container on {}".format(self.daemon.host_name)
if self.details is None:
return 1, "container does not exist"
if not self.details['State']['Running'] is False:
Expand All @@ -157,7 +176,7 @@ def remove(self):
"""
starts one of the containers of this application
"""
print "removing container on {}".format(self.daemon.host_name)
print "remove: removing container on {}".format(self.daemon.host_name)
if self.details is None:
return 1, "container does not exist"
elif self.details['State']['Running'] is False:
Expand Down Expand Up @@ -201,8 +220,17 @@ def connect_gateways(self, cluster="default"):
use_ssh = self.settings[cluster]['use_ssh']

ssh_user = self.settings[cluster].get('ssh_user', None)
for hipache_config in self.settings['default']['hipaches']:
hipache_host, hipache_port = hipache_config.split(':')
if os.environ["REDIS_PORT_6379_TCP_ADDR"]:
hipache_host = os.environ["REDIS_PORT_6379_TCP_ADDR"]
hipache_port = os.environ["REDIS_PORT_6379_TCP_PORT"]
self.hipaches.append(Hipache(hipache_host, int(hipache_port), ssh_user=ssh_user, use_ssh=use_ssh))
elif 'hipaches' in self.settings['default'].keys():
for hipache_config in self.settings['default']['hipaches']:
hipache_host, hipache_port = hipache_config.split(':')
self.hipaches.append(Hipache(hipache_host, int(hipache_port), ssh_user=ssh_user, use_ssh=use_ssh))
else:
hipache_host = "127.0.0.1"
hipache_port = "6379"
self.hipaches.append(Hipache(hipache_host, int(hipache_port), ssh_user=ssh_user, use_ssh=use_ssh))

release_name = self.config.get('release_name', None)
Expand Down Expand Up @@ -286,10 +314,6 @@ def get_details(self):
def get_status(self):
status = []
for key, container in self.containers.items():
print "container {release_name} on host {daemon}, Running={status}" \
.format(release_name=container.config['release_name'],
daemon=container.daemon.host_name,
status=container.status)
status.append(container.status)
return status

Expand Down Expand Up @@ -366,13 +390,13 @@ def unregister(self, domain, hard=False):
# check length
length = hipache.connection.llen(frontend)

print "setting was", hipache.connection.lrange(frontend, 0, -1)
print "unregister: setting was", hipache.connection.lrange(frontend, 0, -1)

if not length > 0:
sys.exit("no backends in redis with this domain")
sys.exit("unregister: no backends in redis with this domain")
elif length == 1:
print hipache.connection.lrange(frontend, 0, -1)
sys.exit("domain known, but no backends present")
sys.exit("unregister: domain known, but no backends present")
else:
if hard is False:
for backend_uri in backend_uris:
Expand All @@ -381,7 +405,7 @@ def unregister(self, domain, hard=False):
hipache.connection.ltrim(frontend, 0, 0) # remove all backends from this domain

stored_backends = hipache.connection.lrange(frontend, 0, -1)
print "setting now", stored_backends
print "unregister: setting now", stored_backends
results.append(stored_backends)

return results
Expand All @@ -390,7 +414,10 @@ def unregister_all(self, domain):
self.unregister(domain, hard=True)

def switch_backends(self, domain):
print "switch: unregistering all"
self.unregister(domain, hard=True)

print "switch: registering {}".format(domain)
self.register(domain)

def redis_status(self, domain):
Expand Down
6 changes: 4 additions & 2 deletions docker_container_runner/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import yaml
import sys
import os
import re
import bgtunnel
from bgtunnel import SSHTunnelError

Expand All @@ -12,7 +13,8 @@ def read_appconfig(filename):
print "no filename given, or incorrect file"
return err

config = yaml.load(stream)
config = yaml.load(os.path.expandvars(re.sub(
r'\%([a-zA-Z0-9\-_]+)',r'\1=$\1', stream.read())))

directives = {}

Expand Down Expand Up @@ -124,7 +126,7 @@ def read_settings(filename='settings.yml'):
print "no filename given, or incorrect file"
return err

settings = yaml.load(stream)
settings = yaml.load(os.path.expandvars(stream.read()))

items = settings['default']
items['registry_login'] = try_replace_vars(items.get("registry_login", None))
Expand Down
9 changes: 9 additions & 0 deletions samples/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
test:
image: "busybox"
command: ["sleep", "100"]
env:
- "AIRFIELD_USER=admin"
- "AIRFIELD_PASS=password"
# links: ["hipache-0.1:redis"]
ports: ['100']
release_name: "test1"
3 changes: 1 addition & 2 deletions settings.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
default:
hipaches: ['blue3.koffiedik.net:6379']
daemons: ['http://blue3.koffiedik.net:4243']
base_domain: ['tea.project.io']
daemons: ['http://localhost:4243']
use_ssh: False
12 changes: 12 additions & 0 deletions tests/integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,20 @@ def runTest(self):
self.assertIn(status, acceptedValues)


class TestRunningStatus(BaseTestCase):
def runTest(self):
self.application.create_containers()
create_results = self.application.start_containers()
res = self.application.get_status()

acceptedValues = ['stopped', 'running', 'doesnotexist']
for status in res:
self.assertIn(status, acceptedValues)


class TestPullContainer(BaseTestCase):
def runTest(self):
login = self.application.login_registry()
results = self.application.pull_image()
for result in results:
self.assertNotIn("Authentication is required", result)
Expand Down
5 changes: 2 additions & 3 deletions tests/settings.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
default:
hipaches: ['blue4.koffiedik.net:6379']
daemons: ['blue4.koffiedik.net:4243']
daemons: ['localhost:4243']
ssh_user: "docker"
base_domain: ['tea.project.io']
use_ssh: True
use_ssh: False
registry_login: "$REGISTRY_USER:$REGISTRY_PASS:$REGISTRY_EMAIL"