Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
77a0036
feature: prepare pxc-mysql job to configure replicas
nouseforaname Apr 24, 2026
d4c3577
wip: add job to handle replication
nouseforaname Apr 24, 2026
5df5c33
chore: add dev helpers, remove before pr
nouseforaname Apr 24, 2026
f8dfd0a
feature: add failsafes
nouseforaname Apr 28, 2026
a83d48a
fix: remove extra rendered line, breaks units
nouseforaname May 4, 2026
227873b
feature: enable manual config & compatibility with old pxc-release
nouseforaname May 6, 2026
9a03023
chore: update ops files for testing replicas
nouseforaname May 6, 2026
57f4179
review: remove server_id handling
nouseforaname May 6, 2026
85edbc4
review: use tls for encrypting connections
nouseforaname May 6, 2026
c7e6807
review: duplicate ops file
nouseforaname May 6, 2026
b35b8bf
fix: forgot to commit cert templates
nouseforaname May 7, 2026
a02db63
chore: remove unnecessary 2nd call
nouseforaname May 7, 2026
18edd0e
review: bad copy pasting.
nouseforaname May 7, 2026
01ef8f5
review: remove dupe
nouseforaname May 7, 2026
6f04ee5
review: wrong war name used.
nouseforaname May 7, 2026
1aa3c6a
review: clean out unused mount / write access
nouseforaname May 7, 2026
40bcb0c
review: use already existing ops file
nouseforaname May 7, 2026
02c0ae7
review: mark all mounts as writeable false
nouseforaname May 7, 2026
edfd160
review: query for replica status instead of log check
nouseforaname May 11, 2026
f8ab819
improvement: ensure permissions for manual user on restart
nouseforaname May 11, 2026
1b3781e
chore: rework post-start
nouseforaname May 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions jobs/pxc-mysql/spec
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ consumes:
optional: true

provides:
- name: source
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we reuse the mysql link and just expose more properties on it? It already has port and mysql_version

If we are pulling all this from the "primary" deployments link anyway, I was imagining something like:

# primary deployment manifest
- instance_groups:
   - name: mysql
      jobs:
      - name: pxc-mysql
         ...
         provides: mysql: {as: mysql, shared: true}


# replica deployment manifest
- instance_groups:
   - name: mysql
      jobs:
      - name: pxc-replicator
         ...
         consumes: source: {from: mysql, deployment: ((primary_deployment_name)) }

Plus or minus some bosh syntax cleanup here.

Maybe a second link isn't so bad, but it adds some more maintenance overhead where if we expose another mysql job property we have to maintain it in two places going forward.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My reasoning was mostly about being specific what the link type is used for and not wanting to introduce additional properties to existing consumers to avoid confusion. I have no strong feelings about either direction.

type: source
properties:
- port
- mysql_version
- mysql_backup_username
- mysql_backup_password
- tls

- name: mysql
type: mysql
properties:
Expand All @@ -67,15 +76,13 @@ provides:
- mysql_socket

properties:

pxc_enabled:
description: 'Used for disabling the job. Useful if co-locating the cf-mysql release mysql job and migrating'
default: true
disable_persistent_storage_safety_check:
description: 'pre-start checks that /var/vcap/store is a persistent volume to prevent accidentally running the database on an ephemeral disk. This can be used to disable this check for test or bosh-lite situations'
default: false


# Admin Users
admin_username:
description: 'Username for the MySQL server admin user'
Expand Down Expand Up @@ -309,6 +316,12 @@ properties:
engine_config.read_write_permissions:
description: "Specify the database server's read/write setting. For single-node deployments, valid options are `read_write`, `read_only`, or `super_read_only`. The setting must be `read_write` for Galera clusters."
default: read_write
engine_config.enable_replication_target:
description: 'When configuring a replica, this will use spec.index to populate server_id on each node starting at the highest possible index. Any value set for server_id will be discarded by enabling this setting'
default: false
engine_config.enable_replication_source:
description: 'When configuring a replica, this will use spec.index to populate server_id on each node starting at the lowest possible index. Any value set for server_id will be discarded by enabling this setting'
default: false
Comment on lines +319 to +324
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these are used anymore and should be cleaned up.

