files.new_contents: # 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.
  
  """
  Provides generic deployment steps for machines post boot.
  """
  
  from __future__ import with_statement
  
  from typing import Union
  from typing import Optional
  from typing import List
  from typing import IO
  from typing import cast
  
  import os
  import binascii
  
  from libcloud.utils.py3 import basestring, PY3
  from libcloud.compute.base import Node
  from libcloud.compute.ssh import BaseSSHClient
  
  
  class Deployment(object):
      """
      Base class for deployment tasks.
      """
  
      def run(self, node, client):
          # type: (Node, BaseSSHClient) -> Node
          """
          Runs this deployment task on node using the client provided.
  
          :type node: :class:`Node`
          :keyword node: Node to operate one
  
          :type client: :class:`BaseSSHClient`
          :keyword client: Connected SSH client to use.
  
          :return: :class:`Node`
          """
          raise NotImplementedError(
              'run not implemented for this deployment')
  
      def _get_string_value(self, argument_name, argument_value):
          if not isinstance(argument_value, basestring) and \
             not hasattr(argument_value, 'read'):
              raise TypeError('%s argument must be a string or a file-like '
                              'object' % (argument_name))
  
          if hasattr(argument_value, 'read'):
              argument_value = argument_value.read()
  
          return argument_value
  
  
  class SSHKeyDeployment(Deployment):
      """
      Installs a public SSH Key onto a server.
      """
  
      def __init__(self, key):
          # type: (Union[str, IO]) -> None
          """
          :type key: ``str`` or :class:`File` object
          :keyword key: Contents of the public key write or a file object which
                        can be read.
          """
          self.key = self._get_string_value(argument_name='key',
                                            argument_value=key)
  
      def run(self, node, client):
          # type: (Node, BaseSSHClient) -> Node
          """
          Installs SSH key into ``.ssh/authorized_keys``
  
          See also :class:`Deployment.run`
          """
          client.put(".ssh/authorized_keys", contents=self.key, mode='a')
          return node
  
  
  class FileDeployment(Deployment):
      """
      Installs a
  
  [... the rest is omitted ...]
files.new_path: libcloud/compute/deployment.py
files.old_contents: # 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.
  
  """
  Provides generic deployment steps for machines post boot.
  """
  
  from __future__ import with_statement
  
  from typing import Union
  from typing import Optional
  from typing import List
  from typing import IO
  from typing import cast
  
  import os
  import binascii
  
  from libcloud.utils.py3 import basestring, PY3
  from libcloud.compute.base import Node
  from libcloud.compute.ssh import BaseSSHClient
  
  
  class Deployment(object):
      """
      Base class for deployment tasks.
      """
  
      def run(self, node, client):
          # type: (Node, BaseSSHClient) -> Node
          """
          Runs this deployment task on node using the client provided.
  
          :type node: :class:`Node`
          :keyword node: Node to operate one
  
          :type client: :class:`BaseSSHClient`
          :keyword client: Connected SSH client to use.
  
          :return: :class:`Node`
          """
          raise NotImplementedError(
              'run not implemented for this deployment')
  
      def _get_string_value(self, argument_name, argument_value):
          if not isinstance(argument_value, basestring) and \
             not hasattr(argument_value, 'read'):
              raise TypeError('%s argument must be a string or a file-like '
                              'object' % (argument_name))
  
          if hasattr(argument_value, 'read'):
              argument_value = argument_value.read()
  
          return argument_value
  
  
  class SSHKeyDeployment(Deployment):
      """
      Installs a public SSH Key onto a server.
      """
  
      def __init__(self, key):
          # type: (Union[str, IO]) -> None
          """
          :type key: ``str`` or :class:`File` object
          :keyword key: Contents of the public key write or a file object which
                        can be read.
          """
          self.key = self._get_string_value(argument_name='key',
                                            argument_value=key)
  
      def run(self, node, client):
          # type: (Node, BaseSSHClient) -> Node
          """
          Installs SSH key into ``.ssh/authorized_keys``
  
          See also :class:`Deployment.run`
          """
          client.put(".ssh/authorized_keys", contents=self.key, mode='a')
          return node
  
  
  class FileDeployment(Deployment):
      """
      Installs a
  
  [... the rest is omitted ...]
