Skip to content

Commit

Permalink
ci: scripts to redeploy in developments
Browse files Browse the repository at this point in the history
  • Loading branch information
Hadrien Froger committed Feb 7, 2024
1 parent 1399db3 commit eb588d7
Show file tree
Hide file tree
Showing 2 changed files with 337 additions and 0 deletions.
310 changes: 310 additions & 0 deletions .github/workflows/backup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
jpsType: update
jpsVersion: '1.7.4'

name: Scripts/DailyTask
id: daily-task
description:
short: Sysadmin Actions for jelastic account
categories:
- apps/platforms
ssl: true
ha: false
settings:
fields:
- name: RESTIC_REPOSITORY
type: string
caption: Host+bucket+region for the S3
- name: AWS_ACCESS_KEY_ID
type: string
caption: Key ID for S3
- name: AWS_SECRET_ACCESS_KEY
type: string
caption: Secret for S3
- name: RESTIC_PASSWORD
type: string
caption: Key used for restic encryption
- name: AWS_DEFAULT_REGION
type: string
caption: Default Region
default: 'ch-dk-2'
- name: TAG
type: string
caption: Tag the backup
default: 'daily'

onInstall:
- type: "javascript"
script:
- 'var resp = jelastic.environment.control.GetEnvs(appid, session);'
- 'if(resp.result != 0) return {"result": 1, "message": "ERROR"};'
- 'var nodes = (resp.infos || []).filter(function(env) {
return (env.env.status || 0) === 1;
}).reduce(function(acc, curr) {
acc[curr.env.envName] = {
raw: curr,
nodes: curr.nodes.filter(function(nd) {
if(nd.nodeGroup === "cp" && curr.nodes.find(function(nd2) { return nd2.nodeGroup === "storage"; })) {
return false;
}
return (typeof nd.customitem !== "undefined") &&
(typeof nd.customitem.dockerVolumes !== "undefined") &&
(nd.customitem.dockerVolumes.length > 0) &&
["cp", "bl", "sqldb", "storage"].includes(nd.nodeGroup);
}).map(function(nd) {
return {
nodeGroup: nd.nodeGroup,
volumes: nd.customitem.dockerVolumes,
id: nd.id,
ip: nd.intIP,
port: nd.port
};
})
};
return acc;
}, {})'
- 'var result = Object.keys(nodes).map(function(envName) {
var nd = nodes[envName];
nd.envName = envName;
return nd;
})'
- 'return {"result": 0,"environments": JSON.stringify(result)}'

- setGlobals:
- ENVIRONMENTS: ${response.environments}

