summaryrefslogtreecommitdiffstats
path: root/qa/tasks/ceph_iscsi.py
blob: a8870743a09f129145c11c82b7fddd2c1f1bdb87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""
Run ceph-iscsi cluster setup
"""
import logging
import contextlib
from io import StringIO
from teuthology.exceptions import CommandFailedError, ConnectionLostError
from teuthology.orchestra import run
from textwrap import dedent

log = logging.getLogger(__name__)

class IscsiSetup(object):
    def __init__(self, ctx, config):
        self.ctx = ctx
        self.config = config
        self.target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:ceph-gw"
        self.client_iqn = "iqn.1994-05.com.redhat:client"
        self.trusted_ip_list = []
        self.background_procs = []

    def run_daemon(self, remote, cmds):
        p = remote.run(args=['sudo', 'adjust-ulimits', 'daemon-helper', 'kill', cmds],
                          wait=False, stdin=run.PIPE, stdout=StringIO())
        self.background_procs.append(p)

    def _kill_background(self, p):
        if p.stdin:
            p.stdin.close()
            try:
                p.wait()
            except (CommandFailedError, ConnectionLostError):
                pass

    def kill_backgrounds(self):
        for p in self.background_procs:
            self._kill_background(p)
        self.background_procs = []

    def _setup_iscsi_gateway_cfg(self, role):
        # setup the iscsi-gateway.cfg file, we only set the
        # clust_name and trusted_ip_list and all the others
        # as default
        ips = ','.join(self.trusted_ip_list)
        conf = dedent(f'''\
[config]
cluster_name = ceph
pool = rbd
api_secure = false
api_port = 5000
trusted_ip_list = {ips}
''')
        path = "/etc/ceph/iscsi-gateway.cfg"
        (remote,) = (self.ctx.cluster.only(role).remotes.keys())
        remote.sudo_write_file(path, conf)

    def _setup_gateway(self, role):
        """Spawned task that setups the gateway"""
        (remote,) = (self.ctx.cluster.only(role).remotes.keys())

        self._setup_iscsi_gateway_cfg(role)

        self.run_daemon(remote, "/usr/bin/tcmu-runner")
        self.run_daemon(remote, "/usr/bin/rbd-target-gw")
        self.run_daemon(remote, "/usr/bin/rbd-target-api")

    def setup_gateways(self):
        for role in self.config['gateways']:
            (remote,) = (self.ctx.cluster.only(role).remotes.keys())
            self.trusted_ip_list.append(remote.ip_address)

        for role in self.config['gateways']:
            self._setup_gateway(role)

    def _setup_client(self, role):
        """Spawned task that setups the gateway"""
        (remote,) = (self.ctx.cluster.only(role).remotes.keys())

        # copy the "iscsi-gateway.cfg" to client and will be
        # used to get the IPs
        self._setup_iscsi_gateway_cfg(role)

        conf = dedent(f'''
InitiatorName={self.client_iqn}
''')
        path = "/etc/iscsi/initiatorname.iscsi"
        remote.sudo_write_file(path, conf, mkdir=True)

        # the restart is needed after the above change is applied
        remote.run(args=['sudo', 'systemctl', 'restart', 'iscsid'])

        remote.run(args=['sudo', 'modprobe', 'dm_multipath'])
        remote.run(args=['sudo', 'mpathconf', '--enable'])
        conf = dedent('''\
devices {
        device {
                vendor                 "LIO-ORG"
                product                "LIO-ORG"
                hardware_handler       "1 alua"
                path_grouping_policy   "failover"
                path_selector          "queue-length 0"
                failback               60
                path_checker           tur
                prio                   alua
                prio_args              exclusive_pref_bit
                fast_io_fail_tmo       25
                no_path_retry          queue
        }
}
''')
        path = "/etc/multipath.conf"
        remote.sudo_write_file(path, conf, append=True)
        remote.run(args=['sudo', 'systemctl', 'start', 'multipathd'])

    def setup_clients(self):
        for role in self.config['clients']:
            self._setup_client(role)

@contextlib.contextmanager
def task(ctx, config):
    """
    Run ceph iscsi setup.

    Specify the list of gateways to run ::

      tasks:
        ceph_iscsi:
          gateways: [a_gateway.0, c_gateway.1]
          clients: [b_client.0]

    """
    log.info('Setting ceph iscsi cluster...')
    iscsi = IscsiSetup(ctx, config)
    iscsi.setup_gateways()
    iscsi.setup_clients()

    try:
        yield
    finally:
        log.info('Ending ceph iscsi daemons')
        iscsi.kill_backgrounds()