~gandelman-a/charms/precise/keystone/utils_sync

« back to all changes in this revision

Viewing changes to hooks/lib/unison.py

  • Committer: Adam Gandelman
  • Date: 2013-03-19 18:06:25 UTC
  • mfrom: (57.1.25 keystone)
  • Revision ID: adamg@canonical.com-20130319180625-ov50yaiiec32s15c
Big refactor and cleanup from James.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
#       Either copy required functionality to this library or depend on
41
41
#       something more generic.
42
42
 
43
 
import json
44
43
import os
45
44
import sys
46
 
import utils
 
45
import lib.utils as utils
47
46
import subprocess
48
 
import shutil
49
47
import grp
50
48
import pwd
51
49
 
55
53
        user = pwd.getpwnam(user)
56
54
        return user.pw_dir
57
55
    except KeyError:
58
 
        utils.juju_log('Could not get homedir for user %s: user exists?')
 
56
        utils.juju_log('INFO',
 
57
                       'Could not get homedir for user %s: user exists?')
59
58
        sys.exit(1)
60
59
 
61
60
 
67
66
 
68
67
    priv_key = os.path.join(ssh_dir, 'id_rsa')
69
68
    if not os.path.isfile(priv_key):
70
 
        utils.juju_log('Generating new ssh key for user %s.' % user)
 
69
        utils.juju_log('INFO', 'Generating new ssh key for user %s.' % user)
71
70
        cmd = ['ssh-keygen', '-q', '-N', '', '-t', 'rsa', '-b', '2048',
72
71
               '-f', priv_key]
73
72
        subprocess.check_call(cmd)
74
73
 
75
74
    pub_key = '%s.pub' % priv_key
76
75
    if not os.path.isfile(pub_key):
77
 
        utils.juju_log('Generatring missing ssh public key @ %s.' % pub_key)
 
76
        utils.juju_log('INFO', 'Generatring missing ssh public key @ %s.' % \
 
77
                       pub_key)
78
78
        cmd = ['ssh-keygen', '-y', '-f', priv_key]
79
79
        p = subprocess.check_output(cmd).strip()
80
80
        with open(pub_key, 'wb') as out:
81
81
            out.write(p)
82
82
    subprocess.check_call(['chown', '-R', user, ssh_dir])
83
 
    return open(priv_key, 'r').read().strip(), open(pub_key, 'r').read().strip()
 
83
    return open(priv_key, 'r').read().strip(), \
 
84
           open(pub_key, 'r').read().strip()
84
85
 
85
86
 
86
87
def write_authorized_keys(user, keys):
87
88
    home_dir = get_homedir(user)
88
89
    ssh_dir = os.path.join(home_dir, '.ssh')
89
90
    auth_keys = os.path.join(ssh_dir, 'authorized_keys')
90
 
    utils.juju_log('Syncing authorized_keys @ %s.' % auth_keys)
 
91
    utils.juju_log('INFO', 'Syncing authorized_keys @ %s.' % auth_keys)
91
92
    with open(auth_keys, 'wb') as out:
92
93
        for k in keys:
93
94
            out.write('%s\n' % k)
96
97
def write_known_hosts(user, hosts):
97
98
    home_dir = get_homedir(user)
98
99
    ssh_dir = os.path.join(home_dir, '.ssh')
99
 
    known_hosts  = os.path.join(ssh_dir, 'known_hosts')
 
100
    known_hosts = os.path.join(ssh_dir, 'known_hosts')
100
101
    khosts = []
101
102
    for host in hosts:
102
103
        cmd = ['ssh-keyscan', '-H', '-t', 'rsa', host]
103
104
        remote_key = subprocess.check_output(cmd).strip()
104
105
        khosts.append(remote_key)
105
 
    utils.juju_log('Syncing known_hosts @ %s.' % known_hosts)
 
106
    utils.juju_log('INFO', 'Syncing known_hosts @ %s.' % known_hosts)
106
107
    with open(known_hosts, 'wb') as out:
107
108
        for host in khosts:
108
109
            out.write('%s\n' % host)
113
114
    try:
114
115
        pwd.getpwnam(user)
115
116
    except KeyError:
116
 
        utils.juju_log('Creating new user %s.%s.' % (user, group))
 
117
        utils.juju_log('INFO', 'Creating new user %s.%s.' % (user, group))
117
118
        cmd = ['adduser', '--system', '--shell', '/bin/bash', user]
118
119
        if group:
119
120
            try:
134
135
    priv_key, pub_key = get_keypair(user)
135
136
    hook = os.path.basename(sys.argv[0])
136
137
    if hook == '%s-relation-joined' % peer_interface:
137
 
        utils.relation_set_2(ssh_pub_key=pub_key)
 
138
        utils.relation_set(ssh_pub_key=pub_key)
138
139
        print 'joined'
139
140
    elif hook == '%s-relation-changed' % peer_interface:
140
141
        hosts = []
147
148
                    keys.append(settings['ssh_pub_key'])
148
149
                    hosts.append(settings['private-address'])
149
150
                else:
150
 
                    utils.juju_log('ssh_authorized_peers(): ssh_pub_key '\
 
151
                    utils.juju_log('INFO',
 
152
                                   'ssh_authorized_peers(): ssh_pub_key '\
151
153
                                   'missing for unit %s, skipping.' % unit)
152
154
        write_authorized_keys(user, keys)
153
155
        write_known_hosts(user, hosts)
154
156
        authed_hosts = ':'.join(hosts)
155
 
        utils.relation_set_2(ssh_authorized_hosts=authed_hosts)
 
157
        utils.relation_set(ssh_authorized_hosts=authed_hosts)
156
158
 
157
159
 
158
160
def _run_as_user(user):
159
161
    try:
160
162
        user = pwd.getpwnam(user)
161
163
    except KeyError:
162
 
        utils.juju_log('Invalid user: %s' % user)
 
164
        utils.juju_log('INFO', 'Invalid user: %s' % user)
163
165
        sys.exit(1)
164
166
    uid, gid = user.pw_uid, user.pw_gid
165
167
    os.environ['HOME'] = user.pw_dir
 
168
 
166
169
    def _inner():
167
170
        os.setgid(gid)
168
171
        os.setuid(uid)
169
172
    return _inner
170
173
 
 
174
 
171
175
def run_as_user(user, cmd):
172
176
    return subprocess.check_output(cmd, preexec_fn=_run_as_user(user))
173
177
 
 
178
 
174
179
def sync_to_peers(peer_interface, user, paths=[], verbose=False):
175
180
    base_cmd = ['unison', '-auto', '-batch=true', '-confirmbigdel=false',
176
 
                '-fastcheck=true', '-group=false', '-owner=false', '-prefer=newer',
177
 
                '-times=true']
 
181
                '-fastcheck=true', '-group=false', '-owner=false',
 
182
                '-prefer=newer', '-times=true']
178
183
    if not verbose:
179
184
        base_cmd.append('-silent')
180
185
 
206
211
        # removing trailing slash from directory paths, unison
207
212
        # doesn't like these.
208
213
        if path.endswith('/'):
209
 
            path = path[:(len(path)-1)]
 
214
            path = path[:(len(path) - 1)]
210
215
        for host in hosts:
211
216
            cmd = base_cmd + [path, 'ssh://%s@%s/%s' % (user, host, path)]
212
 
            utils.juju_log('Syncing local path %s to %s@%s:%s' %\
 
217
            utils.juju_log('INFO', 'Syncing local path %s to %s@%s:%s' %\
213
218
                            (path, user, host, path))
214
219
            print ' '.join(cmd)
215
220
            run_as_user(user, cmd)