- type: javascript
environments: ${globals.ENVIRONMENTS}
script:
- 'var installRestic = function(envName, nodeGroups){
var results = nodeGroups.map(function(nodeGroup) {
var resp = jelastic.environment.control.ExecCmdByGroup(
envName,
session,
nodeGroup,
JSON.stringify([
{
"command": "which restic >/dev/null || { which dnf >/dev/null && { dnf install -y epel-release; dnf install -y restic; } || { which apk >/dev/null && apk add restic; } || { which yum >/dev/null && { yum-config-manager --add-repo https://copr.fedorainfracloud.org/coprs/copart/restic/repo/epel-7/copart-restic-epel-7.repo; yum-config-manager --enable copr:copr.fedorainfracloud.org:copart:restic; yum -y install restic; yum-config-manager --disable copr:copr.fedorainfracloud.org:copart:restic; } ; } ; }"
}
])
);
return resp.result === 0;
});
return results.filter(Boolean).length === results.length;
}'
- 'var environments = JSON.parse(getParam("environments"))'
- 'var failedInstall = environments.filter(function(environment) {
var nodes = environment.nodes;
var nodeGroups = nodes.map(function(nd) { return nd.nodeGroup });
return !installRestic(environment.envName, nodeGroups)
})'
- 'var outputMessage = failedInstall.length > 0 ?
(
"Fail to install Restic. Check environments " + failedInstall.map(function(environment) {
return "`" + environment.envName + "`";
}).join(", ")
) : "OK"'
- 'return {result: 0, outputMessage: outputMessage }'
- setGlobals:
- OUTPUT_RESTIC_INSTALL: ${response.outputMessage}
- type: javascript
environments: ${globals.ENVIRONMENTS}
script:
- 'var backupContainer = function(envName, nodeGroup, directories, topology){
var tag = "${settings.TAG}";
var repo = "s3:${settings.RESTIC_REPOSITORY}/" + envName + "-" + nodeGroup;
var keyId = "${settings.AWS_ACCESS_KEY_ID}";
var keySecret = "${settings.AWS_SECRET_ACCESS_KEY}";
var resticPassword = "${settings.RESTIC_PASSWORD}";
var defaultRegion = "${settings.AWS_DEFAULT_REGION}";
if(topology) {
jelastic.environment.control.ExecCmdByGroup(
envName,
session,
nodeGroup,
JSON.stringify([
{
"command": "mkdir -p /tmp/topology",
"params": ""
}
])
);
directories.push("/tmp/topology");
jelastic.environment.file.write(
envName,
session,
"/tmp/topology/topology.json",
JSON.stringify(topology),
undefined,
nodeGroup
);
}
var resp = jelastic.environment.control.ExecCmdByGroup(
envName,
session,
nodeGroup,
JSON.stringify([
{
"command": "export RESTIC_REPOSITORY=\""+repo+"\"",
"params": ""
},
{
"command": "export AWS_ACCESS_KEY_ID=\""+keyId+"\"",
"params": ""
},
{
"command": "export AWS_SECRET_ACCESS_KEY=\""+keySecret+"\"",
"params": ""
},
{
"command": "export RESTIC_PASSWORD=\""+resticPassword+"\"",
"params": ""
},
{
"command": "export AWS_DEFAULT_REGION=\""+defaultRegion+"\"",
"params": ""
},
{
"command": "if ! restic snapshots >/dev/null 2>&1; then restic init; fi",
"params": ""
},
{
"command": "restic backup --tag "+ tag +" " + directories.filter(function(dir) {
return !dir.endsWith("vendor") && !dir.endsWith("node_modules");
}).join(" "),
"params": ""
}
])
);
return resp.result === 0;
}'
- 'var backupDatabase = function(envName){
var resp = jelastic.environment.control.ExecCmdByGroup(
envName,
session,
"sqldb",
JSON.stringify([
{
"command": "mkdir -p /root/dump",
"params": ""
},
{
"command": "cd /root/dump",
"params": ""
},
{
"command": "databases=$(psql --username $POSTGRES_USER postgres -qAt -c \"SELECT datname FROM pg_database WHERE NOT datistemplate\")",
"params": ""
},
{
"command": "for db in $databases; do pg_dump --username $POSTGRES_USER -Fp $db > /root/dump/$db.sql; done",
"params": ""
}
])
);
return resp.result == 0;
}'
- 'var environments = JSON.parse(getParam("environments"))'
- 'var backups = environments.map(function(environment) {
var nodes = environment.nodes;
var raw = environment.raw;
var envName = environment.envName;
var nodeGroups = nodes.map(function(nd) { return nd.nodeGroup });
var backupProcess = [];
var hasStorage = nodeGroups.includes("storage");
if(nodeGroups.includes("sqldb")) {
var matchNode = nodes.find(function(nd) { return nd.nodeGroup == "sqldb";});
backupProcess.push(backupContainer(envName, "sqldb", ["/root/dump"], undefined));
}
if(nodeGroups.includes("cp")) {
var matchNode = nodes.find(function(nd) { return nd.nodeGroup == "cp";});
backupProcess.push(backupContainer(envName, "cp", matchNode.volumes, hasStorage ? undefined : raw));
}
if(hasStorage) {
var matchNode = nodes.find(function(nd) { return nd.nodeGroup == "storage";});
backupProcess.push(backupContainer(envName, "storage", matchNode.volumes, raw));
}
if(nodeGroups.includes("bl")) {
var matchNode = nodes.find(function(nd) { return nd.nodeGroup == "bl";});
backupProcess.push(backupContainer(envName, "bl", matchNode.volumes, undefined));
}
return [
envName,
backupProcess.length > 0 && backupProcess.filter(Boolean).length === backupProcess.length
];
})'
- 'var outputMessage = backups.map(function(backupInfo) {
return " * " + backupInfo[0] + ": " + (backupInfo[1] ? "✅" : "⚠️")
}).join("\n")'
- 'return {"result": 0, outputMessage: outputMessage}'

