fetchers: Cleanup more variables
[bitbake.git] / lib / bb / fetch / ssh.py
1 #!/usr/bin/env python
2 # ex:ts=4:sw=4:sts=4:et
3 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4 '''
5 BitBake 'Fetch' implementations
6
7 This implementation is for Secure Shell (SSH), and attempts to comply with the
8 IETF secsh internet draft:
9     http://tools.ietf.org/wg/secsh/draft-ietf-secsh-scp-sftp-ssh-uri/
10
11     Currently does not support the sftp parameters, as this uses scp
12     Also does not support the 'fingerprint' connection parameter.
13
14 Copyright (C) 2006  OpenedHand Ltd.
15
16 Based in part on svk.py:
17     Copyright (C) 2006 Holger Hans Peter Freyther
18     Based on svn.py:
19         Copyright (C) 2003, 2004  Chris Larson
20         Based on functions from the base bb module:
21             Copyright 2003 Holger Schurig
22
23
24 This program is free software; you can redistribute it and/or modify it under
25 the terms of the GNU General Public License as published by the Free Software
26 Foundation; either version 2 of the License, or (at your option) any later
27 version.
28
29 This program is distributed in the hope that it will be useful, but WITHOUT
30 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
31 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
32
33 You should have received a copy of the GNU General Public License along with
34 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
35 Place, Suite 330, Boston, MA 02111-1307 USA.
36 '''
37 import re, os
38 import bb
39 from   bb import data
40 from   bb.fetch import Fetch
41 from   bb.fetch import FetchError
42 from   bb.fetch import MissingParameterError
43
44
45 __pattern__ = re.compile(r'''
46  \s*                 # Skip leading whitespace
47  ssh://              # scheme
48  (                   # Optional username/password block
49   (?P<user>\S+)      # username
50   (:(?P<pass>\S+))?  # colon followed by the password (optional)
51  )?
52  (?P<cparam>(;[^;]+)*)?  # connection parameters block (optional)
53  @
54  (?P<host>\S+?)          # non-greedy match of the host
55  (:(?P<port>[0-9]+))?    # colon followed by the port (optional)
56  /
57  (?P<path>[^;]+)         # path on the remote system, may be absolute or relative,
58                          # and may include the use of '~' to reference the remote home
59                          # directory
60  (?P<sparam>(;[^;]+)*)?  # parameters block (optional)
61  $
62 ''', re.VERBOSE)
63
64 class SSH(Fetch):
65     '''Class to fetch a module or modules via Secure Shell'''
66
67     def supports(self, url, urldata, d):
68         return __pattern__.match(url) != None
69
70     def localpath(self, url, urldata, d):
71         m = __pattern__.match(url)
72         path = m.group('path')
73         host = m.group('host')
74         lpath = os.path.join(data.getVar('DL_DIR', d, True), host, os.path.basename(path))
75         return lpath
76
77     def go(self, url, urldata, d):
78         dldir = data.getVar('DL_DIR', d, 1)
79
80         m = __pattern__.match(url)
81         path = m.group('path')
82         host = m.group('host')
83         port = m.group('port')
84         user = m.group('user')
85         password = m.group('pass')
86
87         ldir = os.path.join(dldir, host)
88         lpath = os.path.join(ldir, os.path.basename(path))
89
90         if not os.path.exists(ldir):
91             os.makedirs(ldir)
92
93         if port:
94             port = '-P %s' % port
95         else:
96             port = ''
97
98         if user:
99             fr = user
100             if password:
101                 fr += ':%s' % password
102             fr += '@%s' % host
103         else:
104             fr = host
105         fr += ':%s' % path
106
107
108         import commands
109         cmd = 'scp -B -r %s %s %s/' % (
110             port,
111             commands.mkarg(fr),
112             commands.mkarg(ldir)
113         )
114
115         (exitstatus, output) = commands.getstatusoutput(cmd)
116         if exitstatus != 0:
117             print output
118             raise FetchError('Unable to fetch %s' % url)