engine_config.server_id:
description: 'In leader-follower topology, this value must be unique. In other words, the leader must have a different value than the follower and vice versa. If this is set to 0, then the server refuses any replication connections.'
default: 0
Expand Down Expand Up @@ -388,4 +401,4 @@ properties:
kernel.vm.swappiness:
description: "Configure Linux vm.swappiness"
# https://docs.kernel.org/admin-guide/sysctl/vm.html#swappiness
# https://www.percona.com/blog/mysql-101-linux-tuning-for-mysql/
# https://www.percona.com/blog/mysql-101-linux-tuning-for-mysql/
20 changes: 13 additions & 7 deletions jobs/pxc-mysql/templates/db_init.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@ DROP USER IF EXISTS '<%= p('admin_username') %>'@'<%= host %>';
<%- end -%>
DROP USER IF EXISTS 'roadmin'@'<%= host %>';

<%- end -%>
<%- if_p('mysql_backup_password') do |password| -%>
CREATE USER IF NOT EXISTS '<%= p('mysql_backup_username') %>'@'localhost';
ALTER USER '<%= p('mysql_backup_username') %>'@'localhost' IDENTIFIED WITH <%= p('engine_config.user_authentication_policy') %> BY '<%= password %>';
GRANT RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT, /*!80001 BACKUP_ADMIN,*/ PROCESS ON *.* to '<%= p('mysql_backup_username') %>'@'localhost';
GRANT SELECT on performance_schema.keyring_component_status to '<%= p('mysql_backup_username') %>'@'localhost';
GRANT SELECT ON performance_schema.log_status TO '<%= p('mysql_backup_username') %>'@'localhost';
<%- end
allowed_remote_backup_hosts='localhost'

if p('engine_config.enable_replication_source')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it makes sense to just allow allowed_remote_backup_hosts to be configurable in some way. This seems similar to remote_admin_access and doesn't necessarily need to be tied to replication.

allowed_remote_backup_hosts='%'
end

if_p('mysql_backup_password') do |password| -%>
CREATE USER IF NOT EXISTS '<%= p('mysql_backup_username') %>'@'<%= allowed_remote_backup_hosts %>';
ALTER USER '<%= p('mysql_backup_username') %>'@'<%= allowed_remote_backup_hosts %>' IDENTIFIED WITH <%= p('engine_config.user_authentication_policy') %> BY '<%= password %>';
GRANT RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT, /*!80001 BACKUP_ADMIN,*/ PROCESS ON *.* to '<%= p('mysql_backup_username') %>'@'<%= allowed_remote_backup_hosts %>';
GRANT SELECT on performance_schema.keyring_component_status to '<%= p('mysql_backup_username') %>'@'<%= allowed_remote_backup_hosts %>';
GRANT SELECT ON performance_schema.log_status TO '<%= p('mysql_backup_username') %>'@'<%= allowed_remote_backup_hosts %>';

<%- end -%>
<%- hosts.each do |host| -%>
Expand Down
7 changes: 7 additions & 0 deletions jobs/pxc-replicator/monit
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<% if p('replicator_enabled') == true %>
check process pxc-replicator
with pidfile /var/vcap/sys/run/bpm/pxc-replicator/pxc-replicator.pid
start program "/var/vcap/jobs/bpm/bin/bpm start pxc-replicator" with timeout <%= p('monit_startup_timeout') %> seconds
stop program "/var/vcap/jobs/bpm/bin/bpm stop pxc-replicator"
group vcap
<% end %>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be a long-lived process? Could setup be a "one shot" task?

Maybe okay to keep it in bpm, but maybe use bpm run pxc-replicator in post-start rather than having a monit job and this becomes empty.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it's useful to have it running to be aware when it stops working.

a one shot would probably do the job just as well, until the remote changes in a way that replication breaks. At this point the replica instance would not indicate at all that the replication broke.

Currently, if the source instance would be restored to another state, the job would notice and restart the replication by getting a fresh dump of the changed upstream.

72 changes: 72 additions & 0 deletions jobs/pxc-replicator/spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
name: pxc-replicator

templates:
bpm.yml.erb: config/bpm.yml
bin/setup: bin/setup
bin/post-start: bin/post-start
source.mysql.cnf.erb: config/source.mysql.cnf
source.admin.mysql.cnf.erb: config/source.admin.mysql.cnf
config/client-cert.pem.erb: certificates/client-cert.pem
config/client-key.pem.erb: certificates/client-key.pem
config/server-ca.pem.erb: certificates/server-ca.pem

packages:
- percona-xtradb-cluster-8.0
- percona-xtradb-cluster-8.4
- percona-xtrabackup-2.4
- percona-xtrabackup-8.0
- percona-xtrabackup-8.4
- pxc-utils

