Merge branch '1.12'
This commit is contained in:
commit
0d6bf1d965
|
@ -5,3 +5,5 @@ dist/
|
|||
paramiko.egg-info/
|
||||
test.log
|
||||
docs/
|
||||
!sites/docs
|
||||
_build
|
||||
|
|
14
.travis.yml
14
.travis.yml
|
@ -5,8 +5,18 @@ python:
|
|||
install:
|
||||
# Self-install for setup.py-driven deps
|
||||
- pip install -e .
|
||||
- pip install coveralls
|
||||
script: coverage run --source=paramiko test.py --verbose
|
||||
# Dev (doc/test running) requirements
|
||||
- pip install coveralls # For coveralls.io specifically
|
||||
- pip install -r dev-requirements.txt
|
||||
script:
|
||||
# Main tests, with coverage!
|
||||
- coverage run --source=paramiko test.py --verbose
|
||||
# Ensure documentation & invoke pipeline run OK.
|
||||
# Run 'docs' first since its objects.inv is referred to by 'www'.
|
||||
# Also force warnings to be errors since most of them tend to be actual
|
||||
# problems.
|
||||
- invoke docs -o -W
|
||||
- invoke www -o -W
|
||||
notifications:
|
||||
irc:
|
||||
channels: "irc.freenode.org#paramiko"
|
||||
|
|
|
@ -1,2 +1,10 @@
|
|||
# Older junk
|
||||
tox>=1.4,<1.5
|
||||
epydoc>=3.0,<3.1
|
||||
# For newer tasks like building Sphinx docs.
|
||||
# NOTE: Requires Python >=2.6
|
||||
invoke>=0.7.0
|
||||
invocations>=0.4.4
|
||||
sphinx>=1.1.3
|
||||
alabaster>=0.2.0
|
||||
releases>=0.2.4
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
|
@ -0,0 +1,4 @@
|
|||
# Obtain shared config values
|
||||
import os, sys
|
||||
sys.path.append(os.path.abspath('..'))
|
||||
from shared_conf import *
|
|
@ -0,0 +1,6 @@
|
|||
Welcome to Paramiko's documentation!
|
||||
====================================
|
||||
|
||||
This site covers Paramiko's usage & API documentation. For basic info on what
|
||||
Paramiko is, including its public changelog & how the project is maintained,
|
||||
please see `the main website <http://paramiko.org>`_.
|
|
@ -0,0 +1,40 @@
|
|||
from datetime import datetime
|
||||
import os
|
||||
import sys
|
||||
|
||||
import alabaster
|
||||
|
||||
|
||||
# Alabaster theme
|
||||
html_theme_path = [alabaster.get_path()]
|
||||
# Paths relative to invoking conf.py - not this shared file
|
||||
html_static_path = ['../_shared_static']
|
||||
html_theme = 'alabaster'
|
||||
html_theme_options = {
|
||||
'description': "A Python implementation of SSHv2.",
|
||||
'github_user': 'paramiko',
|
||||
'github_repo': 'paramiko',
|
||||
'gittip_user': 'bitprophet',
|
||||
'analytics_id': 'UA-18486793-2',
|
||||
|
||||
'link': '#3782BE',
|
||||
'link_hover': '#3782BE',
|
||||
}
|
||||
html_sidebars = {
|
||||
'**': [
|
||||
'about.html',
|
||||
'navigation.html',
|
||||
'searchbox.html',
|
||||
'donate.html',
|
||||
]
|
||||
}
|
||||
|
||||
# Regular settings
|
||||
project = u'Paramiko'
|
||||
year = datetime.now().year
|
||||
copyright = u'2013-%d Jeff Forcier, 2003-2012 Robey Pointer' % year
|
||||
master_doc = 'index'
|
||||
templates_path = ['_templates']
|
||||
exclude_trees = ['_build']
|
||||
source_suffix = '.rst'
|
||||
default_role = 'obj'
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<atom:link href="{{ atom }}" rel="self" type="application/rss+xml" />
|
||||
<title>{{ title }}</title>
|
||||
<link>{{ link }}</link>
|
||||
<description>{{ description }}</description>
|
||||
<pubDate>{{ date }}</pubDate>
|
||||
{% for link, title, desc, date in posts %}
|
||||
<item>
|
||||
<link>{{ link }}</link>
|
||||
<guid>{{ link }}</guid>
|
||||
<title><![CDATA[{{ title }}]]></title>
|
||||
<description><![CDATA[{{ desc }}]]></description>
|
||||
<pubDate>{{ date }}</pubDate>
|
||||
</item>
|
||||
{% endfor %}
|
||||
</channel>
|
||||
</rss>
|
|
@ -0,0 +1,140 @@
|
|||
from collections import namedtuple
|
||||
from datetime import datetime
|
||||
import time
|
||||
import email.utils
|
||||
|
||||
from sphinx.util.compat import Directive
|
||||
from docutils import nodes
|
||||
|
||||
|
||||
class BlogDateDirective(Directive):
|
||||
"""
|
||||
Used to parse/attach date info to blog post documents.
|
||||
|
||||
No nodes generated, since none are needed.
|
||||
"""
|
||||
has_content = True
|
||||
|
||||
def run(self):
|
||||
# Tag parent document with parsed date value.
|
||||
self.state.document.blog_date = datetime.strptime(
|
||||
self.content[0], "%Y-%m-%d"
|
||||
)
|
||||
# Don't actually insert any nodes, we're already done.
|
||||
return []
|
||||
|
||||
class blog_post_list(nodes.General, nodes.Element):
|
||||
pass
|
||||
|
||||
class BlogPostListDirective(Directive):
|
||||
"""
|
||||
Simply spits out a 'blog_post_list' temporary node for replacement.
|
||||
|
||||
Gets replaced at doctree-resolved time - only then will all blog post
|
||||
documents be written out (& their date directives executed).
|
||||
"""
|
||||
def run(self):
|
||||
return [blog_post_list('')]
|
||||
|
||||
|
||||
Post = namedtuple('Post', 'name doc title date opener')
|
||||
|
||||
def get_posts(app):
|
||||
# Obtain blog posts
|
||||
post_names = filter(lambda x: x.startswith('blog/'), app.env.found_docs)
|
||||
posts = map(lambda x: (x, app.env.get_doctree(x)), post_names)
|
||||
# Obtain common data used for list page & RSS
|
||||
data = []
|
||||
for post, doc in sorted(posts, key=lambda x: x[1].blog_date, reverse=True):
|
||||
# Welp. No "nice" way to get post title. Thanks Sphinx.
|
||||
title = doc[0][0][0]
|
||||
# Date. This may or may not end up reflecting the required
|
||||
# *input* format, but doing it here gives us flexibility.
|
||||
date = doc.blog_date
|
||||
# 1st paragraph as opener. TODO: allow a role or something marking
|
||||
# where to actually pull from?
|
||||
opener = doc.traverse(nodes.paragraph)[0]
|
||||
data.append(Post(post, doc, title, date, opener))
|
||||
return data
|
||||
|
||||
def replace_blog_post_lists(app, doctree, fromdocname):
|
||||
"""
|
||||
Replace blog_post_list nodes with ordered list-o-links to posts.
|
||||
"""
|
||||
# Obtain blog posts
|
||||
post_names = filter(lambda x: x.startswith('blog/'), app.env.found_docs)
|
||||
posts = map(lambda x: (x, app.env.get_doctree(x)), post_names)
|
||||
# Build "list" of links/etc
|
||||
post_links = []
|
||||
for post, doc, title, date, opener in get_posts(app):
|
||||
# Link itself
|
||||
uri = app.builder.get_relative_uri(fromdocname, post)
|
||||
link = nodes.reference('', '', refdocname=post, refuri=uri)
|
||||
# Title, bolded. TODO: use 'topic' or something maybe?
|
||||
link.append(nodes.strong('', title))
|
||||
date = date.strftime("%Y-%m-%d")
|
||||
# Meh @ not having great docutils nodes which map to this.
|
||||
html = '<div class="timestamp"><span>%s</span></div>' % date
|
||||
timestamp = nodes.raw(text=html, format='html')
|
||||
# NOTE: may group these within another element later if styling
|
||||
# necessitates it
|
||||
group = [timestamp, nodes.paragraph('', '', link), opener]
|
||||
post_links.extend(group)
|
||||
|
||||
# Replace temp node(s) w/ expanded list-o-links
|
||||
for node in doctree.traverse(blog_post_list):
|
||||
node.replace_self(post_links)
|
||||
|
||||
def rss_timestamp(timestamp):
|
||||
# Use horribly inappropriate module for its magical daylight-savings-aware
|
||||
# timezone madness. Props to Tinkerer for the idea.
|
||||
return email.utils.formatdate(
|
||||
time.mktime(timestamp.timetuple()),
|
||||
localtime=True
|
||||
)
|
||||
|
||||
def generate_rss(app):
|
||||
# Meh at having to run this subroutine like 3x per build. Not worth trying
|
||||
# to be clever for now tho.
|
||||
posts_ = get_posts(app)
|
||||
# LOL URLs
|
||||
root = app.config.rss_link
|
||||
if not root.endswith('/'):
|
||||
root += '/'
|
||||
# Oh boy
|
||||
posts = [
|
||||
(
|
||||
root + app.builder.get_target_uri(x.name),
|
||||
x.title,
|
||||
str(x.opener[0]), # Grab inner text element from paragraph
|
||||
rss_timestamp(x.date),
|
||||
)
|
||||
for x in posts_
|
||||
]
|
||||
location = 'blog/rss.xml'
|
||||
context = {
|
||||
'title': app.config.project,
|
||||
'link': root,
|
||||
'atom': root + location,
|
||||
'description': app.config.rss_description,
|
||||
# 'posts' is sorted by date already
|
||||
'date': rss_timestamp(posts_[0].date),
|
||||
'posts': posts,
|
||||
}
|
||||
yield (location, context, 'rss.xml')
|
||||
|
||||
def setup(app):
|
||||
# Link in RSS feed back to main website, e.g. 'http://paramiko.org'
|
||||
app.add_config_value('rss_link', None, '')
|
||||
# Ditto for RSS description field
|
||||
app.add_config_value('rss_description', None, '')
|
||||
# Interprets date metadata in blog post documents
|
||||
app.add_directive('date', BlogDateDirective)
|
||||
# Inserts blog post list node (in e.g. a listing page) for replacement
|
||||
# below
|
||||
app.add_node(blog_post_list)
|
||||
app.add_directive('blog-posts', BlogPostListDirective)
|
||||
# Performs abovementioned replacement
|
||||
app.connect('doctree-resolved', replace_blog_post_lists)
|
||||
# Generates RSS page from whole cloth at page generation step
|
||||
app.connect('html-collect-pages', generate_rss)
|
|
@ -0,0 +1,16 @@
|
|||
====
|
||||
Blog
|
||||
====
|
||||
|
||||
.. blog-posts directive gets replaced with an ordered list of blog posts.
|
||||
|
||||
.. blog-posts::
|
||||
|
||||
|
||||
.. The following toctree ensures blog posts get processed.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:glob:
|
||||
|
||||
blog/*
|
|
@ -0,0 +1,7 @@
|
|||
===========
|
||||
First post!
|
||||
===========
|
||||
|
||||
A blog post.
|
||||
|
||||
.. date:: 2013-12-04
|
|
@ -0,0 +1,7 @@
|
|||
===========
|
||||
Another one
|
||||
===========
|
||||
|
||||
.. date:: 2013-12-05
|
||||
|
||||
Indeed!
|
|
@ -0,0 +1,116 @@
|
|||
=========
|
||||
Changelog
|
||||
=========
|
||||
|
||||
* :release:`1.12.2 <2014-01-21>`
|
||||
* :release:`1.11.4 <2014-01-21>` 193
|
||||
* :release:`1.10.6 <2014-01-21>` 193
|
||||
* :bug:`193` (and its attentant PRs :issue:`230` & :issue:`253`): Fix SSH agent
|
||||
problems present on Windows. Thanks to David Hobbs for initial report and to
|
||||
Aarni Koskela & Olle Lundberg for the patches.
|
||||
* :release:`1.12.1 <2014-01-08>`
|
||||
* :release:`1.11.3 <2014-01-08>` 176
|
||||
* :release:`1.10.5 <2014-01-08>` 176
|
||||
* :bug:`225` Note ecdsa requirement in README. Thanks to Amaury Rodriguez for
|
||||
the catch.
|
||||
* :bug:`176` Fix AttributeError bugs in known_hosts file (re)loading. Thanks
|
||||
to Nathan Scowcroft for the patch & Martin Blumenstingl for the initial test
|
||||
case.
|
||||
* :release:`1.12.0 <2013-09-27>`
|
||||
* :release:`1.11.2 <2013-09-27>`
|
||||
* :release:`1.10.4 <2013-09-27>` 199, 200, 179
|
||||
* :feature:`152` Add tentative support for ECDSA keys. *This adds the ecdsa
|
||||
module as a new dependency of Paramiko.* The module is available at
|
||||
[warner/python-ecdsa on Github](https://github.com/warner/python-ecdsa) and
|
||||
[ecdsa on PyPI](https://pypi.python.org/pypi/ecdsa).
|
||||
|
||||
* Note that you might still run into problems with key negotiation --
|
||||
Paramiko picks the first key that the server offers, which might not be
|
||||
what you have in your known_hosts file.
|
||||
* Mega thanks to Ethan Glasser-Camp for the patch.
|
||||
|
||||
* :feature:`136` Add server-side support for the SSH protocol's 'env' command.
|
||||
Thanks to Benjamin Pollack for the patch.
|
||||
* :bug:`156` Fix potential deadlock condition when using Channel objects as
|
||||
sockets (e.g. when using SSH gatewaying). Thanks to Steven Noonan and Frank
|
||||
Arnold for catch & patch.
|
||||
* :bug:`179` Fix a missing variable causing errors when an ssh_config file has
|
||||
a non-default AddressFamily set. Thanks to Ed Marshall & Tomaz Muraus for
|
||||
catch & patch.
|
||||
* :bug:`200` Fix an exception-causing typo in ``demo_simple.py``. Thanks to Alex
|
||||
Buchanan for catch & Dave Foster for patch.
|
||||
* :bug:`199` Typo fix in the license header cross-project. Thanks to Armin
|
||||
Ronacher for catch & patch.
|
||||
* :release:`1.11.1 <2013-09-20>`
|
||||
* :release:`1.10.3 <2013-09-20>`
|
||||
* :bug:`162` Clean up HMAC module import to avoid deadlocks in certain uses of
|
||||
SSHClient. Thanks to Gernot Hillier for the catch & suggested fix.
|
||||
* :bug:`36` Fix the port-forwarding demo to avoid file descriptor errors.
|
||||
Thanks to Jonathan Halcrow for catch & patch.
|
||||
* :bug:`168` Update config handling to properly handle multiple 'localforward'
|
||||
and 'remoteforward' keys. Thanks to Emre Yılmaz for the patch.
|
||||
* :release:`1.11.0 <2013-07-26>`
|
||||
* :release:`1.10.2 <2013-07-26>`
|
||||
* :bug:`98 major` On Windows, when interacting with the PuTTY PAgeant, Paramiko
|
||||
now creates the shared memory map with explicit Security Attributes of the
|
||||
user, which is the same technique employed by the canonical PuTTY library to
|
||||
avoid permissions issues when Paramiko is running under a different UAC
|
||||
context than the PuTTY Ageant process. Thanks to Jason R. Coombs for the
|
||||
patch.
|
||||
* :support:`100` Remove use of PyWin32 in ``win_pageant`` module. Module was
|
||||
already dependent on ctypes for constructing appropriate structures and had
|
||||
ctypes implementations of all functionality. Thanks to Jason R. Coombs for
|
||||
the patch.
|
||||
* :bug:`87 major` Ensure updates to ``known_hosts`` files account for any
|
||||
updates to said files after Paramiko initially read them. (Includes related
|
||||
fix to guard against duplicate entries during subsequent ``known_hosts``
|
||||
loads.) Thanks to ``@sunweaver`` for the contribution.
|
||||
* :bug:`153` (also :issue:`67`) Warn on parse failure when reading known_hosts
|
||||
file. Thanks to ``@glasserc`` for patch.
|
||||
* :bug:`146` Indentation fixes for readability. Thanks to Abhinav Upadhyay for
|
||||
catch & patch.
|
||||
* :release:`1.10.1 <2013-04-05>`
|
||||
* :bug:`142` (`Fabric #811 <https://github.com/fabric/fabric/issues/811>`_)
|
||||
SFTP put of empty file will still return the attributes of the put file.
|
||||
Thanks to Jason R. Coombs for the patch.
|
||||
* :bug:`154` (`Fabric #876 <https://github.com/fabric/fabric/issues/876>`_)
|
||||
Forwarded SSH agent connections left stale local pipes lying around, which
|
||||
could cause local (and sometimes remote or network) resource starvation when
|
||||
running many agent-using remote commands. Thanks to Kevin Tegtmeier for catch
|
||||
& patch.
|
||||
* :release:`1.10.0 <2013-03-01>`
|
||||
* :feature:`66` Batch SFTP writes to help speed up file transfers. Thanks to
|
||||
Olle Lundberg for the patch.
|
||||
* :bug:`133 major` Fix handling of window-change events to be on-spec and not
|
||||
attempt to wait for a response from the remote sshd; this fixes problems with
|
||||
less common targets such as some Cisco devices. Thanks to Phillip Heller for
|
||||
catch & patch.
|
||||
* :feature:`93` Overhaul SSH config parsing to be in line with ``man
|
||||
ssh_config`` (& the behavior of ``ssh`` itself), including addition of parameter
|
||||
expansion within config values. Thanks to Olle Lundberg for the patch.
|
||||
* :feature:`110` Honor SSH config ``AddressFamily`` setting when looking up
|
||||
local host's FQDN. Thanks to John Hensley for the patch.
|
||||
* :feature:`128` Defer FQDN resolution until needed, when parsing SSH config
|
||||
files. Thanks to Parantapa Bhattacharya for catch & patch.
|
||||
* :bug:`102 major` Forego random padding for packets when running under
|
||||
``*-ctr`` ciphers. This corrects some slowdowns on platforms where random
|
||||
byte generation is inefficient (e.g. Windows). Thanks to ``@warthog618`` for
|
||||
catch & patch, and Michael van der Kolff for code/technique review.
|
||||
* :feature:`127` Turn ``SFTPFile`` into a context manager. Thanks to Michael
|
||||
Williamson for the patch.
|
||||
* :feature:`116` Limit ``Message.get_bytes`` to an upper bound of 1MB to protect
|
||||
against potential DoS vectors. Thanks to ``@mvschaik`` for catch & patch.
|
||||
* :feature:`115` Add convenience ``get_pty`` kwarg to ``Client.exec_command`` so
|
||||
users not manually controlling a channel object can still toggle PTY
|
||||
creation. Thanks to Michael van der Kolff for the patch.
|
||||
* :feature:`71` Add ``SFTPClient.putfo`` and ``.getfo`` methods to allow direct
|
||||
uploading/downloading of file-like objects. Thanks to Eric Buehl for the
|
||||
patch.
|
||||
* :feature:`113` Add ``timeout`` parameter to ``SSHClient.exec_command`` for
|
||||
easier setting of the command's internal channel object's timeout. Thanks to
|
||||
Cernov Vladimir for the patch.
|
||||
* :support:`94` Remove duplication of SSH port constant. Thanks to Olle
|
||||
Lundberg for the catch.
|
||||
* :feature:`80` Expose the internal "is closed" property of the file transfer
|
||||
class ``BufferedFile`` as ``.closed``, better conforming to Python's file
|
||||
interface. Thanks to ``@smunaut`` and James Hiscock for catch & patch.
|
|
@ -0,0 +1,35 @@
|
|||
# Obtain shared config values
|
||||
import sys
|
||||
import os
|
||||
from os.path import abspath, join, dirname
|
||||
|
||||
sys.path.append(abspath(join(dirname(__file__), '..')))
|
||||
from shared_conf import *
|
||||
|
||||
# Local blog extension
|
||||
sys.path.append(abspath('.'))
|
||||
extensions = ['blog']
|
||||
rss_link = 'http://paramiko.org'
|
||||
rss_description = 'Paramiko project news'
|
||||
|
||||
# Releases changelog extension
|
||||
extensions.append('releases')
|
||||
releases_release_uri = "https://github.com/paramiko/paramiko/tree/%s"
|
||||
releases_issue_uri = "https://github.com/paramiko/paramiko/issues/%s"
|
||||
|
||||
# Intersphinx for referencing API/usage docs
|
||||
extensions.append('sphinx.ext.intersphinx')
|
||||
# Default is 'local' building, but reference the public docs site when building
|
||||
# under RTD.
|
||||
target = join(dirname(__file__), '..', 'docs', '_build')
|
||||
if os.environ.get('READTHEDOCS') == 'True':
|
||||
# TODO: switch to docs.paramiko.org post go-live of sphinx API docs
|
||||
target = 'http://paramiko-docs.readthedocs.org/en/latest/'
|
||||
#intersphinx_mapping = {
|
||||
# 'docs': (target, None),
|
||||
#}
|
||||
|
||||
# Sister-site links to API docs
|
||||
html_theme_options['extra_nav_links'] = {
|
||||
"API Docs": 'http://docs.paramiko.org',
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
=======
|
||||
Contact
|
||||
=======
|
||||
|
||||
You can get in touch with the developer & user community in any of the
|
||||
following ways:
|
||||
|
||||
* IRC: ``#paramiko`` on Freenode
|
||||
* Mailing list: ``paramiko@librelist.com`` (see `the LibreList homepage
|
||||
<http://librelist.com>`_ for usage details).
|
||||
* This website's :doc:`blog </blog>`.
|
|
@ -0,0 +1,19 @@
|
|||
============
|
||||
Contributing
|
||||
============
|
||||
|
||||
How to get the code
|
||||
===================
|
||||
|
||||
Our primary Git repository is on Github at `paramiko/paramiko
|
||||
<https://github.com/paramiko/paramiko>`; please follow their instruction for
|
||||
cloning to your local system. (If you intend to submit patches/pull requests,
|
||||
we recommend forking first, then cloning your fork. Github has excellent
|
||||
documentation for all this.)
|
||||
|
||||
|
||||
How to submit bug reports or new code
|
||||
=====================================
|
||||
|
||||
Please see `this project-agnostic contribution guide
|
||||
<http://contribution-guide.org>`_ - we follow it explicitly.
|
|
@ -0,0 +1,38 @@
|
|||
Welcome to Paramiko!
|
||||
====================
|
||||
|
||||
Paramiko is a Python (2.5+) implementation of the SSHv2 protocol [#]_,
|
||||
providing both client and server functionality. While it leverages a Python C
|
||||
extension for low level cryptography (`PyCrypto <http://pycrypto.org>`_),
|
||||
Paramiko itself is a pure Python interface around SSH networking concepts.
|
||||
|
||||
This website covers project information for Paramiko such as the changelog,
|
||||
contribution guidelines, development roadmap, news/blog, and so forth. Detailed
|
||||
usage and API documentation can be found at our code documentation site,
|
||||
`docs.paramiko.org <http://docs.paramiko.org>`_.
|
||||
|
||||
.. toctree::
|
||||
changelog
|
||||
installing
|
||||
contributing
|
||||
contact
|
||||
|
||||
.. Hide blog in hidden toctree for now (to avoid warnings.)
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
blog
|
||||
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
.. [#]
|
||||
SSH is defined in RFCs
|
||||
`4251 <http://www.rfc-editor.org/rfc/rfc4251.txt>`_,
|
||||
`4252 <http://www.rfc-editor.org/rfc/rfc4252.txt>`_,
|
||||
`4253 <http://www.rfc-editor.org/rfc/rfc4253.txt>`_, and
|
||||
`4254 <http://www.rfc-editor.org/rfc/rfc4254.txt>`_;
|
||||
the primary working implementation of the protocol is the `OpenSSH project
|
||||
<http://openssh.org>`_. Paramiko implements a large portion of the SSH
|
||||
feature set, but there are occasional gaps.
|
|
@ -0,0 +1,105 @@
|
|||
==========
|
||||
Installing
|
||||
==========
|
||||
|
||||
Paramiko itself
|
||||
===============
|
||||
|
||||
The recommended way to get Invoke is to **install the latest stable release**
|
||||
via `pip <http://pip-installer.org>`_::
|
||||
|
||||
$ pip install paramiko
|
||||
|
||||
.. note::
|
||||
Users who want the bleeding edge can install the development version via
|
||||
``pip install paramiko==dev``.
|
||||
|
||||
We currently support **Python 2.5/2.6/2.7**, with support for Python 3 coming
|
||||
soon. Users on Python 2.4 or older are urged to upgrade. Paramiko *may* work on
|
||||
Python 2.4 still, but there is no longer any support guarantee.
|
||||
|
||||
Paramiko has two dependencies: the pure-Python ECDSA module `ecdsa`, and the
|
||||
PyCrypto C extension. `ecdsa` is easily installable from wherever you
|
||||
obtained Paramiko's package; PyCrypto may require more work. Read on for
|
||||
details.
|
||||
|
||||
PyCrypto
|
||||
========
|
||||
|
||||
`PyCrypto <https://www.dlitz.net/software/pycrypto/>`_ provides the low-level
|
||||
(C-based) encryption algorithms we need to implement the SSH protocol. There
|
||||
are a couple gotchas associated with installing PyCrypto: its compatibility
|
||||
with Python's package tools, and the fact that it is a C-based extension.
|
||||
|
||||
.. _pycrypto-and-pip:
|
||||
|
||||
Possible gotcha on older Python and/or pip versions
|
||||
---------------------------------------------------
|
||||
|
||||
We strongly recommend using ``pip`` to as it is newer and generally better than
|
||||
``easy_install``. However, a combination of bugs in specific (now rather old)
|
||||
versions of Python, ``pip`` and PyCrypto can prevent installation of PyCrypto.
|
||||
Specifically:
|
||||
|
||||
* Python = 2.5.x
|
||||
* PyCrypto >= 2.1 (required for most modern versions of Paramiko)
|
||||
* ``pip`` < 0.8.1
|
||||
|
||||
When all three criteria are met, you may encounter ``No such file or
|
||||
directory`` IOErrors when trying to ``pip install paramiko`` or ``pip install
|
||||
PyCrypto``.
|
||||
|
||||
The fix is to make sure at least one of the above criteria is not met, by doing
|
||||
the following (in order of preference):
|
||||
|
||||
* Upgrade to ``pip`` 0.8.1 or above, e.g. by running ``pip install -U pip``.
|
||||
* Upgrade to Python 2.6 or above.
|
||||
* Downgrade to Paramiko 1.7.6 or 1.7.7, which do not require PyCrypto >= 2.1,
|
||||
and install PyCrypto 2.0.1 (the oldest version on PyPI which works with
|
||||
Paramiko 1.7.6/1.7.7)
|
||||
|
||||
|
||||
C extension
|
||||
-----------
|
||||
|
||||
Unless you are installing from a precompiled source such as a Debian apt
|
||||
repository or RedHat RPM, or using :ref:`pypm <pypm>`, you will also need the
|
||||
ability to build Python C-based modules from source in order to install
|
||||
PyCrypto. Users on **Unix-based platforms** such as Ubuntu or Mac OS X will
|
||||
need the traditional C build toolchain installed (e.g. Developer Tools / XCode
|
||||
Tools on the Mac, or the ``build-essential`` package on Ubuntu or Debian Linux
|
||||
-- basically, anything with ``gcc``, ``make`` and so forth) as well as the
|
||||
Python development libraries, often named ``python-dev`` or similar.
|
||||
|
||||
For **Windows** users we recommend using :ref:`pypm`, installing a C
|
||||
development environment such as `Cygwin <http://cygwin.com>`_ or obtaining a
|
||||
precompiled Win32 PyCrypto package from `voidspace's Python modules page
|
||||
<http://www.voidspace.org.uk/python/modules.shtml#pycrypto>`_.
|
||||
|
||||
.. note::
|
||||
Some Windows users whose Python is 64-bit have found that the PyCrypto
|
||||
dependency ``winrandom`` may not install properly, leading to ImportErrors.
|
||||
In this scenario, you'll probably need to compile ``winrandom`` yourself
|
||||
via e.g. MS Visual Studio. See `Fabric #194
|
||||
<https://github.com/fabric/fabric/issues/194>`_ for info.
|
||||
|
||||
|
||||
.. _pypm:
|
||||
|
||||
ActivePython and PyPM
|
||||
=====================
|
||||
|
||||
Windows users who already have ActiveState's `ActivePython
|
||||
<http://www.activestate.com/activepython/downloads>`_ distribution installed
|
||||
may find Paramiko is best installed with `its package manager, PyPM
|
||||
<http://code.activestate.com/pypm/>`_. Below is example output from an
|
||||
installation of Paramiko via ``pypm``::
|
||||
|
||||
C:\> pypm install paramiko
|
||||
The following packages will be installed into "%APPDATA%\Python" (2.7):
|
||||
paramiko-1.7.8 pycrypto-2.4
|
||||
Get: [pypm-free.activestate.com] paramiko 1.7.8
|
||||
Get: [pypm-free.activestate.com] pycrypto 2.4
|
||||
Installing paramiko-1.7.8
|
||||
Installing pycrypto-2.4
|
||||
C:\>
|
|
@ -0,0 +1,23 @@
|
|||
from os.path import join
|
||||
|
||||
from invoke import Collection
|
||||
from invocations import docs as _docs, testing
|
||||
|
||||
|
||||
d = 'sites'
|
||||
|
||||
# Usage doc/API site (published as docs.paramiko.org)
|
||||
path = join(d, 'docs')
|
||||
docs = Collection.from_module(_docs, name='docs', config={
|
||||
'sphinx.source': path,
|
||||
'sphinx.target': join(path, '_build'),
|
||||
})
|
||||
|
||||
# Main/about/changelog site ((www.)?paramiko.org)
|
||||
path = join(d, 'www')
|
||||
www = Collection.from_module(_docs, name='www', config={
|
||||
'sphinx.source': path,
|
||||
'sphinx.target': join(path, '_build'),
|
||||
})
|
||||
|
||||
ns = Collection(testing.test, docs=docs, www=www)
|
|
@ -0,0 +1,2 @@
|
|||
# Not sure why tox can't just read setup.py?
|
||||
pycrypto
|
Loading…
Reference in New Issue