files.old_path: libcloud/compute/deployment.py
files.new_contents: # 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.
  
  """
  Wraps multiple ways to communicate over SSH.
  """
  
  from typing import Type
  from typing import Optional
  from typing import Tuple
  from typing import List
  from typing import Union
  from typing import cast
  
  have_paramiko = False
  
  try:
      import paramiko
      have_paramiko = True
  except ImportError:
      pass
  
  # Depending on your version of Paramiko, it may cause a deprecation
  # warning on Python 2.6.
  # Ref: https://bugs.launchpad.net/paramiko/+bug/392973
  
  import os
  import time
  import subprocess
  import logging
  import warnings
  
  from os.path import split as psplit
  from os.path import join as pjoin
  
  from libcloud.utils.logging import ExtraLogFormatter
  from libcloud.utils.py3 import StringIO
  from libcloud.utils.py3 import b
  
  __all__ = [
      'BaseSSHClient',
      'ParamikoSSHClient',
      'ShellOutSSHClient',
  
      'SSHCommandTimeoutError'
  ]
  
  SUPPORTED_KEY_TYPES_URL = 'https://libcloud.readthedocs.io/en/latest/compute/deployment.html#supported-private-ssh-key-types' # NOQA
  
  
  class SSHCommandTimeoutError(Exception):
      """
      Exception which is raised when an SSH command times out.
      """
      def __init__(self, cmd, timeout):
          # type: (str, float) -> None
          self.cmd = cmd
          self.timeout = timeout
          self.message = 'Command didn\'t finish in %s seconds' % (timeout)
          super(SSHCommandTimeoutError, self).__init__(self.message)
  
      def __repr__(self):
          return ('<SSHCommandTimeoutError: cmd="%s",timeout=%s)>' %
                  (self.cmd, self.timeout))
  
      def __str__(self):
          return self.__repr__()
  
  
  class BaseSSHClient(object):
      """
      Base class representing a connection over SSH/SCP to a remote node.
      """
  
      def __init__(self,
                   hostname,  # type: str
                   port=22,  # type: int
                   username='root',  # type: str
                   password=None,  # type: Optional[str]
                   key=None,  # type: Optional[str]
                   key_files=None
  
  [... the rest is omitted ...]
files.new_path: libcloud/compute/ssh.py
files.old_contents: # 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.
  
  """
  Wraps multiple ways to communicate over SSH.
  """
  
  from typing import Type
  from typing import Optional
  from typing import Tuple
  from typing import List
  from typing import Union
  from typing import cast
  
  have_paramiko = False
  
  try:
      import paramiko
      have_paramiko = True
  except ImportError:
      pass
  
  # Depending on your version of Paramiko, it may cause a deprecation
  # warning on Python 2.6.
  # Ref: https://bugs.launchpad.net/paramiko/+bug/392973
  
  import os
  import time
  import subprocess
  import logging
  import warnings
  
  from os.path import split as psplit
  from os.path import join as pjoin
  
  from libcloud.utils.logging import ExtraLogFormatter
  from libcloud.utils.py3 import StringIO
  from libcloud.utils.py3 import b
  
  __all__ = [
      'BaseSSHClient',
      'ParamikoSSHClient',
      'ShellOutSSHClient',
  
      'SSHCommandTimeoutError'
  ]
  
  SUPPORTED_KEY_TYPES_URL = 'https://libcloud.readthedocs.io/en/latest/compute/deployment.html#supported-private-ssh-key-types' # NOQA
  
  
  class SSHCommandTimeoutError(Exception):
      """
      Exception which is raised when an SSH command times out.
      """
      def __init__(self, cmd, timeout):
          # type: (str, float) -> None
          self.cmd = cmd
          self.timeout = timeout
          self.message = 'Command didn\'t finish in %s seconds' % (timeout)
          super(SSHCommandTimeoutError, self).__init__(self.message)
  
      def __repr__(self):
          return ('<SSHCommandTimeoutError: cmd="%s",timeout=%s)>' %
                  (self.cmd, self.timeout))
  
      def __str__(self):
          return self.__repr__()
  
  
  class BaseSSHClient(object):
      """
      Base class representing a connection over SSH/SCP to a remote node.
      """
  
      def __init__(self,
                   hostname,  # type: str
                   port=22,  # type: int
                   username='root',  # type: str
                   password=None,  # type: Optional[str]
                   key=None,  # type: Optional[str]
                   key_files=None
  
  [... the rest is omitted ...]
files.old_path: libcloud/compute/ssh.py
files.new_contents: # -*- coding: utf-8 -*-
  # 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
  
  import os
  import sys
  import time
  import unittest
  
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import u
  from libcloud.utils.py3 import PY3
  from libcloud.utils.py3 import assertRaisesRegex
  
  from libcloud.compute.deployment import MultiStepDeployment, Deployment
  from libcloud.compute.deployment import SSHKeyDeployment, ScriptDeployment
  from libcloud.compute.deployment import ScriptFileDeployment, FileDeployment
  from libcloud.compute.base import Node
  from libcloud.compute.base import NodeAuthPassword
  from libcloud.compute.types import NodeState, DeploymentError, LibcloudError
  from libcloud.compute.ssh import BaseSSHClient
  from libcloud.compute.ssh import have_paramiko
  from libcloud.compute.ssh import SSHCommandTimeoutError
  from libcloud.compute.drivers.rackspace import RackspaceFirstGenNodeDriver as Rackspace
  
  from libcloud.test import MockHttp, XML_HEADERS
  from libcloud.test.file_fixtures import ComputeFileFixtures
  from mock import Mock, patch
  
  from libcloud.test.secrets import RACKSPACE_PARAMS
  
  # Keyword arguments which are specific to deploy_node() method, but not
  # create_node()
  DEPLOY_NODE_KWARGS = ['deploy', 'ssh_username', 'ssh_alternate_usernames',
                        'ssh_port', 'ssh_timeout', 'ssh_key', 'timeout',
                        'max_tries', 'ssh_interface']
  
  FILE_PATH = '{0}home{0}ubuntu{0}relative.sh'.format(os.path.sep)
  
  
  class MockDeployment(Deployment):
  
      def run(self, node, client):
          return node
  
  
  class MockClient(BaseSSHClient):
  
      def __init__(self, throw_on_timeout=False, *args, **kwargs):
          self.stdout = ''
          self.stderr = ''
          self.exit_status = 0
          self.throw_on_timeout = throw_on_timeout
  
      def put(self, path, contents, chmod=755, mode='w'):
          return contents
  
      def run(self, cmd, timeout=None):
          if self.throw_on_timeout and timeout is not None:
              raise
  
  [... the rest is omitted ...]
files.new_path: libcloud/test/compute/test_deployment.py
files.old_contents: # -*- coding: utf-8 -*-
  # 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
  
  import os
  import sys
  import time
  import unittest
  
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import u
  from libcloud.utils.py3 import PY3
  from libcloud.utils.py3 import assertRaisesRegex
  
  from libcloud.compute.deployment import MultiStepDeployment, Deployment
  from libcloud.compute.deployment import SSHKeyDeployment, ScriptDeployment
  from libcloud.compute.deployment import ScriptFileDeployment, FileDeployment
  from libcloud.compute.base import Node
  from libcloud.compute.base import NodeAuthPassword
  from libcloud.compute.types import NodeState, DeploymentError, LibcloudError
  from libcloud.compute.ssh import BaseSSHClient
  from libcloud.compute.ssh import have_paramiko
  from libcloud.compute.ssh import SSHCommandTimeoutError
  from libcloud.compute.drivers.rackspace import RackspaceFirstGenNodeDriver as Rackspace
  
  from libcloud.test import MockHttp, XML_HEADERS
  from libcloud.test.file_fixtures import ComputeFileFixtures
  from mock import Mock, patch
  
  from libcloud.test.secrets import RACKSPACE_PARAMS
  
  # Keyword arguments which are specific to deploy_node() method, but not
  # create_node()
  DEPLOY_NODE_KWARGS = ['deploy', 'ssh_username', 'ssh_alternate_usernames',
                        'ssh_port', 'ssh_timeout', 'ssh_key', 'timeout',
                        'max_tries', 'ssh_interface']
  
  FILE_PATH = '{0}home{0}ubuntu{0}relative.sh'.format(os.path.sep)
  
  
  class MockDeployment(Deployment):
  
      def run(self, node, client):
          return node
  
  
  class MockClient(BaseSSHClient):
  
      def __init__(self, *args, **kwargs):
          self.stdout = ''
          self.stderr = ''
          self.exit_status = 0
  
      def put(self, path, contents, chmod=755, mode='w'):
          return contents
  
      def run(self, name):
          return self.stdout, self.stderr, self.exit_status
  
      def delete(self, name):
          return True
  
  
  class DeploymentTests(unittest.TestCase):
  
      def setUp(self):
          R
  
  [... the rest is omitted ...]
files.old_path: libcloud/test/compute/test_deployment.py