<reponame>anwarchk/quay<gh_stars>1-10
from abc import ABCMeta, abstractmethod
from collections import namedtuple
from six import add_metaclass

Command = namedtuple('Command', ['command'])

# NOTE: FileCopy is done via `scp`, instead of `ssh` which is how Command is run.
FileCopy = namedtuple('FileCopy', ['source', 'destination'])


@add_metaclass(ABCMeta)
class Client(object):
  """ Client defines the interface for all clients being tested. """

  @abstractmethod
  def setup_client(self, registry_host, verify_tls):
    """ Returns the commands necessary to setup the client inside the VM.
    """

  @abstractmethod
  def populate_test_image(self, registry_host, namespace, name):
    """ Returns the commands necessary to populate the test image. """

  @abstractmethod
  def print_version(self):
    """ Returns the commands necessary to print the version of the client. """

  @abstractmethod
  def login(self, registry_host, username, password):
    """ Returns the commands necessary to login. """

  @abstractmethod
  def push(self, registry_host, namespace, name):
    """ Returns the commands necessary to test pushing. """

  @abstractmethod
  def pre_pull_cleanup(self, registry_host, namespace, name):
    """ Returns the commands necessary to cleanup before pulling. """

  @abstractmethod
  def pull(self, registry_host, namespace, name):
    """ Returns the commands necessary to test pulling. """

  @abstractmethod
  def verify(self, registry_host, namespace, name):
    """ Returns the commands necessary to verify the pulled image. """


class DockerClient(Client):
  def __init__(self, requires_v1=False, requires_email=False):
    self.requires_v1 = requires_v1
    self.requires_email = requires_email

  def setup_client(self, registry_host, verify_tls):
    if not verify_tls:
      cp_command = ('sudo cp /home/core/50-insecure-registry.conf ' +
                    '/etc/systemd/system/docker.service.d/50-insecure-registry.conf')

      yield Command('sudo mkdir -p /etc/systemd/system/docker.service.d/')
      yield FileCopy('50-insecure-registry.conf', '/home/core')
      yield Command(cp_command)
      yield Command('sudo systemctl daemon-reload')

    yield FileCopy('Dockerfile.test', '/home/core/Dockerfile')

  def populate_test_image(self, registry_host, namespace, name):
    if self.requires_v1:
      # These versions of Docker don't support the new TLS cert on quay.io, so we need to pull
      # from v1.quay.io and then retag so the build works.
      yield Command('docker pull v1.quay.io/quay/busybox')
      yield Command('docker tag v1.quay.io/quay/busybox quay.io/quay/busybox')

    yield Command('docker build -t %s/%s/%s .' % (registry_host, namespace, name))

  def print_version(self):
    yield Command('docker version')

  def login(self, registry_host, username, password):
    email_param = ""
    if self.requires_email:
      # cli will block forever if email is not set for version under 1.10.3
      email_param = "--email=none "

    yield Command('docker login --username=%s --password=%s %s %s' %
                  (username, password, email_param, registry_host))

  def push(self, registry_host, namespace, name):
    yield Command('docker push %s/%s/%s' % (registry_host, namespace, name))

  def pre_pull_cleanup(self, registry_host, namespace, name):
    prefix = 'v1.' if self.requires_v1 else ''
    yield Command('docker rmi -f %s/%s/%s' % (registry_host, namespace, name))
    yield Command('docker rmi -f %squay.io/quay/busybox' % prefix)

  def pull(self, registry_host, namespace, name):
    yield Command('docker pull %s/%s/%s' % (registry_host, namespace, name))

  def verify(self, registry_host, namespace, name):
    yield Command('docker run %s/%s/%s echo testfile' % (registry_host, namespace, name))


class PodmanClient(Client):
  def __init__(self):
    self.verify_tls = False

  def setup_client(self, registry_host, verify_tls):
    yield FileCopy('Dockerfile.test', '/home/vagrant/Dockerfile')
    self.verify_tls = verify_tls

  def populate_test_image(self, registry_host, namespace, name):
    yield Command('sudo podman build -t %s/%s/%s /home/vagrant/' % (registry_host, namespace, name))

  def print_version(self):
    yield Command('sudo podman version')

  def login(self, registry_host, username, password):
    yield Command('sudo podman login --tls-verify=%s --username=%s --password=%s %s' %
                  (self.verify_tls, username, password, registry_host))

  def push(self, registry_host, namespace, name):
    yield Command('sudo podman push --tls-verify=%s %s/%s/%s' % (self.verify_tls, registry_host, namespace, name))

  def pre_pull_cleanup(self, registry_host, namespace, name):
    yield Command('sudo podman rmi -f %s/%s/%s' % (registry_host, namespace, name))
    yield Command('sudo podman rmi -f quay.io/quay/busybox')

  def pull(self, registry_host, namespace, name):
    yield Command('sudo podman pull --tls-verify=%s %s/%s/%s' % (self.verify_tls, registry_host, namespace, name))

  def verify(self, registry_host, namespace, name):
    yield Command('sudo podman run %s/%s/%s echo testfile' % (registry_host, namespace, name))

from abc import ABCMeta, abstractmethod
from collections import namedtuple
from six import add_metaclass

Command = namedtuple('Command', ['command'])

# NOTE: FileCopy is done via `scp`, instead of `ssh` which is how Command is run.
FileCopy = namedtuple('FileCopy', ['source', 'destination'])


