blob: 50fc8761eb5446238518d87bfc543a51e23ccbfc [file] [log] [blame]
/**
*
* Add Ceph node to existing cluster
*
* Requred parameters:
* SALT_MASTER_URL URL of Salt master
* SALT_MASTER_CREDENTIALS Credentials to the Salt API
* HOST Host (minion id) to be added
* CLUSTER_FLAGS Expected flags on the cluster during job run
* OSD_ONLY Add only new osds while keep rest intact
* USE_UPMAP Use upmap for rebalance the data after node was added
*
*/
def common = new com.mirantis.mk.Common()
def salt = new com.mirantis.mk.Salt()
def ceph = new com.mirantis.mk.Ceph()
def orchestrate = new com.mirantis.mk.Orchestrate()
def python = new com.mirantis.mk.Python()
def pepperEnv = "pepperEnv"
def flags = CLUSTER_FLAGS.tokenize(',').toSet()
def osdOnly = OSD_ONLY.toBoolean()
def useUpmap = USE_UPMAP.toBoolean()
timeout(time: 12, unit: 'HOURS') {
node("python") {
// create connection to salt master
python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
def target = salt.getMinions(pepperEnv, HOST)
if(target.isEmpty()) {
common.errorMsg("Host not found")
throw new InterruptedException()
}
else if(target.size() > 1) {
common.warningMsg("$HOST targeted more than one minion")
}
if(useUpmap) {
stage('enable upmap balancer') {
def features = ceph.cmdRun(pepperEnv, "ceph features --format json", false)
features = common.parseJSON(features)
for(group in features['client']) {
if(group instanceof java.util.HashMap$Node) { // Luminous
if(group.getValue()['release'] != 'luminous') {
throw new Exception("Some of installed clients does not support upmap. Update all clients to luminous or newer before using upmap")
}
}
else if(group['release'] != 'luminous') { // Nautilus
throw new Exception("Some of installed clients does not support upmap. Update all clients to luminous or newer before using upmap")
}
}
ceph.cmdRun(pepperEnv, 'ceph osd set-require-min-compat-client luminous')
ceph.cmdRun(pepperEnv, 'ceph balancer on')
ceph.cmdRun(pepperEnv, 'ceph balancer mode upmap')
}
}
salt.fullRefresh(pepperEnv, HOST)
stage("set flags") {
if(useUpmap) {
flags.add('norebalance')
}
ceph.setFlags(pepperEnv, flags)
}
try {
stage('Launch VMs') {
if(salt.testTarget(pepperEnv, "$HOST and not I@ceph:osd")) {
// launch VMs
salt.enforceState([saltId: pepperEnv, target: "I@salt:control", state: 'salt.control'])
// wait till the HOST appears in salt-key on salt-master
salt.minionPresent(pepperEnv, 'I@salt:master', HOST)
}
else {
common.infoMsg("No VM require for a osd node.")
}
}
stage('Install infra') {
if(!osdOnly) {
// run basic states
orchestrate.installFoundationInfraOnTarget(pepperEnv, HOST)
}
else {
common.infoMsg('Stage skipped due to OSD_ONLY.')
}
}
stage('Install ceph components') {
if(salt.testTarget(pepperEnv, "$HOST and I@ceph:mon")) {
ceph.installMon(pepperEnv, HOST)
}
if(salt.testTarget(pepperEnv, "$HOST and I@ceph:radosgw")) {
ceph.installRgw(pepperEnv, HOST)
}
if(salt.testTarget(pepperEnv, "$HOST and I@ceph:osd")) {
ceph.installOsd(pepperEnv, HOST, !osdOnly) //skip setup while osdOnly
}
else if(osdOnly) {
common.infoMsg('Stage skipped due to OSD_ONLY.')
}
}
stage("Update/Install monitoring and hosts files") {
if(!osdOnly) {
ceph.updateMonitoring(pepperEnv, HOST)
salt.enforceState([saltId: pepperEnv, target: "I@ceph:common", state: 'linux.network.host'])
}
else {
common.infoMsg('Stage skipped due to OSD_ONLY.')
}
}
if(useUpmap) {
stage("update mappings") {
def pgmap
for (int x = 1; x <= 3; x++) {
pgmap = ceph.cmdRun(pepperEnv, 'ceph pg ls remapped --format=json', false)
if (pgmap.trim()) {
pgmap = "{\"pgs\":$pgmap}" // common.parseJSON() can't parse a list of maps
pgmap = common.parseJSON(pgmap)['pgs']
if (pgmap instanceof java.util.Map && pgmap.get('pg_ready', false)) {
continue
}
def mapping = []
ceph.generateMapping(pgmap, mapping)
for(map in mapping) {
ceph.cmdRun(pepperEnv, map)
}
sleep(30)
}
}
}
stage('Unset norebalance') {
ceph.unsetFlags(pepperEnv, 'norebalance')
flags.removeElement('norebalance')
}
}
stage('Wait for healthy cluster status') {
ceph.waitForHealthy(pepperEnv, flags)
}
}
finally {
stage('Unset cluster flags') {
ceph.unsetFlags(pepperEnv, flags)
}
}
}
}