consumes:
- name: source
type: source
optional: true
properties:
- port
- mysql_version
- mysql_backup_username
- mysql_backup_password
- tls

properties:
source_admin_username:
description: |
this is here for compatibility with older deployments of the pxc-release.
technically, the `roadmin` user is viable as a replication user, but it misses `REPLICATION SLAVE` privilege.
providing the source_admin_username & password will ensure that the roadmin will updated with the missing permission

source_admin_password:
description: |
this is here for compatibility with older deployments of the pxc-release.
technically, the `roadmin` user is viable as a replication user, but it misses `REPLICATION SLAVE` privilege.
providing the source_admin_username & password will ensure that the roadmin will updated with the missing permission
monit_startup_timeout:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With bpm this is probably not super useful - the pid gets dropped as soon as the job starts and monit will treat the job as healthy.

But this made me wonder if we even really need monit for this use case. See my comments on the monit template.

description: 'How long to wait for monit to show running for the process, will also be used as a timeout for the post-start health check'
default: 180
mysql_version:
description: 'deployed version'
default: 8.0
logging.format.timestamp:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't look like this is used anywhere.

default: rfc3339
replicator_enabled:
description: 'Whether to enable the job ( skips writing monit file if set to false )'
default: false
mysql_backup_username:
description: 'user to use for connection to source instance'
mysql_backup_password:
description: 'password to use for connection to source instance'
host:
description: 'hostname of the source database instance'
port:
description: 'Whether to enable the job ( skips writing monit file if set to false )'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Bad description

default: 3306
Comment on lines +60 to +64
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not to make this complicated, but may make sense to add source prefix here. either nested with source.{admin_username,admin_password,host,port} or just use the source_{host,port} naming convention to make it clear when referencing this property what its purpose is.

tls:
description: 'TLS certificates to use for connections'
example: {
"ca": "...",
"certificate": "...",
"private_key": "..."
}
default: {}
31 changes: 31 additions & 0 deletions jobs/pxc-replicator/templates/bin/post-start
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
<% if p('replicator_enabled') then %>
. /var/vcap/packages/pxc-utils/logging.sh

#it's a bash feature.
#https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html#index-SECONDS
SECONDS=0
PATH="${PATH}:/var/vcap/packages/percona-xtradb-cluster-<%= p('mysql_version') -%>/bin"

log "starting post-start, checking replication"
while [[ $SECONDS -lt 300 ]]; do
if mysql --defaults-file=/var/vcap/jobs/pxc-mysql/config/mylogin.cnf <<< "SHOW REPLICA STATUS\G" | grep 'Replica_IO_Running: Yes'; then
log "IO thread is running"
else
log "IO thread is running"
continue
fi

if mysql --defaults-file=/var/vcap/jobs/pxc-mysql/config/mylogin.cnf <<< "SHOW REPLICA STATUS\G" | grep 'Replica_SQL_Running: Yes'; then
log "SQL thread is running"
exit 0
else
log "SQL thread not running" && continue
continue
fi
sleep 5
done

log "timed out waiting for replication to report healthy"
exit -1
<% end %>
108 changes: 108 additions & 0 deletions jobs/pxc-replicator/templates/bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/usr/bin/env bash
set -eo pipefail

. /var/vcap/packages/pxc-utils/logging.sh


<%- if_p('tls.client.ca','tls.client.certificate','tls.client.private_key') do -%>
SOURCE_SSL_CONFIG="SOURCE_SSL_CA = '/var/vcap/jobs/pxc-replicator/certificates/server-ca.pem', SOURCE_SSL_CERT = '/var/vcap/jobs/pxc-replicator/certificates/client-cert.pem', SOURCE_SSL_KEY = '/var/vcap/jobs/pxc-replicator/certificates/client-key.pem'"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't think deeply about this during my initial review pass so up-front apologies for not surfacing this earlier.

These certificates are going to be read by the mysqld process running in the pxc-mysql bpm context. That job currently would not have access to the pxc-replicator job certificates without adjusting the bpm.yml.

Rather than doing this, I think maybe just configure certificates on the pxc-mysql job. This should be the point of the pxc-mysql tls.client.{certificate,key} properties. If configured then you can just set SOURCE_SSL_{CERT,KEY} = /var/vcap/jobs/pxc-mysql/certificates/client-{cert,key}.pem

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SOURCE_SSL_{CERT,KEY} is only needed if you want x509 authentication (mTLS).