@add_metaclass(ABCMeta)
class Client(object):
  """ Client defines the interface for all clients being tested. """

  @abstractmethod
  def setup_client(self, registry_host, verify_tls):
    """ Returns the commands necessary to setup the client inside the VM.
    """

  @abstractmethod
  def populate_test_image(self, registry_host, namespace, name):
    """ Returns the commands necessary to populate the test image. """

  @abstractmethod
  def print_version(self):
    """ Returns the commands necessary to print the version of the client. """

  @abstractmethod
  def login(self, registry_host, username, password):
    """ Returns the commands necessary to login. """

  @abstractmethod
  def push(self, registry_host, namespace, name):
    """ Returns the commands necessary to test pushing. """

  @abstractmethod
  def pre_pull_cleanup(self, registry_host, namespace, name):
    """ Returns the commands necessary to cleanup before pulling. """

  @abstractmethod
  def pull(self, registry_host, namespace, name):
    """ Returns the commands necessary to test pulling. """

  @abstractmethod
  def verify(self, registry_host, namespace, name):
    """ Returns the commands necessary to verify the pulled image. """


class DockerClient(Client):
  def __init__(self, requires_v1=False, requires_email=False):
    self.requires_v1 = requires_v1
    self.requires_email = requires_email

  def setup_client(self, registry_host, verify_tls):
    if not verify_tls:
      cp_command = ('sudo cp /home/core/50-insecure-registry.conf ' +
                    '/etc/systemd/system/docker.service.d/50-insecure-registry.conf')

      yield Command('sudo mkdir -p /etc/systemd/system/docker.service.d/')
      yield FileCopy('50-insecure-registry.conf', '/home/core')
      yield Command(cp_command)
      yield Command('sudo systemctl daemon-reload')

    yield FileCopy('Dockerfile.test', '/home/core/Dockerfile')

  def populate_test_image(self, registry_host, namespace, name):
    if self.requires_v1:
      # These versions of Docker don't support the new TLS cert on quay.io, so we need to pull
      # from v1.quay.io and then retag so the build works.
      yield Command('docker pull v1.quay.io/quay/busybox')
      yield Command('docker tag v1.quay.io/quay/busybox quay.io/quay/busybox')

    yield Command('docker build -t %s/%s/%s .' % (registry_host, namespace, name))

  def print_version(self):
    yield Command('docker version')

  def login(self, registry_host, username, password):
    email_param = ""
    if self.requires_email:
      # cli will block forever if email is not set for version under 1.10.3
      email_param = "--email=none "

    yield Command('docker login --username=%s --password=%s %s %s' %
                  (username, password, email_param, registry_host))

  def push(self, registry_host, namespace, name):
    yield Command('docker push %s/%s/%s' % (registry_host, namespace, name))

  def pre_pull_cleanup(self, registry_host, namespace, name):
    prefix = 'v1.' if self.requires_v1 else ''
    yield Command('docker rmi -f %s/%s/%s' % (registry_host, namespace, name))
    yield Command('docker rmi -f %squay.io/quay/busybox' % prefix)

  def pull(self, registry_host, namespace, name):
    yield Command('docker pull %s/%s/%s' % (registry_host, namespace, name))

  def verify(self, registry_host, namespace, name):
    yield Command('docker run %s/%s/%s echo testfile' % (registry_host, namespace, name))


class PodmanClient(Client):
  def __init__(self):
    self.verify_tls = False

  def setup_client(self, registry_host, verify_tls):
    yield FileCopy('Dockerfile.test', '/home/vagrant/Dockerfile')
    self.verify_tls = verify_tls

  def populate_test_image(self, registry_host, namespace, name):
    yield Command('sudo podman build -t %s/%s/%s /home/vagrant/' % (registry_host, namespace, name))

  def print_version(self):
    yield Command('sudo podman version')

  def login(self, registry_host, username, password):
    yield Command('sudo podman login --tls-verify=%s --username=%s --password=%s %s' %
                  (self.verify_tls, username, password, registry_host))

  def push(self, registry_host, namespace, name):
    yield Command('sudo podman push --tls-verify=%s %s/%s/%s' % (self.verify_tls, registry_host, namespace, name))

  def pre_pull_cleanup(self, registry_host, namespace, name):
    yield Command('sudo podman rmi -f %s/%s/%s' % (registry_host, namespace, name))
    yield Command('sudo podman rmi -f quay.io/quay/busybox')

  def pull(self, registry_host, namespace, name):
    yield Command('sudo podman pull --tls-verify=%s %s/%s/%s' % (self.verify_tls, registry_host, namespace, name))

  def verify(self, registry_host, namespace, name):
    yield Command('sudo podman run %s/%s/%s echo testfile' % (registry_host, namespace, name))
# NOTE: FileCopy is done via `scp`, instead of `ssh` which is how Command is run. Client defines the interface for all clients being tested. Returns the commands necessary to setup the client inside the VM. Returns the commands necessary to populate the test image. Returns the commands necessary to print the version of the client. Returns the commands necessary to login. Returns the commands necessary to test pushing. Returns the commands necessary to cleanup before pulling. Returns the commands necessary to test pulling. Returns the commands necessary to verify the pulled image. # These versions of Docker don't support the new TLS cert on quay.io, so we need to pull # from v1.quay.io and then retag so the build works. # cli will block forever if email is not set for version under 1.10.3