- setGlobals:
- OUTPUT_BACKUP: ${response.outputMessage}

- type: javascript
environments: ${globals.ENVIRONMENTS}
script:
- 'var fetchBilling = function(targetAppId, envName) {
var yesterdayStart = new Date();
yesterdayStart.setDate(yesterdayStart.getDate() - 1);
yesterdayStart.setUTCHours(0,0,0,0);
yesterdayStart = yesterdayStart.toISOString();
var yesterdayEnd = new Date();
yesterdayEnd.setDate(yesterdayEnd.getDate() - 1);
yesterdayEnd.setUTCHours(23,59,59,999);
yesterdayEnd = yesterdayEnd.toISOString();
var billingHistory = jelastic.billing.account.GetExtendedAccountBillingHistoryByPeriod(
appid,
session,
yesterdayStart,
yesterdayEnd,
targetAppId
);
if(!billingHistory || billingHistory.result !== 0 || billingHistory.object.envs.length === 0) {
return null;
}
var envBillingHistory = billingHistory.object.envs[0][envName];
var cloudlets = (envBillingHistory.cloudlets.flexible.cost || 0) + (envBillingHistory.cloudlets.fixed.cost || 0);
var storage = envBillingHistory.storage.total.cost || 0;
var ips = envBillingHistory.ips.cost || 0;
var ssl = envBillingHistory.ssl.cost || 0;
return {
"total": (cloudlets + storage + ips + ssl).toFixed(2),
"ips": ips.toFixed(2),
"cloudlets": cloudlets.toFixed(2),
"storage": storage.toFixed(2),
"ssl": ssl.toFixed(2)
};
}'
- 'var environments = JSON.parse(getParam("environments"))'
- 'var billings = environments.map(function(environment) {
var billingHistory = fetchBilling(environment.raw.env.appid, envName);
return [
"Yesterday Billing " + (billingHistory ? billingHistory.total + "CHF" : "unknown"),
"_Yesterday Billing Details_",
(billingHistory ? Object.keys(billingHistory).filter(function(k) { return k !== "total"}).map(function(k) {
var value = billingHistory[k];
return " * __"+ k + "__: " + (value === "0" ? "free" : value + "CHF")
}).join("\n") : "unknown")
].join("\n\n");
}'
- 'var outputMessage = billings.join("\n")'
- 'return {"result": 0, outputMessage: outputMessage}'
- setGlobals:
- OUTPUT_BILLING: ${response.outputMessage}

- return:
type: success
message: |
# Jelastic Daily Review
## Backup Status
**▪️ Backup are installed**
${globals.OUTPUT_RESTIC_INSTALL}
**▪️ Backup are done**
${globals.OUTPUT_BACKUP}
## Billing status
${globals.OUTPUT_BILLING}
27 changes: 27 additions & 0 deletions .github/workflows/redeploy-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Redploy Decidim Image in Jelastic Infra

on:
workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-latest
container:
image: mwienk/jelastic-cli

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Redeploy container in Jelastic
env:
JELASTIC_LOGIN: ${{ secrets.JELASTIC_LOGIN }}
JELASTIC_PASSWORD: ${{ secrets.JELASTIC_PASSWORD }}
JELASTIC_HOSTER: ${{ secrets.JELASTIC_HOSTER }}
ENVNAME: ${{ secrets.ENVNAME }}
NODE_GROUP: ${{ secrets.NODE_GROUP }} # Default to cp if not set
TAG: ${{ secrets.TAG }} # Default to latest if not set
USE_EXISTING_VOLUME: ${{ secrets.USE_EXISTING_VOLUME }} # Default to true if not set
run: |
/root/jelastic/users/authentication/signin --login $JELASTIC_LOGIN --password $JELASTIC_PASSWORD --platformUrl $JELASTIC_HOSTER
/root/jelastic/environment/control/redeploycontainersbygroup --envName $ENVNAME --nodeGroup ${NODE_GROUP:-cp} --tag ${TAG:-latest} --useExistingVolumes ${USE_EXISTING_VOLUME:-true}

0 comments on commit eb588d7

Please sign in to comment.