Not necessarily bad a security perspective but the replication user would need to be specifically configured for it.

i.e.

CREATE USER $replicationUSER REQUIRE X509  .... ;
-- or
CREATE USER $replicationUSER REQUIRE SUBJECT '/CN=some-client-identity' ...;

See: MySQL CREATE USER docs

As I mentioned in an earlier comment, mutual TLS is not a requirement for an MVP but maybe a nice-to-have. If you need it, it would add it as an option to user creation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth noting that best practice would also set SOURCE_SSL_VERIFY_SERVER_CERT (hostname verification).

This would require the primary's TLS certificate to contain the bosh dns server name (provided by the link here) Bosh docs.

In the context of cf-d this is usually sql-db.service.cf.internal but would require explicit configuration.

<%- end.else do if_link('source') do |link| -%>
<%- if link.p('tls') != nil && link.p('tls')['client'] != nil then -%>
SOURCE_SSL_CONFIG="SOURCE_SSL_CA = '/var/vcap/jobs/pxc-replicator/certificates/server-ca.pem', SOURCE_SSL_CERT = '/var/vcap/jobs/pxc-replicator/certificates/client-cert.pem', SOURCE_SSL_KEY = '/var/vcap/jobs/pxc-replicator/certificates/client-key.pem'"
<%- else -%>
SOURCE_SSL_CONFIG=""
<%- end -%>
<%- end end -%>
function is_replication_configured(){
! test "$($self_mysql <<< "SHOW REPLICA STATUS\G")" = ""
}
function is_replica_io_running (){
$self_mysql <<< "SHOW REPLICA STATUS\G" | grep 'Replica_IO_Running: Yes'
}
function is_replica_sql_running (){
$self_mysql <<< "SHOW REPLICA STATUS\G" | grep 'Replica_SQL_Running: Yes'
}
function enable_replication (){
$self_mysql <<< "STOP REPLICA;
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='${SOURCE_ADDR}',
SOURCE_USER='${SOURCE_USER}',
SOURCE_PASSWORD='${SOURCE_PASS}',
SOURCE_AUTO_POSITION=1,
${SOURCE_SSL_CONFIG};
START REPLICA;"
}
function ensure_backup_user_has_replication_slave(){
if [[ ! -z "${source_admin_mysql}" ]]; then
log "found source_admin_creds, ensuring source_replica user permissions"
${source_admin_mysql} <<< "GRANT REPLICATION SLAVE ON *.* TO '${SOURCE_USER}'@'%';"
fi
}
function sync_databases(){
log "resyncing with full backup"
ensure_backup_user_has_replication_slave
log $($self_mysql <<< "STOP REPLICA;")
log $($self_mysql <<< "RESET REPLICA;")
log $($self_mysql <<< "RESET MASTER;")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note: RESET MASTER is deprecated in v8.4 and removed in MySQL v9, replaced with RESET BINARY LOGS AND GTIDS.

I understand this is likely used here since pxc-release still supports MySQL v8.0 which still requires this syntax.

Copy link
Copy Markdown
Author

@nouseforaname nouseforaname May 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, what's the preferred way of handling this?

I noticed while reading docs that they're still cleaning up the weirdo naming..
I tried already using the replica/source naming as far as possible but didn't know if it would be idempotent :/

https://dev.mysql.com/doc/refman/8.4/en/replication-howto-repuser.html

it seems that the permissions still does not have an alternative?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, v8.0 (and earlier) only support RESET MASTER and v8.4 only supports RESET BINARY LOGS ...

We've typically dealt with this kind of thing with version checks:

if mysql_major_minor() == "8.0":  # <- Delete branch when we don't care about old version anymore
   do_legacy_sql_stuff() 
else:
   do_latest_sql_stuff()
end

That could potentially be done at template rendering time by looking at the p('mysql_version') property.

MySQL v8.0 is EOL (although we'll probably get one more patch release from Percona for v8.0.46), so there is an argument to only support v8.4 and onwards. Maybe guard against using this feature on v8.0?

# In some pxc-replicator template
<%- if p('mysql_version') == "8.0" -%>
raise "Unsupported <helpful error message>"
<%- end -%>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm. How'd that play with cf-depl?

It seems that 8.4 is still experimental cloudfoundry/cf-deployment@3870c60

I'm not sure if there are any reasons why it's still setup to default to 8.0 outside of being cautious.

I'm going to ask around what the plans for runtime are in regards to switching the default. For now I guess I'll try to find all relevant places and sprinkle some ifs

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking here was that it could be reasonable to not support this replication feature for EOL MySQL versions to simplify things.

However this exposes that, as pxc-release maintainers, we have been bad netizens of cf-d and have not updated the default MySQL version to v8.4. I'll try to follow-up on that.

I think it's okay to add a version check to support both the old and new syntax for now.

log $($source_dump --all-databases --triggers --routines --single-transaction | $self_mysql)
Comment thread
abg marked this conversation as resolved.
}
function source_upcheck(){
$source_mysql <<< "exit"
}
function self_upcheck(){
$self_mysql <<< "exit"
}

while ! source_upcheck; do
log "waiting for source to be available"
sleep 5
done

while ! self_upcheck; do
log "waiting for self to be available"
sleep 5
done

log "starting replication setup"

log "checking existing databases in source instance"

log "checking replication status"

if ! is_replication_configured; then
log "replication is not yet enabled"
sync_databases

log "replication is not configured. enabling"
OUT=$(enable_replication);
if [[ "${OUT}" != "" ]]; then
log "failed enabling replication: '$OUT'" | sed "s/${SOURCE_PASS}/<REDACTED>/g"
else
log "replication enabled"
fi
else
log "replicaton already enabled, skipping"
fi

while true; do
log "checking running status"
RUNNING_STATUS="$($self_mysql <<< "SHOW REPLICA STATUS\G" | grep 'Replica_.*_Running: ' | xargs )"
if is_replica_io_running && is_replica_sql_running; then
log "replication healthy"
elif ! is_replica_io_running; then
log "restarting replica"
ensure_backup_user_has_replication_slave
$self_mysql <<< "START REPLICA;"
sleep 30
elif ! is_replica_sql_running ; then
log "replication Replica_SQL_Running marked as no. Attempting to resync"
sync_databases
else
log "$RUNNING_STATUS"
for line in $($self_mysql <<< "SHOW REPLICA STATUS\G" | grep 'Err' | tr -d '[:blank:]' ); do
log "${line/$SOURCE_PASS/<redacted>/}";
done
fi
log "$RUNNING_STATUS"
sleep 5
done
53 changes: 53 additions & 0 deletions jobs/pxc-replicator/templates/bpm.yml.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<%-
if !['rfc3339', 'unix-epoch'].include?(p('logging.format.timestamp'))
raise "'#{p('logging.format.timestamp')}' is not a valid timestamp format for the property 'logging.format.timestamp'." +
" Valid options are: 'rfc3339' and 'unix-epoch'."
end
path = [
"/usr/bin",
"/bin",
"/var/vcap/packages/percona-xtradb-cluster-#{p('mysql_version')}/bin",
]
flags = ""
if_p('tls.client.ca','tls.client.certificate','tls.client.private_key') do
flags = "--ssl-ca=/var/vcap/jobs/pxc-replicator/certificates/server-ca.pem --ssl-cert=/var/vcap/jobs/pxc-replicator/certificates/client-cert.pem --ssl-key=/var/vcap/jobs/pxc-replicator/certificates/client-key.pem"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to set these flags via the my.cnf? (i.e. source{,.admin}.mysql.cnf)

end
if_link('source') do |link|
if link.p('tls') != nil && link.p('tls')['client'] != nil then
flags = "--ssl-ca=/var/vcap/jobs/pxc-replicator/certificates/server-ca.pem --ssl-cert=/var/vcap/jobs/pxc-replicator/certificates/client-cert.pem --ssl-key=/var/vcap/jobs/pxc-replicator/certificates/client-key.pem"
end
end
-%>
---
<% if p('replicator_enabled') %>
processes:
- name: pxc-replicator
executable: /var/vcap/jobs/pxc-replicator/bin/setup
args: []
env:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would probably be clearer to just set these env vars in the setup template itself rather than here.

I am bouncing around between bpm and setup to figure out the magic variables set in the bpm to understand what's being done in setup. Some of it feels a little magical.

PATH: <%= path.join(":") %>
<%- if_p('mysql_backup_username', 'mysql_backup_password' ,'host', 'port') do |user,pass,host| -%>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we would apply the principal of least privilege here. Otherwise this will get flagged by security scans.

Replication doesn't need full SELECT access on tables from the primary - it just needs the privilege to stream binary logs.

Similarly the backup user just needs minimal privileges for a backup, but not necessarily binlog streaming privileges.

SOURCE_USER: <%= user %>
SOURCE_PASS: <%= pass %>
SOURCE_ADDR: <%= host %>
<%- end.else do if_link("source") do |link| -%>
SOURCE_USER: <%= link.p('mysql_backup_username') %>
SOURCE_PASS: <%= link.p('mysql_backup_password') %>
SOURCE_ADDR: <%= link.address %>
<%- end end -%>
self_mysql: 'mysql --defaults-file=/var/vcap/jobs/pxc-mysql/config/mylogin.cnf'
source_dump: 'mysqldump --defaults-file=/var/vcap/jobs/pxc-replicator/config/source.mysql.cnf <%= flags -%>'
source_mysql: 'mysql --defaults-file=/var/vcap/jobs/pxc-replicator/config/source.mysql.cnf <%= flags -%>'
<%- if_p('source_admin_username','source_admin_password','host') do -%>
source_admin_mysql: 'mysql --defaults-file=/var/vcap/jobs/pxc-replicator/config/source.admin.mysql.cnf <%= flags -%>'
<%- end -%>
persistent_disk: true
ephemeral_disk: true
Comment on lines +44 to +45
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these used anywhere? I did not see a /var/vcap/{store,data}/pxc-replicator referenced.

additional_volumes:
- path: /var/vcap/sys/run/pxc-mysql
Comment thread
abg marked this conversation as resolved.
writeable: false
- path: /var/vcap/jobs/pxc-mysql/config
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is needed, I would mark this writable: false since write access is unnecessary.

I think better would be to use a "replication admin" role. Maybe worth adding a seeded_users role for this.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my current thinking is to just generate a bosh user for the initial root account of the replica target and set that via the set-repilcator-target ops file.. Mostly because I noticed that if I don't change the initial root user name between cf-d and my replica deployments, they both used defaults for naming the root user. So after initial sync, the targets root account used the pw from cf-d..

writeable: false
- path: /var/vcap/jobs/pxc-replicator/certificates
writeable: false
<% end %>
5 changes: 5 additions & 0 deletions jobs/pxc-replicator/templates/config/client-cert.pem.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%- if_p('tls.client') do |client_tls| -%>
<%= client_tls['certificate'] %>
<%- end.else_if_p do if_link('source') do |link| -%>
<%= link.tls.client.certificate -%>
<%- end end -%>
5 changes: 5 additions & 0 deletions jobs/pxc-replicator/templates/config/client-key.pem.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%- if_p('tls.client') do |client_tls| -%>
<%= client_tls['private_key'] %>
<%- end.else_if_p do if_link('source') do |link| -%>
<%= link.tls.client.private_key -%>
<%- end end -%>
5 changes: 5 additions & 0 deletions jobs/pxc-replicator/templates/config/server-ca.pem.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%- if_p('tls.client') do |client_tls| -%>
<%= client_tls['ca'] %>
<%- end.else_if_p do if_link('source') do |link| -%>
<%= link.tls.client.ca -%>
<%- end end -%>
7 changes: 7 additions & 0 deletions jobs/pxc-replicator/templates/source.admin.mysql.cnf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<% if_p('source_admin_username','source_admin_password','host','port') do |user,pass,host,port| %>
[client]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these actually optional? If this job is deployed, it just fails if these aren't set right?

Maybe be worth just failing on the property lookup rather than having a guard here

i.e.

[client]
user = <% p('source_admin_username') %>
password = <%= p('source_admin_password') %>
...

Note you can also put the ssl-* options here as well for secure remote connections to the source (rather than passing on the commandline)

user = <%= user %>
password = <%= pass %>
host = <%= host %>
port = <%= port %>
<% end %>
13 changes: 13 additions & 0 deletions jobs/pxc-replicator/templates/source.mysql.cnf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<% if_p('mysql_backup_username', 'mysql_backup_password' ,'host', 'port') do |user,pass,host,port| %>
[client]
user = <%= user %>
password = <%= pass %>
host = <%= host %>
port = <%= port %>
<% end.else_if_p do if_link("source") do |link| %>
[client]
user = <%= link.p('mysql_backup_username') %>
password = <%= link.p('mysql_backup_password') %>
host = <%= link.address %>
port = <%= link.p('port') %>
<% end end %>
Comment thread
abg marked this conversation as resolved.
Loading
Loading