Create and use the mysql system user
Change-Id: Ife32e896a964596903ae24b1f0a36a956957747f
This commit is contained in:
parent
91f80513db
commit
454f6e9f8b
|
@ -14,11 +14,6 @@ options:
|
|||
.
|
||||
See https://wiki.ubuntu.com/OpenStack/CloudArchive for info on which
|
||||
cloud archives are available and supported.
|
||||
system-user:
|
||||
# TODO What user? No mysql user exists. Create one?
|
||||
type: string
|
||||
description: System user to run mysqlrouter
|
||||
default: ubuntu
|
||||
base-port:
|
||||
type: int
|
||||
default: 3306
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import charms_openstack.charm
|
||||
|
@ -171,7 +172,7 @@ class MySQLRouterCharm(charms_openstack.charm.OpenStackCharm):
|
|||
return self.options.shared_db_address
|
||||
|
||||
@property
|
||||
def mysqlrouter_dir(self):
|
||||
def mysqlrouter_working_dir(self):
|
||||
"""Determine the path to the mysqlrouter working directory.
|
||||
|
||||
:param self: Self
|
||||
|
@ -179,7 +180,26 @@ class MySQLRouterCharm(charms_openstack.charm.OpenStackCharm):
|
|||
:returns: Path to the directory
|
||||
:rtype: str
|
||||
"""
|
||||
return "/home/{}/mysqlrouter".format(self.options.system_user)
|
||||
return "{}/mysqlrouter".format(self.mysqlrouter_home_dir)
|
||||
|
||||
@property
|
||||
def mysqlrouter_home_dir(self):
|
||||
"""Determine the path to the mysqlrouter working directory.
|
||||
|
||||
:param self: Self
|
||||
:type self: MySQLRouterCharm instance
|
||||
:returns: Path to the directory
|
||||
:rtype: str
|
||||
"""
|
||||
return "/var/lib/mysql"
|
||||
|
||||
@property
|
||||
def mysqlrouter_user(self):
|
||||
return "mysql"
|
||||
|
||||
@property
|
||||
def mysqlrouter_group(self):
|
||||
return "mysql"
|
||||
|
||||
def install(self):
|
||||
"""Custom install function.
|
||||
|
@ -195,6 +215,27 @@ class MySQLRouterCharm(charms_openstack.charm.OpenStackCharm):
|
|||
self.configure_source()
|
||||
super().install()
|
||||
|
||||
# Neither MySQL Router nor MySQL common packaging creates a user, group
|
||||
# or home dir. As we want it to run as a system user in a predictable
|
||||
# location create all of these.
|
||||
# Create the group
|
||||
if not ch_core.host.group_exists(self.mysqlrouter_group):
|
||||
ch_core.host.add_group(
|
||||
self.mysqlrouter_group, system_group=True)
|
||||
# Create the user
|
||||
if not ch_core.host.user_exists(self.mysqlrouter_user):
|
||||
ch_core.host.adduser(
|
||||
self.mysqlrouter_user, shell="/usr/sbin/nologin",
|
||||
system_user=True, primary_group=self.mysqlrouter_group,
|
||||
home_dir=self.mysqlrouter_home_dir)
|
||||
# Create the directory
|
||||
if not os.path.exists(self.mysqlrouter_home_dir):
|
||||
ch_core.host.mkdir(
|
||||
self.mysqlrouter_home_dir,
|
||||
owner=self.mysqlrouter_user,
|
||||
group=self.mysqlrouter_group,
|
||||
perms=0o755)
|
||||
|
||||
def get_db_helper(self):
|
||||
"""Get an instance of the MySQLDB8Helper class.
|
||||
|
||||
|
@ -307,12 +348,12 @@ class MySQLRouterCharm(charms_openstack.charm.OpenStackCharm):
|
|||
:rtype: None
|
||||
"""
|
||||
cmd = [self.mysqlrouter_bin,
|
||||
"--user", self.options.system_user,
|
||||
"--user", self.mysqlrouter_user,
|
||||
"--bootstrap",
|
||||
"{}:{}@{}".format(self.db_router_user,
|
||||
self.db_router_password,
|
||||
self.cluster_address),
|
||||
"--directory", self.mysqlrouter_dir,
|
||||
"--directory", self.mysqlrouter_working_dir,
|
||||
"--conf-use-sockets",
|
||||
"--conf-base-port", str(self.options.base_port)]
|
||||
try:
|
||||
|
@ -336,7 +377,7 @@ class MySQLRouterCharm(charms_openstack.charm.OpenStackCharm):
|
|||
:returns: This function is called for its side effect
|
||||
:rtype: None
|
||||
"""
|
||||
cmd = ["{}/start.sh".format(self.mysqlrouter_dir)]
|
||||
cmd = ["{}/start.sh".format(self.mysqlrouter_working_dir)]
|
||||
try:
|
||||
proc = subprocess.Popen(
|
||||
cmd, stdout=subprocess.PIPE,
|
||||
|
@ -362,7 +403,7 @@ class MySQLRouterCharm(charms_openstack.charm.OpenStackCharm):
|
|||
:returns: This function is called for its side effect
|
||||
:rtype: None
|
||||
"""
|
||||
cmd = ["{}/stop.sh".format(self.mysqlrouter_dir)]
|
||||
cmd = ["{}/stop.sh".format(self.mysqlrouter_working_dir)]
|
||||
try:
|
||||
proc = subprocess.Popen(
|
||||
cmd, stdout=subprocess.PIPE,
|
||||
|
|
|
@ -61,6 +61,7 @@ class TestMySQLRouterCharm(test_utils.PatchHelper):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.patch_object(mysql_router, "os")
|
||||
self.patch_object(mysql_router, "subprocess")
|
||||
self.patch_object(mysql_router.reactive.flags, "set_flag")
|
||||
self.patch_object(mysql_router.reactive.flags, "clear_flag")
|
||||
|
@ -68,6 +69,11 @@ class TestMySQLRouterCharm(test_utils.PatchHelper):
|
|||
mysql_router.reactive.relations, "endpoint_from_flag")
|
||||
self.patch_object(mysql_router.ch_net_ip, "get_relation_ip")
|
||||
self.patch_object(mysql_router.ch_core.hookenv, "local_unit")
|
||||
self.patch_object(mysql_router.ch_core.host, "adduser")
|
||||
self.patch_object(mysql_router.ch_core.host, "add_group")
|
||||
self.patch_object(mysql_router.ch_core.host, "user_exists")
|
||||
self.patch_object(mysql_router.ch_core.host, "group_exists")
|
||||
self.patch_object(mysql_router.ch_core.host, "mkdir")
|
||||
|
||||
self.stdout = mock.MagicMock()
|
||||
self.subprocess.STDOUT = self.stdout
|
||||
|
@ -210,23 +216,48 @@ class TestMySQLRouterCharm(test_utils.PatchHelper):
|
|||
mrc.shared_db_address,
|
||||
"127.0.0.1")
|
||||
|
||||
def test_mysqlrouter_dir(self):
|
||||
_user = "ubuntu"
|
||||
def test_mysqlrouter_working_dir(self):
|
||||
mrc = mysql_router.MySQLRouterCharm()
|
||||
mrc.options.system_user = _user
|
||||
self.assertEqual(
|
||||
mrc.mysqlrouter_dir,
|
||||
"/home/{}/mysqlrouter".format(_user))
|
||||
mrc.mysqlrouter_working_dir,
|
||||
"/var/lib/mysql/mysqlrouter")
|
||||
|
||||
def test_mysqlrouter_home_dir(self):
|
||||
mrc = mysql_router.MySQLRouterCharm()
|
||||
self.assertEqual(
|
||||
mrc.mysqlrouter_home_dir,
|
||||
"/var/lib/mysql")
|
||||
|
||||
def test_mysqlrouter_group(self):
|
||||
mrc = mysql_router.MySQLRouterCharm()
|
||||
self.assertEqual(
|
||||
mrc.mysqlrouter_group,
|
||||
"mysql")
|
||||
|
||||
def test_mysqlrouter_user(self):
|
||||
mrc = mysql_router.MySQLRouterCharm()
|
||||
self.assertEqual(
|
||||
mrc.mysqlrouter_user,
|
||||
"mysql")
|
||||
|
||||
def test_install(self):
|
||||
self.patch_object(
|
||||
mysql_router.charms_openstack.charm.OpenStackCharm,
|
||||
"install", "super_install")
|
||||
self.os.path.exists.return_value = False
|
||||
self.group_exists.return_value = False
|
||||
self.user_exists.return_value = False
|
||||
mrc = mysql_router.MySQLRouterCharm()
|
||||
mrc.configure_source = mock.MagicMock()
|
||||
mrc.install()
|
||||
self.super_install.assert_called_once()
|
||||
mrc.configure_source.assert_called_once()
|
||||
self.add_group.assert_called_once_with("mysql", system_group=True)
|
||||
self.adduser.assert_called_once_with(
|
||||
"mysql", home_dir="/var/lib/mysql", primary_group="mysql",
|
||||
shell="/usr/sbin/nologin", system_user=True)
|
||||
self.mkdir.assert_called_once_with(
|
||||
"/var/lib/mysql", group="mysql", owner="mysql", perms=0o755)
|
||||
|
||||
def test_get_db_helper(self):
|
||||
self.patch_object(
|
||||
|
@ -325,7 +356,7 @@ class TestMySQLRouterCharm(test_utils.PatchHelper):
|
|||
_json_pass = '"clusterpass"'
|
||||
_pass = json.loads(_json_pass)
|
||||
_addr = json.loads(_json_addr)
|
||||
_user = "ubuntu"
|
||||
_user = "mysql"
|
||||
_port = "3006"
|
||||
self.endpoint_from_flag.return_value = self.db_router
|
||||
self.db_router.password.return_value = _json_pass
|
||||
|
@ -340,7 +371,7 @@ class TestMySQLRouterCharm(test_utils.PatchHelper):
|
|||
self.subprocess.check_output.assert_called_once_with(
|
||||
[mrc.mysqlrouter_bin, "--user", _user, "--bootstrap",
|
||||
"{}:{}@{}".format(mrc.db_router_user, _pass, _addr),
|
||||
"--directory", mrc.mysqlrouter_dir, "--conf-use-sockets",
|
||||
"--directory", mrc.mysqlrouter_working_dir, "--conf-use-sockets",
|
||||
"--conf-base-port", _port],
|
||||
stderr=self.stdout)
|
||||
self.set_flag.assert_called_once_with(
|
||||
|
@ -356,7 +387,7 @@ class TestMySQLRouterCharm(test_utils.PatchHelper):
|
|||
self.set_flag.assert_not_called()
|
||||
|
||||
def test_start_mysqlrouter(self):
|
||||
_user = "ubuntu"
|
||||
_user = "mysql"
|
||||
_port = "3006"
|
||||
mrc = mysql_router.MySQLRouterCharm()
|
||||
mrc.options.system_user = _user
|
||||
|
@ -365,7 +396,7 @@ class TestMySQLRouterCharm(test_utils.PatchHelper):
|
|||
# Successful
|
||||
mrc.start_mysqlrouter()
|
||||
self.subprocess.Popen.assert_called_once_with(
|
||||
["/home/ubuntu/mysqlrouter/start.sh"],
|
||||
["/var/lib/mysql/mysqlrouter/start.sh"],
|
||||
bufsize=1,
|
||||
stdout=self.stdout,
|
||||
stderr=self.stdout,
|
||||
|
@ -391,7 +422,7 @@ class TestMySQLRouterCharm(test_utils.PatchHelper):
|
|||
# Successful
|
||||
mrc.stop_mysqlrouter()
|
||||
self.subprocess.Popen.assert_called_once_with(
|
||||
["/home/ubuntu/mysqlrouter/stop.sh"],
|
||||
["/var/lib/mysql/mysqlrouter/stop.sh"],
|
||||
bufsize=1,
|
||||
stdout=self.stdout,
|
||||
stderr=self.stdout,
|
||||
|
|
Loading…
Reference in New Issue