Skip to content

Commit fd5e963

Browse files
committed
Convert server deployment to use Docker images
This avoids the overhead of RPM install which has to validate every single file. That validation basically is done ahead of time in the process of creating the image that will be used. This saves about 25 seconds of runtime in the case of stopping and restarting.
1 parent 7f0e101 commit fd5e963

File tree

4 files changed

+67
-79
lines changed

4 files changed

+67
-79
lines changed

environment/aws/common/docker.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def start_container(
6161
host: str,
6262
docker_args: list[str] | None = None,
6363
container_args: list[str] | None = None,
64+
replace_existing: bool = False,
6465
) -> None:
6566
context_result = subprocess.run(
6667
["docker", "context", "ls", "--format", "{{.Name}}"],
@@ -108,17 +109,23 @@ def start_container(
108109

109110
if container_check.stdout.strip() != "":
110111
if container_check.stdout.startswith("Up"):
111-
click.echo(f"{name} already running, returning...")
112-
return
112+
if not replace_existing:
113+
click.echo(f"{name} already running, returning...")
114+
return
113115

114-
click.echo(f"Restarting existing {name} container...")
115-
subprocess.run(["docker", "start", name], check=False, env=env)
116-
return
116+
click.echo(f"Stopping existing {name} container...")
117+
subprocess.run(["docker", "stop", name], check=True, env=env)
118+
119+
if not replace_existing:
120+
click.echo(f"Restarting existing {name} container...")
121+
subprocess.run(["docker", "start", name], check=False, env=env)
122+
return
117123

118124
click.echo(f"Starting new {name} container...")
119125
args = [
120126
"docker",
121127
"run",
128+
"--rm",
122129
"-d",
123130
"--name",
124131
name,

environment/aws/server_setup/configure-node.sh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/sh
1+
#!/bin/bash
22

33
mkdir -p /home/ec2-user/logs
44

@@ -7,6 +7,7 @@ config_done() {
77
touch ${CONFIG_DONE_FILE}
88
echo "Couchbase Admin UI: http://localhost:8091" \
99
"\nLogin credentials: Administrator / password"
10+
sleep infinity
1011
}
1112

1213
if [ -e ${CONFIG_DONE_FILE} ]; then
@@ -65,14 +66,14 @@ curl_check() {
6566
wait_for_uri 200 http://localhost:8091/ui/index.html
6667
echo "Couchbase Server up!"
6768

68-
if [[ ! -z $1 ]]; then
69+
if [[ ! -z $E2E_PARENT_CLUSTER ]]; then
6970
my_ip=$(ifconfig | grep "inet 10" | awk '{print $2}')
70-
echo "Adding node to cluster"
71-
couchbase_cli_check server-add -c $1 -u Administrator -p password --server-add $my_ip \
71+
echo "Adding node to cluster $E2E_PARENT_CLUSTER"
72+
couchbase_cli_check server-add -c $E2E_PARENT_CLUSTER -u Administrator -p password --server-add $my_ip \
7273
--server-add-username Administrator --server-add-password password --services data,index,query
7374
echo
7475
echo "Rebalancing cluster"
75-
couchbase_cli_check rebalance -c $1 -u Administrator -p password
76+
couchbase_cli_check rebalance -c $E2E_PARENT_CLUSTER -u Administrator -p password
7677
echo
7778
else
7879
echo "Set up the cluster"
Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,14 @@
11
#!/bin/bash
22

3-
# Check if the script is run as root
4-
if [ "$EUID" -ne 0 ]; then
5-
echo "Please run as root"
6-
exit 1
7-
fi
8-
9-
echo "Disabling Transparent Huge Pages (THP)..."
10-
11-
cp /tmp/disable-thp.service /etc/systemd/system/disable-thp.service
12-
systemctl daemon-reload
13-
systemctl start disable-thp
14-
systemctl enable disable-thp
15-
16-
tmp=$(cat /sys/kernel/mm/transparent_hugepage/enabled)
17-
if [[ $tmp != *"[never]"* ]]; then
18-
echo "Failed to disable Transparent Huge Pages!"
19-
exit 1
20-
fi
21-
22-
tmp=$(cat /sys/kernel/mm/transparent_hugepage/defrag)
23-
if [[ $tmp != *"[never]"* ]]; then
24-
echo "Failed to disable THP defrag"
25-
exit 1
26-
fi
27-
28-
echo "Setting swappiness to 1..."
3+
set -x
294

30-
echo 1 > /proc/sys/vm/swappiness
31-
tmp=$(cat /proc/sys/vm/swappiness)
32-
if [[ $tmp != "1" ]]; then
33-
echo "Failed to set swappiness to 1"
34-
exit 1
5+
if ! command -v docker &> /dev/null; then
6+
echo "Docker not found, installing and starting..."
7+
sudo yum install -y docker
8+
sudo systemctl start docker
359
fi
3610

37-
rm -f /home/ec2-user/container-configured
11+
if ! groups $USER | grep -q "\bdocker\b"; then
12+
echo "Adding $USER to docker group"
13+
sudo usermod -aG docker $USER
14+
fi

environment/aws/server_setup/setup_server.py

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
import click
2222
import paramiko
2323

24-
from environment.aws.common.io import LIGHT_GRAY, sftp_progress_bar
24+
from environment.aws.common.docker import start_container
25+
from environment.aws.common.io import LIGHT_GRAY, get_ec2_hostname, sftp_progress_bar
2526
from environment.aws.common.output import header
2627
from environment.aws.topology_setup.setup_topology import TopologyConfig
2728

@@ -63,6 +64,7 @@ def setup_node(
6364
hostname: str,
6465
pkey: paramiko.Ed25519Key | None,
6566
version: str,
67+
tag: str,
6668
cluster: str | None = None,
6769
) -> None:
6870
"""
@@ -74,11 +76,6 @@ def setup_node(
7476
version (str): The version of Couchbase Server to install.
7577
cluster (Optional[str]): The cluster to join, if any.
7678
"""
77-
couchbase_filename = f"couchbase-server-enterprise-{version}-linux.x86_64.rpm"
78-
couchbase_url = (
79-
f"http://packages.couchbase.com/releases/{version}/{couchbase_filename}"
80-
)
81-
8279
header(f"Setting up server {hostname} with version {version}")
8380
ssh = paramiko.SSHClient()
8481
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
@@ -90,45 +87,42 @@ def setup_node(
9087
sftp_progress_bar(
9188
sftp, SCRIPT_DIR / "configure-system.sh", "/tmp/configure-system.sh"
9289
)
93-
sftp_progress_bar(
94-
sftp, SCRIPT_DIR / "disable-thp.service", "/tmp/disable-thp.service"
95-
)
9690
sftp.close()
9791

9892
global current_ssh
9993
current_ssh = hostname
10094

101-
remote_exec(ssh, "sudo bash /tmp/configure-system.sh", "Setting up machine")
10295
remote_exec(
10396
ssh,
104-
f"wget -nc -O /tmp/{couchbase_filename} {couchbase_url} 2>&1",
105-
f"Downloading Couchbase Server {version}",
106-
fail_on_error=False,
107-
)
108-
remote_exec(
109-
ssh,
110-
"sudo rpm -e couchbase-server",
111-
"Uninstalling Couchbase Server",
112-
fail_on_error=False,
113-
)
114-
remote_exec(
115-
ssh,
116-
f"sudo rpm -i /tmp/{couchbase_filename}",
117-
f"Installing Couchbase Server {version}",
118-
)
119-
remote_exec(
120-
ssh, "sudo systemctl start couchbase-server", "Starting Couchbase Server"
97+
"chmod +x /tmp/configure-node.sh && bash /tmp/configure-system.sh",
98+
"Setting up machine",
12199
)
100+
ssh.close()
122101

123-
# Some magic here that might be overlooked. If we pass in a cluster
124-
# address to the configure node script, it will join an existing cluster
125-
# rather than using itself to create a new one
126-
config_command = "bash /tmp/configure-node.sh"
127-
if cluster is not None:
128-
config_command += f" {cluster}"
129-
remote_exec(ssh, config_command, "Setting up node")
102+
ec2_hostname = get_ec2_hostname(hostname)
103+
docker_args = [
104+
"--network",
105+
"host",
106+
"-v",
107+
"/tmp/configure-node.sh:/etc/service/couchbase-config/run",
108+
]
130109

131-
ssh.close()
110+
if cluster is not None:
111+
docker_args.extend(
112+
[
113+
"-e",
114+
f"E2E_PARENT_CLUSTER={cluster}",
115+
]
116+
)
117+
context_name = "cbs" if tag == "" else f"cbs-{tag}"
118+
start_container(
119+
"cbs-e2e",
120+
context_name,
121+
f"couchbase/server:enterprise-{version}",
122+
ec2_hostname,
123+
docker_args,
124+
replace_existing=True,
125+
)
132126

133127

134128
def setup_topology(pkey: paramiko.Ed25519Key | None, topology: TopologyConfig) -> None:
@@ -144,10 +138,19 @@ def setup_topology(pkey: paramiko.Ed25519Key | None, topology: TopologyConfig) -
144138
return
145139

146140
for cluster_config in topology.clusters:
147-
setup_node(cluster_config.public_hostnames[0], pkey, cluster_config.version)
141+
setup_node(
142+
cluster_config.public_hostnames[0],
143+
pkey,
144+
cluster_config.version,
145+
topology.tag,
146+
)
148147
for server in cluster_config.public_hostnames[1:]:
149148
setup_node(
150-
server, pkey, cluster_config.version, cluster_config.public_hostnames[0]
149+
server,
150+
pkey,
151+
cluster_config.version,
152+
topology.tag,
153+
cluster_config.internal_hostnames[0],
151154
)
152155

153156

0 commit comments

Comments
 (0)