Initial commit

main
Denny Cave 2023-10-05 22:11:32 -05:00
commit 8e180f22ea
51 changed files with 2140 additions and 0 deletions

45
addon/WPMU.jps 100755
View File

@ -0,0 +1,45 @@
jpsType: update
jpsVersion: '1.1'
name: Multisites addon for WordPress cluster
description: Multisites addon for WordPress cluster
logo: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master/images/wp-cluster.png
baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master
settings:
main:
fields:
- name: mode
caption: Multisites mode
type: radio-fieldset
values:
subdir: SubDirectories
subdom: SubDomain
default: subdir
globals:
MODE: ${settings.mode}
onInstall:
- if (/lemp/.test("${nodes.cp.nodeType}") || /nginxphp/.test("${nodes.cp.nodeType}")):
- if ('${globals.MODE}' == 'subdir'):
cmd[${nodes.cp.master.id}]: |-
wget ${baseUrl}/configs/cp/nginx/subdir.conf -O /etc/nginx/conf.d/SITES_ENABLED/subdir.conf
sudo /etc/init.d/nginx reload
- if ('${globals.MODE}' == 'subdom'):
cmd[${nodes.cp.master.id}]: |-
wget ${baseUrl}/configs/cp/nginx/subdom.conf -O /etc/nginx/conf.d/SITES_ENABLED/subdom.conf
sudo /etc/init.d/nginx reload
- if (/llsmp/.test("${nodes.cp.nodeType}") || /litespeed/.test("${nodes.cp.nodeType}")):
- if ('${globals.MODE}' == 'subdir'):
cmd[${nodes.cp.master.id}]: |-
wget ${baseUrl}/configs/cp/litespeed/.htaccess_subdir -O /tmp/.htaccess_wpmu
- if ('${globals.MODE}' == 'subdom'):
cmd[${nodes.cp.master.id}]: |-
wget ${baseUrl}/configs/cp/litespeed/.htaccess_subdom -O /tmp/.htaccess_wpmu
- cmd[${nodes.cp.master.id}]: |-
cat /tmp/.htaccess_wpmu >> /var/www/webroot/ROOT/.htaccess
wget ${baseUrl}/scripts/setupWP.sh?_r=${fn.random} -O ~/setupWP.sh &>> /var/log/run.log
bash ~/setupWP.sh --wpmu true --MODE ${settings.mode}

View File

@ -0,0 +1,17 @@
jpsType: update
jpsVersion: '1.1'
id: myisam2innodb
name: WordPress MyISAM to InnoDB converter
onInstall:
- forEach(nodes.sqldb):
- cmd[${nodes.cp.master.id}]: |-
rm -f /tmp/dump-node${@i.id}.sql
~/bin/wp config set DB_HOST node${@i.id} --path=${SERVER_WEBROOT}
~/bin/wp db export /tmp/dump-node${@i.id}.sql --path=${SERVER_WEBROOT}
- cmd[${nodes.cp.master.id}]: |-
mv $(ls -S /tmp/dump* | head -n 1) /tmp/dump.sql
sed 's/ENGINE=MyISAM/ENGINE=InnoDB/g' /tmp/dump.sql > /tmp/dump-innodb.sql
~/bin/wp db import /tmp/dump-innodb.sql --path=${SERVER_WEBROOT}
~/bin/wp config set DB_HOST sqldb --path=${SERVER_WEBROOT}

View File

@ -0,0 +1,44 @@
jpsType: update
jpsVersion: '1.1'
id: wordpress-multisite
name: WordPress Multisite
description: WordPress Multisite
logo: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master/images/wp-cluster.png
settings:
fields:
- name: mode
caption: Multisites mode
type: radio-fieldset
values:
subdir: SubDirectories
subdom: SubDomain
default: subdir
globals:
mode: ${settings.mode:subdir}
onInstall:
- if (/lemp/.test("${nodes.cp.nodeType}") || /nginxphp/.test("${nodes.cp.nodeType}")):
- if ('${globals.mode}' == 'subdir'):
cmd[${nodes.cp.master.id}]: |-
wget ${baseUrl}../configs/cp/nginx/subdir.conf -O /etc/nginx/conf.d/sites-enabled/subdir.conf;
sudo jem service restart
- if ('${globals.mode}' == 'subdom'):
cmd[${nodes.cp.master.id}]: |-
wget ${baseUrl}../configs/cp/nginx/subdom.conf -O /etc/nginx/conf.d/sites-enabled/subdom.conf;
sudo jem service restart
- if (/llsmp/.test("${nodes.cp.nodeType}") || /litespeed/.test("${nodes.cp.nodeType}")):
- if ('${globals.mode}' == 'subdir'):
cmd[${nodes.cp.master.id}]: |-
wget ${baseUrl}../configs/cp/litespeed/.htaccess_subdir -O /tmp/.htaccess_wpmu;
- if ('${globals.mode}' == 'subdom'):
cmd[${nodes.cp.master.id}]: |-
wget ${baseUrl}../configs/cp/litespeed/.htaccess_subdom -O /tmp/.htaccess_wpmu;
- cmd[${nodes.cp.master.id}]: |-
cat /tmp/.htaccess_wpmu >> /var/www/webroot/ROOT/.htaccess;
bash ~/bin/setupWP.sh --multisite true --mode ${globals.mode};

View File

@ -0,0 +1,42 @@
jps: https://github.com/jelastic-jps/wordpress-cluster/blob/v2.0.0/manifest.yml
component: wordpress
stack:
- nodeType: litespeedadc
tagSetting: bl_tag
nodeGroup: bl
optimization: true
options:
- ls-addon: true
wp_protect: true
waf: true
- nodeType: litespeedphp
tagSetting: cp_tag
nodeGroup: cp
optimization: true
options:
- ls-addon: true
wp_protect: true
waf: true
- nodeType: nginx
tagSetting: bl_tag
nodeGroup: bl
options:
- ls-addon: false
- nodeType: nginxphp
tagSetting: cp_tag
nodeGroup: cp
optimization: true
options:
- ls-addon: false
- nodeType: mariadb
tagSetting: sqldb_tag
nodeGroup: sqldb
options:
- galera: true
- galera: false
- nodeType: storage
tagSetting: storage_tag
nodeGroup: storage
options:
- glusterfs: false
- glusterfs: true

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<virtualHostConfig>
<logging>
<accessLog>
<useServer>1</useServer>
</accessLog>
</logging>
<security>
<wpProtectAction>0</wpProtectAction>
<wpProtectLimit>10</wpProtectLimit>
</security>
<cache>
<storage>
<cacheStorePath>/tmp/lscache/vhosts/$VH_NAME</cacheStorePath>
<litemage>0</litemage>
</storage>
<cachePolicy>
<checkPublicCache>1</checkPublicCache>
<checkPrivateCache>1</checkPrivateCache>
<cacheStaticFile>15</cacheStaticFile>
</cachePolicy>
</cache>
</virtualHostConfig>

View File

@ -0,0 +1,25 @@
fields:
- caption: Scaling Strategy
type: list
name: loadGrowth
default: slow
required: true
width: 225
tooltip: |
Configure auto-scaling triggers, i.e. how fast the system responds to load spikes by adding or removing nodes.
<p>Read more about <a href="https://docs.jelastic.com/automatic-horizontal-scaling">Automatic Horizontal Scaling</a></p>
values:
- value: slow
caption: Low Load
tooltip: <h2>Low load scaling strategy</h2>add 1 new node when CPU > 70% <p>remove when CPU < 20%</p>
- value: medium
caption: Medium Load
tooltip: <h3>Medium load scaling strategy</h3>add 1 new node when CPU > 50% <p>remove when CPU < 20%</p>
- value: fast
caption: High Load
tooltip: <h3>High load scaling strategy</h3>add 2 new nodes when CPU > 30% <p>remove when CPU < 10%</p>
- caption: Advanced Features
type: displayfield
name: displayfield
markup:

View File

@ -0,0 +1,16 @@
[mysqld]
# Duplicate entry '_transient_doing_cron' for key 'option_name', Error_code: 1062;
slave-skip-errors = 1062
max_connections=500
join_buffer_size = 3M
tmp_table_size = 128M
max_heap_table_size = 128M
thread_cache_size = 16K
table_definition_cache = 4K
open_files_limit = 524290
local-infile=0
innodb_log_file_size = 128M
wsrep_slave_threads = 16
innodb_flush_log_at_trx_commit = 2

View File

@ -0,0 +1,9 @@
<?php
if ( (isset($_SERVER['HTTP_X_FORWARDED_PROTO'] )) && (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) ) $_SERVER['HTTPS']='on';
// ** WordPress reverse proxy x-forwarded-for ip fix ** //
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
$http_x_headers = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );
$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 57 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
images/favicon.ico 100755

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
images/woo_logo.png 100755

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1 @@
<svg id="bd6942b8-aaf0-4494-94d3-41fa0412bbe5" data-name="—лой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="73" height="49.72" viewBox="0 0 73 49.72"><defs><linearGradient id="b49616d0-f363-43b4-ae48-8f0b400c8ed0" x1="20.57" y1="34.26" x2="29.54" y2="34.26" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0844dc"/><stop offset="0.14" stop-color="#0c49dd"/><stop offset="0.31" stop-color="#1757e0"/><stop offset="0.49" stop-color="#2a6fe6"/><stop offset="0.68" stop-color="#4590ee"/><stop offset="0.87" stop-color="#66baf7"/><stop offset="1" stop-color="#80dbff"/></linearGradient><linearGradient id="b9927cdf-5754-4997-afda-fe49413d9f08" x1="23.19" y1="27.26" x2="47.25" y2="27.26" xlink:href="#b49616d0-f363-43b4-ae48-8f0b400c8ed0"/><linearGradient id="b9b1e13d-0a2e-40f8-8875-73f11c3452b1" x1="32" y1="38.99" x2="41.78" y2="38.99" xlink:href="#b49616d0-f363-43b4-ae48-8f0b400c8ed0"/><linearGradient id="e42f5278-64d8-42e8-a167-eb55486e0588" x1="44.5" y1="33.4" x2="52.42" y2="33.4" xlink:href="#b49616d0-f363-43b4-ae48-8f0b400c8ed0"/><linearGradient id="f91cc7bb-5c27-48fc-b5d0-9a32283d8393" x1="17.93" y1="30.34" x2="55.06" y2="30.34" xlink:href="#b49616d0-f363-43b4-ae48-8f0b400c8ed0"/></defs><circle cx="14.22" cy="30.35" r="13.72" fill="none" stroke="#6a77a8" stroke-miterlimit="10" opacity="0.8"/><circle cx="58.78" cy="30.35" r="13.72" fill="none" stroke="#6a77a8" stroke-miterlimit="10" opacity="0.8"/><path d="M46.27,30.42a12.47,12.47,0,0,0,7,11.21L47.35,25.34A12.47,12.47,0,0,0,46.27,30.42Z" fill="#6a7ca2" opacity="0.8" style="isolation:isolate"/><path d="M67.15,29.79a6.61,6.61,0,0,0-1-3.44,5.89,5.89,0,0,1-1.23-2.92A2.16,2.16,0,0,1,67,21.21h.16a12.46,12.46,0,0,0-18.83,2.35h.8c1.3,0,3.32-.15,3.32-.15a.51.51,0,0,1,.08,1s-.67.08-1.42.12l4.54,13.5,2.72-8.18-1.94-5.32c-.67,0-1.31-.12-1.31-.12a.51.51,0,0,1,.08-1s2.06.15,3.29.15,3.32-.15,3.32-.15a.51.51,0,0,1,.08,1s-.68.08-1.43.12L65,38l1.25-4.15A15.14,15.14,0,0,0,67.15,29.79Z" fill="#6a7ca2" opacity="0.8" style="isolation:isolate"/><path d="M59,31.51,55.21,42.37a12.41,12.41,0,0,0,7.66-.2L62.78,42Z" fill="#6a7ca2" opacity="0.8" style="isolation:isolate"/><path d="M69.67,24.44a10.1,10.1,0,0,1,.08,1.28,11.76,11.76,0,0,1-.94,4.46L65,41.19a12.45,12.45,0,0,0,4.67-16.75Z" fill="#6a7ca2" opacity="0.8" style="isolation:isolate"/><path d="M1.79,30.42a12.46,12.46,0,0,0,7,11.21L2.87,25.34A12.47,12.47,0,0,0,1.79,30.42Z" fill="#6a7ca2" opacity="0.8" style="isolation:isolate"/><path d="M22.67,29.79a6.52,6.52,0,0,0-1-3.44,5.87,5.87,0,0,1-1.22-2.92,2.16,2.16,0,0,1,2.09-2.22h.16A12.46,12.46,0,0,0,3.84,23.57h.81C6,23.58,8,23.43,8,23.43a.51.51,0,0,1,.08,1s-.68.08-1.43.12l4.54,13.5,2.73-8.18L12,24.57c-.68,0-1.31-.12-1.31-.12a.51.51,0,0,1,.08-1s2.06.15,3.28.15,3.32-.15,3.32-.15a.51.51,0,0,1,.08,1s-.68.08-1.43.12L20.48,38l1.24-4.15A15.14,15.14,0,0,0,22.67,29.79Z" fill="#6a7ca2" opacity="0.8" style="isolation:isolate"/><path d="M14.48,31.51,10.74,42.37a12.41,12.41,0,0,0,7.66-.2.56.56,0,0,1-.09-.17Z" fill="#6a7ca2" opacity="0.8" style="isolation:isolate"/><path d="M25.19,24.44a8.47,8.47,0,0,1,.09,1.28,11.8,11.8,0,0,1-1,4.46l-3.81,11a12.45,12.45,0,0,0,6.2-10.77A12.31,12.31,0,0,0,25.19,24.44Z" fill="#6a7ca2"/><circle cx="36.5" cy="30.35" r="19.37" fill="#fff"/><path d="M20.57,30.33a15.93,15.93,0,0,0,9,14.34L22,23.85A15.79,15.79,0,0,0,20.57,30.33Z" fill="url(#b49616d0-f363-43b4-ae48-8f0b400c8ed0)"/><path d="M47.25,29.53a8.33,8.33,0,0,0-1.32-4.39c-.8-1.31-1.56-2.42-1.56-3.74A2.75,2.75,0,0,1,47,18.58h.21a15.92,15.92,0,0,0-24.06,3l1,0c1.67,0,4.25-.21,4.25-.21a.66.66,0,0,1,.1,1.32s-.86.1-1.82.15l5.8,17.25L36,29.67l-2.48-6.8c-.86-.05-1.67-.15-1.67-.15A.66.66,0,0,1,32,21.4s2.63.21,4.2.21,4.24-.21,4.24-.21a.66.66,0,0,1,.1,1.32s-.86.1-1.82.15L44.44,40,46,34.68A19.26,19.26,0,0,0,47.25,29.53Z" fill="url(#b9927cdf-5754-4997-afda-fe49413d9f08)"/><path d="M36.77,31.73,32,45.61a15.92,15.92,0,0,0,9.78-.25,1.51,1.51,0,0,1-.11-.22Z" fill="url(#b9b1e13d-0a2e-40f8-8875-73f11c3452b1)"/><path d="M50.47,22.69a12.09,12.09,0,0,1,.11,1.64A15.24,15.24,0,0,1,49.37,30L44.5,44.1a15.93,15.93,0,0,0,6-21.41Z" fill="url(#e42f5278-64d8-42e8-a167-eb55486e0588)"/><path d="M36.49,11.77A18.57,18.57,0,1,0,55.06,30.33,18.59,18.59,0,0,0,36.49,11.77Zm0,36.28A17.72,17.72,0,1,1,54.21,30.33,17.74,17.74,0,0,1,36.49,48.05Z" fill="url(#f91cc7bb-5c27-48fc-b5d0-9a32283d8393)"/><path d="M44.38,3.62a.61.61,0,0,1,0,.14L43.31,8a.47.47,0,0,1-.46.36l-6.34,0H30.18A.48.48,0,0,1,29.71,8L28.65,3.78a.76.76,0,0,1,0-.15,1,1,0,0,1,.3-2,1,1,0,0,1,.64,1.79l1.33,1.33a1.77,1.77,0,0,0,1.27.53,1.79,1.79,0,0,0,1.43-.71l2.17-2.88A1,1,0,0,1,35.49,1a1,1,0,1,1,2,0,1,1,0,0,1-.28.69h0l2.15,2.88a1.82,1.82,0,0,0,1.44.72,1.74,1.74,0,0,0,1.26-.52l1.34-1.33a1,1,0,1,1,1.63-.79A1,1,0,0,1,44.38,3.62ZM43.21,9.89a.48.48,0,0,0-.48-.48H30.31a.48.48,0,0,0-.48.48V11a.49.49,0,0,0,.48.48H42.73a.49.49,0,0,0,.48-.48Z" fill="#ffc107"/></svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

220
manifest.yml 100755
View File

@ -0,0 +1,220 @@
type: install
jpsVersion: '1.7.2'
name: WordPress Performance Cluster
id: wp-performance-cluster
categories:
- apps/clusters
- apps/content-management
description:
#text: WordPress Cluster Kit with highly available Load Balancer and Shared Storage with GlusterFS, database clustering, and scaling mode to create an optimal environment for highly-loaded projects. The package provides integrated autoscaling and high availability for development and production environments. Clustered topology ensures effective handling of heavy workload.
#short: WordPress Cluster with built-in kit v2 for choosing optimal servers, database clustering type, scaling mode and a set of advanced features for highly-loaded projects
logo: /images/wp-cluster-kit.svg
baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/v2.2.0
onBeforeInit: /scripts/beforeInit.js?_r=${fn.random}
onBeforeInstall: /scripts/beforeInstall.js?_r=${fn.random}
skipNodeEmails: true
nodes: definedInOnBeforeInstall
settings:
fields:
# - caption: Number of App servers
# - caption: Scalable app servers limit
# - caption: App server base vCPU
# - caption: App server scalable vCPU
# - caption: PHP Version
# - caption: Email credentials
# type: checkbox
# name: ls-addon
# value: true
# disabled: false
# tooltip: "If this option is enabled, environment details (including WP admin logins) will be emailed to you upon successful deployment."
# - caption: Database type (single or clustered)
# relay & OCP
# s3 offloading
mixins:
- /scripts/common.yml
globals:
PATH: ${baseUrl}
DB_USER: ${settings.DB_USER:user-[fn.random]}
DB_PASS: ${settings.DB_PASS:[fn.password(10)]}
DB_HOST: sqldb
PROTOCOL: https
WP_ADMIN_PASS: ${settings.WP_ADMIN_PASS:[fn.password(10)]}
LS_ADMIN_PASS: ${settings.LS_ADMIN_PASS:[fn.password(10)]}
onInstall:
- addLimits
#- addMetadata
- setDomain # why is this necessary?
- initLEsettings
#- if (${settings.is_trigger:true}): setTriggers
- optimization
- setupCacheSync
- storageHealthCheck
- storageMount: NFS4
- setPassword
- getRedisPswd
- installWordpress
#- if ('${settings.mu-addon:false}' == 'true'): configureMultisite
- script: |
var actions = [];
actions.push({
jps: "https://github.com/jelastic-jps/lets-encrypt/blob/master/manifest.jps?_r=${fn.random}",
nodeGroup: "bl",
skipEmail: "true",
settings: {
customDomains: "${globals.DOMAIN}",
fallbackToX1: "true",
withExtIp: "${globals.isExtIP}"
}
});
return { result: 0, onAfterReturn: { install: actions } };
- setupLEdomain
- install:
- jps: /scripts/cacheClean.jps?_r=${fn.random}
- jps: /scripts/addons.jps?_r=${fn.random}
- jps: /scripts/events.jps?_r=${fn.random}
#instant login, root access, and other addons
- return:
type: success
message: /success/text/success.md?_r=${fn.random}
email: /success/email/success.md?_r=${fn.random}
actions:
addLimits: #what does this do?
- env.control.ApplyNodeGroupData [*]:
data:
isRequired: true
# addMetadata:
# script: |
# var metadata = { project: "${settings.project:default}", projectScope: "${settings.projectScope:production}" };
# return api.env.control.ApplyEnvProperty ?
# api.env.control.ApplyEnvProperty('${env.name}', session, metadata) :
# api.env.control.ApplyNodeGroupData('${env.name}', session, 'cp', metadata);
setDomain:
- script: /scripts/idna.js
domains: ${env.domain}
- setGlobals:
DOMAIN: ${response.domains}
# setTriggers:
# - log: Auto Scaling Triggers
# - script: /scripts/addTriggers.js
# nodeGroup: cp
# resourceType: CPU
# loadGrowth: 'slow'
# cleanOldTriggers: true
# scaleDownLimit: ${nodes.cp.length}
initLEsettings:
# I don't think we need to check this. Just set to true.
# - script: |
# return {
# result:0,
# extIP: Boolean(jelastic.billing.account.GetQuotas('environment.externalip.enabled').array[0].value)
# }
# - setGlobals:
# isExtIP: ${response.extIP}
- setGlobals:
isExtIP: true
- cmd[cp, bl]: |-
[ ! -d /var/lib/jelastic/keys/letsencrypt ] && mkdir -p /var/lib/jelastic/keys/letsencrypt;
echo "webroot=false" > /var/lib/jelastic/keys/letsencrypt/settings-custom;
echo "webrootPath=/var/www/webroot/ROOT" >> /var/lib/jelastic/keys/letsencrypt/settings-custom;
echo "test=false" >> /var/lib/jelastic/keys/letsencrypt/settings-custom;
echo "withExtIp=${globals.isExtIP}" >> /var/lib/jelastic/keys/letsencrypt/settings-custom;
user: root
setupLEdomain:
- cmd[${nodes.bl.master.id}]: source /opt/letsencrypt/settings && echo $domain
- cmd[${nodes.cp.master.id}]: bash ~/bin/setupWP.sh --url https://${response.out};
optimization:
- log: Load Balancers and App servers optimization
- install:
- jps: https://raw.githubusercontent.com/jelastic/templates/master/config_v2.jps?_r=${fn.random}
settings:
targetGroup: bl
targetNodes: bl
optimization: wordpress
- jps: https://raw.githubusercontent.com/jelastic/templates/master/config_v2.jps?_r=${fn.random}
settings:
targetGroup: cp
targetNodes: cp
optimization: wordpress
- cmd[cp, bl]: if test -f /usr/local/sbin/optimization.sh; then bash /usr/local/sbin/optimization.sh &>> /var/log/run.log; fi
setPassword:
- cmd[cp, bl]: jem passwd set -p ${globals.LS_ADMIN_PASS}
user: root
storageMount:
- log: Mount Storage
- api:
- method: jelastic.environment.file.AddMountPointByGroup
params:
nodeGroup: cp
sourceNodeId: ${nodes.storage.master.id}
sourcePath: /data
path: /var/www/webroot/ROOT
sourceAddressType: NODE_GROUP
protocol: ${this}
storageHealthCheck:
- cmd[cp]: |-
echo "<?php http_response_code(500); ?>" > /var/www/webroot/ROOT/index.php
#configureMultisite:
# - install: /addons/multisite.jps
getRedisPswd:
- cmd[nosqldb]: cat /etc/redis.conf | tail -1 | awk '{print $2}';
- setGlobals:
REDIS_PSWD: ${response.out}
installWordpress:
- install: /scripts/installWP.jps
settings:
db_host: ${globals.DB_HOST}
db_user: ${globals.DB_USER}
db_pass: ${globals.DB_PASS}
redis_host: nosqldb
redis_port: 6379
redis_user: admin
redis_pswd: ${globals.REDIS_PSWD}
wp_admin_pass: ${globals.WP_ADMIN_PASS}
wp_title: "Hello World"
wp_url: ${globals.PROTOCOL}://${globals.DOMAIN}/
version_wordpress: ${globals.version_wordpress}
setupCacheSync:
- if (/litespeed/.test("${nodes.bl.nodeType}")):
- install: /scripts/setupHA4LB.jps?_r=${fn.random}
updateTriggers:
if (!${event.params.auto:true}):
- log: update scaling trigger
- script: /scripts/updateTriggers.js
count: ${nodes.cp.length}
# other stuff - basic BB optimizations should be applied here
# use WP redis cache plugin instead of litespeed redis cache
# Use https://plugintests.com/plugins/wporg/litespeed-cache/tips to disable ls cache page?

View File

@ -0,0 +1,92 @@
//@auth
//@req(nodeGroup, resourceType, cleanOldTriggers, loadGrowth)
var scaleUpLoadPeriod = 1,
scaleDownLimit = getParam("scaleDownLimit") || 2,
scaleDownLoadPeriod = 5;
var resp = jelastic.billing.account.GetQuotas('environment.maxsamenodescount');
if (resp.result != 0) return resp;
var scaleUpLimit = resp.array[0] && resp.array[0].value ? resp.array[0].value : 1000;
if (scaleUpLimit <= scaleDownLimit) return {result:0, warning: 'autoscaling triggers have not been added due to upLimit ['+scaleUpLimit+'] <= downLimit ['+scaleDownLimit+']'}
if (loadGrowth.toLowerCase() == "slow") {
var scaleUpValue = 70,
scaleDownValue = 20,
scaleNodeCount = 1;
}
if (loadGrowth.toLowerCase() == "medium") {
var scaleUpValue = 50,
scaleDownValue = 20,
scaleNodeCount = 1;
}
if (loadGrowth.toLowerCase() == "fast") {
var scaleUpValue = 30,
scaleDownValue = 10,
scaleNodeCount = 2;
}
if (cleanOldTriggers) {
var actions = ['ADD_NODE', 'REMOVE_NODE'];
for (var i = 0; i < actions.length; i++){
var array = jelastic.env.trigger.GetTriggers(appid, session, actions[i]).array;
for (var j = 0; j < array.length; j++) jelastic.env.trigger.DeleteTrigger(appid, session, array[j].id);
}
}
resp = jelastic.env.trigger.AddTrigger('${env.envName}', session,
{
"isEnabled": true,
"name": "scale-up",
"nodeGroup": nodeGroup,
"period": scaleUpLoadPeriod,
"condition": {
"type": "GREATER",
"value": scaleUpValue,
"resourceType": resourceType,
"valueType": "PERCENTAGES"
},
"actions": [
{
"type": "ADD_NODE",
"customData": {
"limit": scaleUpLimit,
"count": scaleNodeCount,
"notify": true
}
}
]
}
);
if (resp.result != 0) return resp;
resp = jelastic.env.trigger.AddTrigger('${env.envName}', session,
{
"isEnabled": true,
"name": "scale-down",
"nodeGroup": nodeGroup,
"period": scaleDownLoadPeriod,
"condition": {
"type": "LESS",
"value": scaleDownValue,
"resourceType": resourceType,
"valueType": "PERCENTAGES"
},
"actions": [
{
"type": "REMOVE_NODE",
"customData": {
"limit": scaleDownLimit,
"count": 1,
"notify": true
}
}
]
}
);
return resp;

73
scripts/addons.jps 100755
View File

@ -0,0 +1,73 @@
type: update
id: wordpress-addons
name: Addons for WordPress
description: Addons for WordPress
onAfterClone:
- script: delete MANIFEST.id; return {result:0, jps:MANIFEST};
- install [cp]: ${response.jps}
envName: ${event.response.env.envName}
onInstall:
installAddon:
- id: setup-site-url-addon
nodeGroup: cp
- id: cache-purge-addon
nodeGroup: cp
addons:
- id: setup-site-url-addon
type: update
name: WordPress Site Address (URL)
description: The Site Address(URL) setting is the address you want people to type in their browser to reach your WordPress blog.
logo: https://github.com/jelastic-jps/wordpress/blob/master/wordpress-edition/images/logo/cluster.svg
settings:
fields:
- type: string
name: siteURL
caption: Site Address (URL)
default: ''
required: true
regex: "^https?:\\/\\/.+$"
regexText: Incorrect Site URL.
buttons:
- caption: Site URL
settings: main
action: setup_site_url
loadingText: Applying...
confirmText: Do you want to change Site URL?
successText: Site URL for WordPress has been successfully applyed!
- id: cache-purge-addon
type: update
name: Cache Manager
description: Clean all caches at once. Object Cache, Static Cache...
logo: https://github.com/jelastic-jps/wordpress/blob/master/wordpress-edition/images/logo/cluster.svg
buttons:
- caption: Clean all caches
action: cache_purge
loadingText: Cleaning...
confirmText: Do you want to clean all caches?
successText: Caches have been successfully cleaned!
actions:
litespeed-cache-clean:
- if (nodes.bl):
cmd[bl]: |-
[ -d /tmp/lscache/vhosts/Jelastic/ ] && rm -rf /tmp/lscache/vhosts/Jelastic/* &>> /var/log/run.log;
- cmd[cp]: |-
[ -d /var/www/webroot/.cache/vhosts/Jelastic/ ] && rm -rf /var/www/webroot/.cache/vhosts/Jelastic/* &>> /var/log/run.log;
wordpress-cache-clean:
- cmd[cp]: |-
wp cache flush --path=/var/www/webroot/ROOT/ &>> /var/log/run.log;
cache_purge:
- if (/llsmp/.test("${nodes.cp.nodeType}") || /litespeed/.test("${nodes.cp.nodeType}")): litespeed-cache-clean
- wordpress-cache-clean
setup_site_url:
- cmd[${nodes.cp.master.id}]: bash ~/bin/setupWP.sh --url ${settings.siteURL}
- cache_purge

View File

@ -0,0 +1,14 @@
jpsType: update
name: Balancer Rebuild
description: This script for balancer rebuild
id: wordpress-balancer-rebuild
onInstall:
- cmd[bl]: |-
[ -f /var/www/conf/hosts_list ] && rm -f /var/www/conf/hosts_list;
- forEach(i:nodes.cp):
cmd[bl]: echo '${@i.address}' >> /var/www/conf/hosts_list;
- cmd[bl]: |-
jem balancer clear;
jem balancer rebuildCommon;
user: root

View File

@ -0,0 +1,151 @@
import com.hivext.api.Response;
import org.yaml.snakeyaml.Yaml;
import com.hivext.api.core.utils.Transport;
var cdnAppid = "c05ffa5b45628a2a0c95467ebca8a0b4";
var lsAppid = "9e6afcf310004ac84060f90ff41a5aba";
var group = jelastic.billing.account.GetAccount(appid, session);
var isCDN = jelastic.dev.apps.GetApp(cdnAppid);
var isLS = jelastic.dev.apps.GetApp(lsAppid);
//checking quotas
var perEnv = "environment.maxnodescount",
maxEnvs = "environment.maxcount",
perNodeGroup = "environment.maxsamenodescount",
maxCloudletsPerRec = "environment.maxcloudletsperrec";
var nodesPerEnvWO_Bl = 9,
nodesPerEnvWO_GlusterFS = 7,
nodesPerEnvMin = 6,
nodesPerGroupMin = 2,
maxCloudlets = 16,
markup = "", cur = null, text = "used", prod = true;
var settings = jps.settings;
var fields = {};
for (var i = 0, field; field = jps.settings.fields[i]; i++)
fields[field.name] = field;
var quotas = jelastic.billing.account.GetQuotas(perEnv + ";"+maxEnvs+";" + perNodeGroup + ";" + maxCloudletsPerRec ).array;
var group = jelastic.billing.account.GetAccount(appid, session);
for (var i = 0; i < quotas.length; i++){
var q = quotas[i], n = toNative(q.quota.name);
if (n == maxCloudletsPerRec && maxCloudlets > q.value){
err(q, "required", maxCloudlets, true);
prod = false;
}
if (n == perEnv && nodesPerEnvMin > q.value){
if (!markup) err(q, "required", nodesPerEnvMin, true);
prod = false;
}
if (n == perNodeGroup && nodesPerGroupMin > q.value){
if (!markup) err(q, "required", nodesPerGroupMin, true);
prod = false;
}
if (n == perEnv && nodesPerEnvMin == q.value){
fields["glusterfs"].value = false;
fields["glusterfs"].disabled = true;
fields["galera"].value = false;
fields["galera"].disabled = true;
fields["bl_count"].value = 1;
fields["displayfield"].markup = "Some advanced features are not available. Please upgrade your account.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
}
if (n == perEnv && nodesPerEnvWO_GlusterFS == q.value){
fields["glusterfs"].value = false;
fields["glusterfs"].disabled = true;
fields["bl_count"].value = 1;
fields["displayfield"].markup = "Some advanced features are not available. Please upgrade your account.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
}
if (n == perEnv && q.value == 8){
fields["glusterfs"].value = false;
fields["glusterfs"].disabled = true;
fields["bl_count"].value = 2;
fields["displayfield"].markup = "Some advanced features are not available. Please upgrade your account.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
}
if (n == perEnv && nodesPerEnvWO_Bl == q.value){
fields["bl_count"].value = 1;
}
if (n == perNodeGroup && nodesPerGroupMin == q.value){
fields["glusterfs"].value = false;
fields["glusterfs"].disabled = true;
fields["galera"].value = false;
fields["galera"].disabled = true;
fields["displayfield"].markup = "Some advanced features are not available. Please upgrade your account.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
}
if (isLS.result == 0 || isLS.result == Response.PERMISSION_DENIED) {
fields["ls-addon"].hidden = false;
fields["ls-addon"].value = true;
} else {
fields["ls-addon"].hidden = true;
fields["ls-addon"].value = false;
fields["ls-addon"].showIf = null;
}
if (isCDN.result == 0 || isCDN.result == Response.PERMISSION_DENIED) {
fields["cdn-addon"].hidden = false;
fields["cdn-addon"].value = true;
} else {
fields["cdn-addon"].hidden = true;
fields["cdn-addon"].value = false;
}
}
if (!prod || group.groupType == 'trial') {
fields["ls-addon"].disabled = true;
fields["ls-addon"].value = false;
fields["loadGrowth"].disabled = true;
fields["galera"].disabled = true;
fields["galera"].value = false;
fields["glusterfs"].disabled = true;
fields["glusterfs"].value = false;
fields["le-addon"].disabled = true;
fields["le-addon"].value = false;
fields["cdn-addon"].disabled = true;
fields["cdn-addon"].value = false;
fields["mu-addon"].disabled = true;
fields["displayfield"].markup = "Advanced features are not available.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
fields["bl_count"].markup = "WordPress cluster is not available. " + markup + "Please upgrade your account.";
if (group.groupType == 'trial')
fields["bl_count"].markup = "WordPress cluster is not available for " + group.groupType + ". Please upgrade your account.";
fields["bl_count"].cls = "warning";
fields["bl_count"].hidden = false;
fields["bl_count"].height = 30;
settings.fields.push(
{"type": "compositefield","height": 0,"hideLabel": true,"width": 0,"items": [{"height": 0,"type": "string","required": true}]}
);
}
return {
result: 0,
settings: settings
};
function err(e, text, cur, override){
var m = (e.quota.description || e.quota.name) + " - " + e.value + ", " + text + " - " + cur + ". ";
if (override) markup = m; else markup += m;
}

View File

@ -0,0 +1,91 @@
var wpbfp = "THROTTLE";
var db_cluster = 'single'; //not sure if 'single' will work. If not, then try 'slave' or 'master'
var db_count = 1; //or 2 if 'slave' or 'master' db_cluster scheme
var nfs_protocol = "NFS4";
var resp = {
result: 0,
ssl: !!jelastic.billing.account.GetQuotas('environment.jelasticssl.enabled').array[0].value,
nodes: []
}
resp.nodes.push({
nodeType: "storage",
count: 1,
cloudlets: ${settings.storage.cloudlets:8},
diskLimit: "${settings.storage.diskspace:[quota.disk.limitation]}",
nodeGroup: "storage",
validation: {
minCount: 1,
maxCount: 1
}
});
// https://docs.cloudscripting.com/creating-manifest/basic-configs/#cluster-parameter
resp.nodes.push({
nodeType: "mariadb-dockerized",
cloudlets: ${settings.sqldb.cloudlets:16},
diskLimit: "${settings.sqldb.diskspace:[quota.disk.limitation]}",
count: db_count,
nodeGroup: "sqldb",
restartDelay: 10,
skipNodeEmails: true,
validation: {
minCount: db_count,
maxCount: db_count
},
cluster: {
scheme: db_cluster,
db_user: "${globals.DB_USER}",
db_pass: "${globals.DB_PASS}",
is_proxysql: false,
custom_conf: "${baseUrl}/configs/sqldb/wordpress.cnf"
},
env: {
SCHEME: db_cluster,
DB_USER: "${globals.DB_USER}",
DB_PASS: "${globals.DB_PASS}",
IS_PROXYSQL: false
}
});
resp.nodes.push({
nodeType: "litespeedadc",
count: 1,
cloudlets: ${settings.bl.cloudlets:8},
diskLimit: "${settings.bl.diskspace:[quota.disk.limitation]}",
nodeGroup: "bl",
restartDelay: 10,
env: {
WP_PROTECT: wpbfp,
WP_PROTECT_LIMIT: 100
}
}, {
nodeType: "litespeedphp",
count: ${settings.cp.nodes:2},
cloudlets: ${settings.cp.cloudlets:8},
diskLimit: "${settings.cp.diskspace:[quota.disk.limitation]}",
nodeGroup: "cp",
restartDelay: 10,
env: {
SERVER_WEBROOT: "/var/www/webroot/ROOT",
REDIS_ENABLED: "true",
WAF: "${settings.waf:false}",
WP_PROTECT: "OFF"
},
volumes: [
"/var/www/webroot/ROOT"
]
});
resp.nodes.push({
nodeType: "redis",
count: 1,
cloudlets: ${settings.nosqldb.cloudlets:8},
diskLimit: "${settings.nosqldb.diskspace:[quota.disk.limitation]}",
nodeGroup: "nosqldb"
});
return resp;

View File

@ -0,0 +1,18 @@
jpsType: update
name: Cache Clean
description: This script for cache clean
id: wordpress-cache-clean
onInstall:
- if (/llsmp/.test("${nodes.cp.nodeType}") || /litespeed/.test("${nodes.cp.nodeType}")): litespeed-cache-clean
- wordpress-cache-clean
actions:
litespeed-cache-clean:
- if (nodes.bl):
cmd[bl]: |-
[ -d /tmp/lscache/vhosts/Jelastic/ ] && rm -rf /tmp/lscache/vhosts/Jelastic/* &>> /var/log/run.log;
wordpress-cache-clean:
- cmd[cp]: |-
wp cache flush --path=/var/www/webroot/ROOT &>> /var/log/run.log;

97
scripts/common.yml 100755
View File

@ -0,0 +1,97 @@
actions:
applyEnvSettings:
script: |
var envs = '${this.targetAppid}'.split(',');
let nodes = [];
let nodeGroups = [], node, nodesByGroup, cloudlets, diskspace, count;
function getNodesByGroup(targetAppid, group) {
let groupNodes = [];
let resp = jelastic.env.control.GetEnvInfo(targetAppid, session);
if (resp.result != 0) return resp;
let nodes = resp.nodes;
for (let i = 0, n = nodes.length; i < n; i++) {
if (nodes[i].nodeGroup == group) {
groupNodes.push(nodes[i]);
}
}
return { result: 0, nodes: groupNodes }
};
for (var i=0, n = envs.length; i < n; i++) {
let targetAppid = envs[i];
let resp = jelastic.env.control.GetEnvInfo(targetAppid, session);
if (resp.result != 0) return resp;
var env = resp.env;
for (let i = 0, n = resp.nodes.length; i < n; i++) {
node = resp.nodes[i];
if (nodeGroups.indexOf(String(node.nodeGroup)) == -1) {
nodeGroups.push(String(node.nodeGroup));
nodesByGroup = getNodesByGroup(targetAppid, node.nodeGroup);
if (nodesByGroup.result != 0) return nodesByGroup;
cloudlets = node.flexibleCloudlets;
diskspace = node.diskLimit / 1000;
count = nodesByGroup.nodes.length;
if (node.nodeGroup == 'bl') {
if (!/cloudlets/.test('${this.bl.cloudlets}'))
cloudlets = String(node.flexibleCloudlets) != '${this.bl.cloudlets}' ? '${this.bl.cloudlets}' : node.flexibleCloudlets;
if (!/diskspace/.test('${this.bl.diskspace}'))
diskspace = String(diskspace) != '${this.bl.diskspace}' ? '${this.bl.diskspace}' : diskspace;
if (!/nodes/.test('${this.bl.nodes}'))
count = String(nodesByGroup.nodes.length) != '${this.bl.nodes}' ? '${this.bl.nodes}' : nodesByGroup.nodes.length;
}
if (node.nodeGroup == 'cp') {
if (!/cloudlets/.test('${this.cp.cloudlets}'))
cloudlets = String(node.flexibleCloudlets) != '${this.cp.cloudlets}' ? '${this.cp.cloudlets}' : node.flexibleCloudlets;
if (!/diskspace/.test('${this.cp.diskspace}'))
diskspace = String(node.diskLimit) != '${this.cp.diskspace}' ? '${this.cp.diskspace}' : node.diskLimit;
if (!/nodes/.test('${this.cp.nodes}'))
count = String(nodesByGroup.nodes.length) != '${this.cp.nodes}' ? '${this.cp.nodes}' : nodesByGroup.nodes.length;
}
if (node.nodeGroup == 'sqldb') {
if (!/cloudlets/.test('${this.sqldb.cloudlets}'))
cloudlets = String(node.flexibleCloudlets) != '${this.sqldb.cloudlets}' ? '${this.sqldb.cloudlets}' : node.flexibleCloudlets;
if (!/diskspace/.test('${this.sqldb.diskspace}'))
diskspace = String(node.diskLimit) != '${this.sqldb.diskspace}' ? '${this.sqldb.diskspace}' : node.diskLimit;
}
if (node.nodeGroup == 'nosqldb') {
if (!/cloudlets/.test('${this.nosqldb.cloudlets}'))
cloudlets = String(node.flexibleCloudlets) != '${this.nosqldb.cloudlets}' ? '${this.nosqldb.cloudlets}' : node.flexibleCloudlets;
if (!/diskspace/.test('${this.nosqldb.diskspace}'))
diskspace = String(node.diskLimit) != '${this.nosqldb.diskspace}' ? '${this.nosqldb.diskspace}' : node.diskLimit;
}
if (node.nodeGroup == 'storage') {
if (!/cloudlets/.test('${this.storage.cloudlets}'))
cloudlets = String(node.flexibleCloudlets) != '${this.storage.cloudlets}' ? '${this.storage.cloudlets}' : node.flexibleCloudlets;
if (!/diskspace/.test('${this.storage.diskspace}'))
diskspace = String(node.diskLimit) != '${this.storage.diskspace}' ? '${this.storage.diskspace}' : node.diskLimit;
}
nodes.push({
flexibleCloudlets: cloudlets,
fixedCloudlets: node.fixedCloudlets,
nodeType: node.nodeType,
nodeGroup: node.nodeGroup,
diskLimit: diskspace,
count: count
});
}
}
resp = api.env.control.ChangeTopology({
envName: targetAppid,
session: session,
env: env,
nodes: nodes
});
}
return { result: 0 };

66
scripts/events.jps 100755
View File

@ -0,0 +1,66 @@
type: update
id: wordpress-cluster-events
name: WordPress Cluster Events
baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/v2.2.0
onAfterScaleOut[nodeGroup:bl]: setupCacheSync
onAfterScaleIn[bl]: setupCacheSync
onAfterScaleIn[cp]: updateTriggers
onAfterScaleOut[nodeGroup:cp]: updateTriggers
onAfterStart:
cmd[cp]: sudo jem service restart
onAfterInstallAddon [nodeGroup:bl, id:letsencrypt-ssl-addon]:
- cmd[${nodes.bl.master.id}]: source /opt/letsencrypt/settings && echo $domain
- cmd[${nodes.cp.master.id}]: bash ~/bin/setupWP.sh --url https://${response.out};
onAfterClone:
- install: /scripts/setupHA4LB.jps?_r=${fn.random}
envName: ${event.response.env.envName}
- install: /scripts/balancerRebuild.jps?_r=${fn.random}
envName: ${event.response.env.envName}
- install: /scripts/setupDomain.jps?_r=${fn.random}
envName: ${event.response.env.envName}
settings:
domain: ${event.response.env.domain}
- install: /scripts/cacheClean.jps?_r=${fn.random}
envName: ${event.response.env.envName}
- script: delete MANIFEST.id; return {result:0, jps:MANIFEST};
- install: ${response.jps}
envName: ${event.response.env.envName}
onBeforeMigrate:
- cmd[${nodes.cp.master.id}]: wp option get siteurl --path=/var/www/webroot/ROOT | cut -d'/' -f3;
- if (/${response.out}/.test(env.domain)):
cmd[${nodes.cp.master.id}]: echo true > ~/migrate
- else:
cmd[${nodes.cp.master.id}]: echo false > ~/migrate
onAfterMigrate:
- install: /scripts/setupHA4LB.jps?_r=${fn.random}
- install: /scripts/balancerRebuild.jps?_r=${fn.random}
- cmd[${nodes.cp.master.id}]: if test -f ~/migrate; then cat ~/migrate; fi
- if (/${response.out}/.test(true)):
- install: /scripts/setupDomain.jps?_r=${fn.random}
settings:
domain: ${env.domain}
- install: /scripts/cacheClean.jps?_r=${fn.random}
actions:
setupCacheSync:
- if (/litespeed/.test("${nodes.bl.nodeType}")):
- install: /scripts/setupHA4LB.jps?_r=${fn.random}
updateTriggers:
if (!${event.params.auto:true}):
- log: update scaling trigger
- script: /scripts/updateTriggers.js
count: ${nodes.cp.length}

View File

@ -0,0 +1,41 @@
var envName = "${env.name}",
bFireWallEnabled,
outputRule,
inputRule,
rules,
resp;
inputRule = {
"direction": "INPUT",
"name": name,
"protocol": "ALL",
"ports": ports,
"src": "ALL",
"priority": 1080,
"action": "ALLOW"
};
outputRule = {
"direction":'OUTPUT',
"name":name,
"protocol":'ALL',
"ports":ports,
"dst":'ALL',
"priority":1000,
"action":'ALLOW'
};
if (jelastic.environment.security) {
resp = jelastic.billing.account.GetOwnerQuotas(appid, session, 'firewall.enabled');
if (!resp || resp.result !== 0) return resp;
bFireWallEnabled = resp.array[0] ? resp.array[0].value : 0;
if (bFireWallEnabled) {
resp = jelastic.environment.security.AddRule(envName, session, inputRule, nodeGroup);
if (!resp || resp.result !== 0) return resp;
return jelastic.environment.security.AddRule(envName, session, outputRule, nodeGroup);
}
}
return {
result: 0
}

332
scripts/idna.js 100755
View File

@ -0,0 +1,332 @@
//Javascript Punycode converter derived from example in RFC3492.
//This implementation is created by some@domain.name and released into public domain
var domains = getParam("domains", ""),
parsed = [];
var punycode = new function Punycode() {
// This object converts to and from puny-code used in IDN
//
// punycode.ToASCII ( domain )
//
// Returns a puny coded representation of "domain".
// It only converts the part of the domain name that
// has non ASCII characters. I.e. it dosent matter if
// you call it with a domain that already is in ASCII.
//
// punycode.ToUnicode (domain)
//
// Converts a puny-coded domain name to unicode.
// It only converts the puny-coded parts of the domain name.
// I.e. it dosent matter if you call it on a string
// that already has been converted to unicode.
//
//
this.utf16 = {
// The utf16-class is necessary to convert from javascripts internal character representation to unicode and back.
decode:function(input){
var output = [], i=0, len=input.length,value,extra;
while (i < len) {
value = input.charCodeAt(i++);
if ((value & 0xF800) === 0xD800) {
extra = input.charCodeAt(i++);
if ( ((value & 0xFC00) !== 0xD800) || ((extra & 0xFC00) !== 0xDC00) ) {
throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence");
}
value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000;
}
output.push(value);
}
return output;
},
encode:function(input){
var output = [], i=0, len=input.length,value;
while (i < len) {
value = input[i++];
if ( (value & 0xF800) === 0xD800 ) {
throw new RangeError("UTF-16(encode): Illegal UTF-16 value");
}
if (value > 0xFFFF) {
value -= 0x10000;
output.push(String.fromCharCode(((value >>>10) & 0x3FF) | 0xD800));
value = 0xDC00 | (value & 0x3FF);
}
output.push(String.fromCharCode(value));
}
return output.join("");
}
}
//Default parameters
var initial_n = 0x80;
var initial_bias = 72;
var delimiter = "\x2D";
var base = 36;
var damp = 700;
var tmin=1;
var tmax=26;
var skew=38;
var maxint = 0x7FFFFFFF;
// decode_digit(cp) returns the numeric value of a basic code
// point (for use in representing integers) in the range 0 to
// base-1, or base if cp is does not represent a value.
function decode_digit(cp) {
return cp - 48 < 10 ? cp - 22 : cp - 65 < 26 ? cp - 65 : cp - 97 < 26 ? cp - 97 : base;
}
// encode_digit(d,flag) returns the basic code point whose value
// (when used for representing integers) is d, which needs to be in
// the range 0 to base-1. The lowercase form is used unless flag is
// nonzero, in which case the uppercase form is used. The behavior
// is undefined if flag is nonzero and digit d has no uppercase form.
function encode_digit(d, flag) {
return d + 22 + 75 * (d < 26) - ((flag != 0) << 5);
// 0..25 map to ASCII a..z or A..Z
// 26..35 map to ASCII 0..9
}
//** Bias adaptation function **
function adapt(delta, numpoints, firsttime ) {
var k;
delta = firsttime ? Math.floor(delta / damp) : (delta >> 1);
delta += Math.floor(delta / numpoints);
for (k = 0; delta > (((base - tmin) * tmax) >> 1); k += base) {
delta = Math.floor(delta / ( base - tmin ));
}
return Math.floor(k + (base - tmin + 1) * delta / (delta + skew));
}
// encode_basic(bcp,flag) forces a basic code point to lowercase if flag is zero,
// uppercase if flag is nonzero, and returns the resulting code point.
// The code point is unchanged if it is caseless.
// The behavior is undefined if bcp is not a basic code point.
function encode_basic(bcp, flag) {
bcp -= (bcp - 97 < 26) << 5;
return bcp + ((!flag && (bcp - 65 < 26)) << 5);
}
// Main decode
this.decode=function(input,preserveCase) {
// Dont use utf16
var output=[];
var case_flags=[];
var input_length = input.length;
var n, out, i, bias, basic, j, ic, oldi, w, k, digit, t, len;
// Initialize the state:
n = initial_n;
i = 0;
bias = initial_bias;
// Handle the basic code points: Let basic be the number of input code
// points before the last delimiter, or 0 if there is none, then
// copy the first basic code points to the output.
basic = input.lastIndexOf(delimiter);
if (basic < 0) basic = 0;
for (j = 0; j < basic; ++j) {
if(preserveCase) case_flags[output.length] = ( input.charCodeAt(j) -65 < 26);
if ( input.charCodeAt(j) >= 0x80) {
throw new RangeError("Illegal input >= 0x80");
}
output.push( input.charCodeAt(j) );
}
// Main decoding loop: Start just after the last delimiter if any
// basic code points were copied; start at the beginning otherwise.
for (ic = basic > 0 ? basic + 1 : 0; ic < input_length; ) {
// ic is the index of the next character to be consumed,
// Decode a generalized variable-length integer into delta,
// which gets added to i. The overflow checking is easier
// if we increase i as we go, then subtract off its starting
// value at the end to obtain delta.
for (oldi = i, w = 1, k = base; ; k += base) {
if (ic >= input_length) {
throw RangeError ("punycode_bad_input(1)");
}
digit = decode_digit(input.charCodeAt(ic++));
if (digit >= base) {
throw RangeError("punycode_bad_input(2)");
}
if (digit > Math.floor((maxint - i) / w)) {
throw RangeError ("punycode_overflow(1)");
}
i += digit * w;
t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
if (digit < t) { break; }
if (w > Math.floor(maxint / (base - t))) {
throw RangeError("punycode_overflow(2)");
}
w *= (base - t);
}
out = output.length + 1;
bias = adapt(i - oldi, out, oldi === 0);
// i was supposed to wrap around from out to 0,
// incrementing n each time, so we'll fix that now:
if ( Math.floor(i / out) > maxint - n) {
throw RangeError("punycode_overflow(3)");
}
n += Math.floor( i / out ) ;
i %= out;
// Insert n at position i of the output:
// Case of last character determines uppercase flag:
if (preserveCase) { case_flags.splice(i, 0, input.charCodeAt(ic -1) -65 < 26);}
output.splice(i, 0, n);
i++;
}
if (preserveCase) {
for (i = 0, len = output.length; i < len; i++) {
if (case_flags[i]) {
output[i] = (String.fromCharCode(output[i]).toUpperCase()).charCodeAt(0);
}
}
}
return this.utf16.encode(output);
};
//** Main encode function **
this.encode = function (input,preserveCase) {
//** Bias adaptation function **
var n, delta, h, b, bias, j, m, q, k, t, ijv, case_flags;
if (preserveCase) {
// Preserve case, step1 of 2: Get a list of the unaltered string
case_flags = this.utf16.decode(input);
}
// Converts the input in UTF-16 to Unicode
input = this.utf16.decode(input.toLowerCase());
var input_length = input.length; // Cache the length
if (preserveCase) {
// Preserve case, step2 of 2: Modify the list to true/false
for (j=0; j < input_length; j++) {
case_flags[j] = input[j] != case_flags[j];
}
}
var output=[];
// Initialize the state:
n = initial_n;
delta = 0;
bias = initial_bias;
// Handle the basic code points:
for (j = 0; j < input_length; ++j) {
if ( input[j] < 0x80) {
output.push(
String.fromCharCode(
case_flags ? encode_basic(input[j], case_flags[j]) : input[j]
)
);
}
}
h = b = output.length;
// h is the number of code points that have been handled, b is the
// number of basic code points
if (b > 0) output.push(delimiter);
// Main encoding loop:
//
while (h < input_length) {
// All non-basic code points < n have been
// handled already. Find the next larger one:
for (m = maxint, j = 0; j < input_length; ++j) {
ijv = input[j];
if (ijv >= n && ijv < m) m = ijv;
}
// Increase delta enough to advance the decoder's
// <n,i> state to <m,0>, but guard against overflow:
if (m - n > Math.floor((maxint - delta) / (h + 1))) {
throw RangeError("punycode_overflow (1)");
}
delta += (m - n) * (h + 1);
n = m;
for (j = 0; j < input_length; ++j) {
ijv = input[j];
if (ijv < n ) {
if (++delta > maxint) return Error("punycode_overflow(2)");
}
if (ijv == n) {
// Represent delta as a generalized variable-length integer:
for (q = delta, k = base; ; k += base) {
t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
if (q < t) break;
output.push( String.fromCharCode(encode_digit(t + (q - t) % (base - t), 0)) );
q = Math.floor( (q - t) / (base - t) );
}
output.push( String.fromCharCode(encode_digit(q, preserveCase && case_flags[j] ? 1:0 )));
bias = adapt(delta, h + 1, h == b);
delta = 0;
++h;
}
}
++delta, ++n;
}
return output.join("");
}
this.ToASCII = function ( domain ) {
var domain_array = domain.split(".");
var out = [];
for (var i=0; i < domain_array.length; ++i) {
var s = domain_array[i];
out.push(
s.match(/[^A-Za-z0-9-]/) ?
"xn--" + punycode.encode(s) :
s
);
}
return out.join(".");
}
this.ToUnicode = function ( domain ) {
var domain_array = domain.split(".");
var out = [];
for (var i=0; i < domain_array.length; ++i) {
var s = domain_array[i];
out.push(
s.match(/^xn--/) ?
punycode.decode(s.slice(4)) :
s
);
}
return out.join(".");
}
}();
domains = domains.split(',');
for (var i = 0, n = domains.length; i < n; i++) {
parsed.push(punycode.ToASCII(String(java.lang.String(domains[i]).trim())));
}
return { result: 0, domains: parsed }

View File

@ -0,0 +1,82 @@
jpsType: update
id: wordpress-core-installation
name: WordPress Core Installation
description: WordPress Core Installation
mixins:
- https://raw.githubusercontent.com/jelastic-jps/wordpress/master/configs/vers.yaml
globals:
WP_ADMIN_PASS: ${settings.wp_admin_pass}
WP_TITLE: ${settings.wp_title}
DB_HOST: ${settings.db_host}
DB_NAME: wp_${fn.random}
DB_USER: ${settings.db_user}
DB_PASS: ${settings.db_pass}
REDIS_HOST: ${settings.redis_host:}
REDIS_PORT: ${settings.redis_port:}
REDIS_USER: ${settings.redis_user:}
REDIS_PSWD: ${settings.redis_pswd:}
WP_URL: ${settings.wp_url}
CLUSTER: ${settings.cluster:true}
onInstall:
- deployWordPress
- installScripts
- installWordPress
- setupWordPress
- installPlugins
- setupPlugins
actions:
deployWordPress:
- cmd[${nodes.cp.master.id}]: |-
#wget -qO /tmp/wordpress.tar.gz 'https://wordpress.org/wordpress-${globals.version_wordpress}.tar.gz';
wget -qO /tmp/wordpress.tar.gz 'https://wordpress.org/latest.tar.gz';
[ -d /tmp/wordpress/ ] && rm -rf /tmp/wordpress;
tar -xzf /tmp/wordpress.tar.gz -C /tmp/;
rsync -a /tmp/wordpress/* /var/www/webroot/ROOT/;
rsync -a --checksum /tmp/wordpress/* /var/www/webroot/ROOT/;
- addContext [cp]:
name: ROOT
fileName: WordPress
type: ARCHIVE
installWordPress:
cmd[${nodes.cp.master.id}]: |-
mysql -u${globals.DB_USER} -p${globals.DB_PASS} -h ${nodes.sqldb.master.intIP} -e "CREATE DATABASE IF NOT EXISTS ${globals.DB_NAME};"
cd /var/www/webroot/ROOT && wp core config --dbhost=${nodes.sqldb.master.intIP} --dbname=${globals.DB_NAME} --dbuser=${globals.DB_USER} --dbpass=${globals.DB_PASS} --path=/var/www/webroot/ROOT;
cd /var/www/webroot/ROOT && wp core install --title="${globals.WP_TITLE}" --admin_user=${user.email} --admin_password=${globals.WP_ADMIN_PASS} --url=${globals.WP_URL} --admin_email=${user.email} --skip-email --path=/var/www/webroot/ROOT;
mv /var/www/webroot/ROOT/wp-config.php /tmp; sed -i "s/${nodes.sqldb.master.intIP}/${globals.DB_HOST}/g" /tmp/wp-config.php; mv /tmp/wp-config.php /var/www/webroot/ROOT;
wget ${baseUrl}../images/favicon.ico -O /var/www/webroot/ROOT/favicon.ico;
- if ('${globals.CLUSTER}' == 'true'):
installScripts:
- cmd[cp]: |-
[ ! -d $HOME/bin ] && mkdir $HOME/bin;
curl -o $HOME/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x $HOME/bin/wp;
echo "apache_modules:" > ~/bin/wp-cli.yml;
echo " - mod_rewrite" >> ~/bin/wp-cli.yml;
echo "export PATH=$PATH:$HOME/bin/" >> $HOME/.bash_profile;
wget ${baseUrl}/setupWP.sh?_r=${fn.random} -O ~/bin/setupWP.sh &>> /var/log/run.log;
echo $HOME/bin;
- cmd[cp]:
echo ${response.out} >> /etc/jelastic/redeploy.conf;
yum install jq -y &>> /var/log/run.log;
user: root
setupWordPress:
- cmd[${nodes.cp.master.id}]: |-
grep -qE "(WP_AUTO_UPDATE_CORE)" /var/www/webroot/ROOT/wp-config.php || sed -i "/^\$table_prefix.*/a define( 'WP_AUTO_UPDATE_CORE', false );" /var/www/webroot/ROOT/wp-config.php;
cd ~/bin/ && wp option update permalink_structure '/%postname%/' --path=/var/www/webroot/ROOT;
cd ~/bin/ && wp rewrite structure '/%postname%/' --hard --path=/var/www/webroot/ROOT;
installPlugins:
- if (/llsmp/.test("${nodes.cp.nodeType}") || /litespeed/.test("${nodes.cp.nodeType}")):
cmd[${nodes.cp.master.id}]: |-
wp plugin install litespeed-cache --version=${globals.version_lscache} --activate --path=/var/www/webroot/ROOT &>> /var/log/run.log;
wp cache flush --path=/var/www/webroot/ROOT &>> /var/log/run.log;
setupPlugins:
- cmd[${nodes.cp.master.id}]: |-
bash ~/bin/setupWP.sh --pgcache true --objectcache true --REDIS_HOST ${globals.REDIS_HOST} --REDIS_PORT ${globals.REDIS_PORT} --REDIS_USER ${globals.REDIS_USER} --REDIS_PSWD ${globals.REDIS_PSWD};

View File

@ -0,0 +1,158 @@
import com.hivext.api.Response;
import org.yaml.snakeyaml.Yaml;
import com.hivext.api.core.utils.Transport;
var cdnAppid = "c05ffa5b45628a2a0c95467ebca8a0b4";
var lsAppid = "9e6afcf310004ac84060f90ff41a5aba";
var group = jelastic.billing.account.GetAccount(appid, session);
var isCDN = jelastic.dev.apps.GetApp(cdnAppid);
var isLS = jelastic.dev.apps.GetApp(lsAppid);
//checking quotas
var perEnv = "environment.maxnodescount",
maxEnvs = "environment.maxcount",
perNodeGroup = "environment.maxsamenodescount",
maxCloudletsPerRec = "environment.maxcloudletsperrec";
var nodesPerEnvWO_Bl = 9,
nodesPerEnvWO_GlusterFS = 7,
nodesPerEnvMin = 6,
nodesPerGroupMin = 2,
maxCloudlets = 16,
markup = "", cur = null, text = "used", prod = true;
var settings = jps.settings;
var fields = {};
for (var i = 0, field; field = jps.settings.fields[i]; i++)
fields[field.name] = field;
var quotas = jelastic.billing.account.GetQuotas(perEnv + ";"+maxEnvs+";" + perNodeGroup + ";" + maxCloudletsPerRec ).array;
var group = jelastic.billing.account.GetAccount(appid, session);
for (var i = 0; i < quotas.length; i++){
var q = quotas[i], n = toNative(q.quota.name);
if (n == maxCloudletsPerRec && maxCloudlets > q.value){
err(q, "required", maxCloudlets, true);
prod = false;
}
if (n == perEnv && nodesPerEnvMin > q.value){
if (!markup) err(q, "required", nodesPerEnvMin, true);
prod = false;
}
if (n == perNodeGroup && nodesPerGroupMin > q.value){
if (!markup) err(q, "required", nodesPerGroupMin, true);
prod = false;
}
if (n == perEnv && nodesPerEnvMin == q.value){
fields["glusterfs"].value = false;
fields["glusterfs"].disabled = true;
fields["galera"].value = false;
fields["galera"].disabled = true;
fields["bl_count"].value = 1;
fields["displayfield"].markup = "Some advanced features are not available. Please upgrade your account.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
}
if (n == perEnv && nodesPerEnvWO_GlusterFS == q.value){
fields["glusterfs"].value = false;
fields["glusterfs"].disabled = true;
fields["bl_count"].value = 1;
fields["displayfield"].markup = "Some advanced features are not available. Please upgrade your account.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
}
if (n == perEnv && q.value == 8){
fields["glusterfs"].value = false;
fields["glusterfs"].disabled = true;
fields["bl_count"].value = 2;
fields["displayfield"].markup = "Some advanced features are not available. Please upgrade your account.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
}
if (n == perEnv && nodesPerEnvWO_Bl == q.value){
fields["bl_count"].value = 1;
}
if (n == perNodeGroup && nodesPerGroupMin == q.value){
fields["glusterfs"].value = false;
fields["glusterfs"].disabled = true;
fields["galera"].value = false;
fields["galera"].disabled = true;
fields["displayfield"].markup = "Some advanced features are not available. Please upgrade your account.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
}
if (isLS.result == 0 || isLS.result == Response.PERMISSION_DENIED) {
fields["ls-addon"].hidden = false;
fields["ls-addon"].value = true;
} else {
fields["ls-addon"].hidden = true;
fields["ls-addon"].value = false;
fields["ls-addon"].showIf = null;
}
if (isCDN.result == 0 || isCDN.result == Response.PERMISSION_DENIED) {
fields["cdn-addon"].hidden = false;
fields["cdn-addon"].value = true;
} else {
fields["cdn-addon"].hidden = true;
fields["cdn-addon"].value = false;
}
var extIP = jelastic.billing.account.GetQuotas('environment.externalip.enabled');
var extIPperEnv = jelastic.billing.account.GetQuotas('environment.externalip.maxcount');
var extIPperNode = jelastic.billing.account.GetQuotas('environment.externalip.maxcount.per.node');
if ((extIP.result == 0 && extIP.array[0].value) && (extIPperEnv.result == 0 && extIPperEnv.array[0].value >= 2) && (extIPperNode.result == 0 && extIPperNode.array[0].value >= 1)) {
fields["le-addon"].disabled = false;
fields["le-addon"].value = true;
}
}
if (!prod) {
fields["ls-addon"].disabled = true;
fields["ls-addon"].value = false;
fields["loadGrowth"].disabled = true;
fields["galera"].disabled = true;
fields["galera"].value = false;
fields["glusterfs"].disabled = true;
fields["glusterfs"].value = false;
fields["le-addon"].disabled = true;
fields["le-addon"].value = false;
fields["cdn-addon"].disabled = true;
fields["cdn-addon"].value = false;
fields["mu-addon"].disabled = true;
fields["displayfield"].markup = "Advanced features are not available.";
fields["displayfield"].cls = "warning";
fields["displayfield"].hideLabel = true;
fields["displayfield"].height = 25;
fields["bl_count"].markup = "WordPress cluster is not available. " + markup + "Please upgrade your account.";
fields["bl_count"].cls = "warning";
fields["bl_count"].hidden = false;
fields["bl_count"].height = 30;
settings.fields.push(
{"type": "compositefield","height": 0,"hideLabel": true,"width": 0,"items": [{"height": 0,"type": "string","required": true}]}
);
}
return {
result: 0,
settings: settings
};
function err(e, text, cur, override){
var m = (e.quota.description || e.quota.name) + " - " + e.value + ", " + text + " - " + cur + ". ";
if (override) markup = m; else markup += m;
}

View File

@ -0,0 +1,9 @@
type: update
id: setup-wordpress-domain
name: Setup WordPress Domain
globals:
DOMAIN: ${settings.domain}
onInstall:
- cmd[${nodes.cp.master.id}]: bash ~/bin/setupWP.sh --domain ${globals.DOMAIN}

View File

@ -0,0 +1,57 @@
jpsType: update
name: Setup HA for Load Balancer
id: setup-ha4lb
onInstall:
- if ('${nodes.bl.master.nodeType}' == 'litespeedadc' && nodes.bl.length > 1):
- script[bl]: firewallRules.js?_r=${fn.random}
ports: '1447'
name: LSADC-HA
- resetReplClusters
- forEach(i:nodes.bl):
- setupInstance:
id: "${@i.id}"
ip: "${@i.address}"
- setupReplClusters
- restartNodesInOrder
- cacheClean
- if ('${nodes.bl.master.nodeType}' == 'litespeedadc' && nodes.bl.length == 1): resetReplClusters
actions:
resetReplClusters:
cmd[bl]: |-
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > /var/www/conf/ha_config.xml;
echo "<haConfig/>" >> /var/www/conf/ha_config.xml;
setupReplClusters:
script:
- var resp = jelastic.env.control.GetEnvInfo('${env.envName}', session);
- if (resp.result != 0) return resp;
- var nodes = [];
- for (var i = 0, n = resp.nodes; i < n.length; i++)
- " n[i].nodeGroup == nodeGroup ? nodes.push(n[i].address + ':1447') : 0"
- 'resp = {result:0, onAfterReturn: {}};'
- resp.onAfterReturn['cmd['+ nodeGroup +']'] = '/usr/bin/xmlstarlet ed --inplace -s "haConfig/replication" -t elem -n "replCluster"
-v "'+ nodes.join(',') +'" "/var/www/conf/ha_config.xml" 2>/dev/null;'
- return resp;
nodeGroup: bl
setupInstance:
cmd[${this.id}]: |-
/usr/bin/xmlstarlet ed --inplace -s "haConfig" -t elem -n "replication" "/var/www/conf/ha_config.xml" 2>/dev/null;
/usr/bin/xmlstarlet ed --inplace -s "haConfig/replication" -t elem -n "serverAddr" -v "${this.ip}:1447" "/var/www/conf/ha_config.xml" 2>/dev/null;
/usr/bin/xmlstarlet ed --inplace -s "haConfig/replication" -t elem -n "isFileCached" -v "1" "/var/www/conf/ha_config.xml" 2>/dev/null;
restartNodesInOrder:
- forEach(i:nodes.bl):
- cmd[${@i.id}]: |-
pkill -9 lslbd;
jem service restart;
user: root
cacheClean:
cmd[bl]: |-
[ -d /tmp/lscache/vhosts/Jelastic/ ] && rm -rf /tmp/lscache/vhosts/Jelastic/* &>> /var/log/run.log;

314
scripts/setupWP.sh 100755
View File

@ -0,0 +1,314 @@
#!/bin/bash -e
purge=false;
pgcache=false;
objectcache=false;
edgeportCDN=false;
multisite=false;
domain=false;
url=false;
woocommerce=false;
SERVER_WEBROOT=/var/www/webroot/ROOT
ARGUMENT_LIST=(
"purge"
"pgcache"
"objectcache"
"edgeportCDN"
"multisite"
"REDIS_HOST"
"REDIS_PORT"
"REDIS_USER"
"REDIS_PSWD"
"CDN_URL"
"CDN_ORI"
"mode"
"url"
"domain"
"ENV_NAME"
"woocommerce"
)
WP=`which wp`
# read arguments
opts=$(getopt \
--longoptions "$(printf "%s:," "${ARGUMENT_LIST[@]}")" \
--name "$(basename "$0")" \
--options "" \
-- "$@"
)
eval set --$opts
while [[ $# -gt 0 ]]; do
case "$1" in
--purge)
purge=$2
shift 2
;;
--pgcache)
pgcache=$2
shift 2
;;
--objectcache)
objectcache=$2
shift 2
;;
--edgeportCDN)
edgeportCDN=$2
shift 2
;;
--REDIS_HOST)
REDIS_HOST=$2
shift 2
;;
--REDIS_PORT)
REDIS_PORT=$2
shift 2
;;
--REDIS_USER)
REDIS_USER=$2
shift 2
;;
--REDIS_PSWD)
REDIS_PSWD=$2
shift 2
;;
--CDN_URL)
CDN_URL=$2
shift 2
;;
--CDN_ORI)
CDN_ORI=$2
shift 2
;;
--multisite)
multisite=$2
shift 2
;;
--mode)
mode=$2
shift 2
;;
--url)
url=$2
shift 2
;;
--domain)
domain=$2
shift 2
;;
--ENV_NAME)
ENV_NAME=$2
shift 2
;;
--woocommerce)
woocommerce=$2
shift 2
;;
*)
break
;;
esac
done
W3TC_OPTION_SET="${WP} w3-total-cache option set"
LSCWP_OPTION_SET="${WP} litespeed-option set"
lOG="/var/log/run.log"
COMPUTE_TYPE=$(grep "COMPUTE_TYPE=" /etc/jelastic/metainf.conf | cut -d"=" -f2)
cd ${SERVER_WEBROOT};
if [[ ${COMPUTE_TYPE} == *"llsmp"* || ${COMPUTE_TYPE} == *"litespeed"* ]] ; then
CACHE_FLUSH="${WP} litespeed-purge all --path=${SERVER_WEBROOT}; rm -rf /var/www/webroot/.cache/vhosts/Jelastic/* "
WPCACHE='lscwp';
elif [[ ${COMPUTE_TYPE} == *"lemp"* || ${COMPUTE_TYPE} == *"nginx"* ]] ; then
CACHE_FLUSH="${WP} w3-total-cache flush all --path=${SERVER_WEBROOT}; /var/www/webroot/.cache/* "
WPCACHE="w3tc";
else
echo 'Compute type is not defined';
exit;
fi
function generateCdnContent () {
echo "wp-content/themes/twentytwentytwo/style.css" > ~/checkCdnContent.txt;
echo "wp-includes/css/dist/block-library/style.min.css" >> ~/checkCdnContent.txt;
echo "wp-includes/css/dist/block-library/theme.min.css" >> ~/checkCdnContent.txt;
echo "wp-includes/js/wp-embed.min.js" >> ~/checkCdnContent.txt;
}
function checkCdnStatus () {
if [ $WPCACHE == 'w3tc' ] ; then
CDN_ENABLE_CMD="${WP} w3-total-cache option set cdn.enabled true --type=boolean"
elif [ $WPCACHE == 'lscwp' ] ; then
CDN_ENABLE_CMD="${WP} litespeed-option set cdn true"
fi
cat > ~/checkCdnStatus.sh <<EOF
#!/bin/bash
while read -ru 4 CONTENT; do
status=\$(curl \$1\$CONTENT -k -s -f -o /dev/null && echo "SUCCESS" || echo "ERROR")
if [ \$status = "SUCCESS" ]
then
continue
else
exit
fi
done 4< ~/checkCdnContent.txt
cd ${SERVER_WEBROOT}
${CDN_ENABLE_CMD} --path=${SERVER_WEBROOT} &>> /var/log/run.log
${CACHE_FLUSH} &>> /var/log/run.log
${WP} cache flush --path=${SERVER_WEBROOT} &>> /var/log/run.log
crontab -l | sed "/checkCdnStatus/d" | crontab -
EOF
chmod +x ~/checkCdnStatus.sh
PROTOCOL=$(${WP} option get siteurl --path=${SERVER_WEBROOT} | cut -d':' -f1)
crontab -l | { cat; echo "* * * * * /bin/bash ~/checkCdnStatus.sh ${PROTOCOL}://${CDN_URL}/"; } | crontab
}
if [ $purge == 'true' ] ; then
${CACHE_FLUSH} &>> /var/log/run.log
${WP} cache flush --path=${SERVER_WEBROOT} &>> /var/log/run.log
[ -d /tmp/lscache/vhosts/ ] && /usr/bin/rm -rf /tmp/lscache/vhosts/Jelastic/* &>> /var/log/run.log
fi
if [ $pgcache == 'true' ] ; then
case $WPCACHE in
w3tc)
$W3TC_OPTION_SET pgcache.enabled true --type=boolean --path=${SERVER_WEBROOT} &>> $lOG
$W3TC_OPTION_SET pgcache.file.nfs true --type=boolean --path=${SERVER_WEBROOT} &>> $lOG
;;
lscwp)
;;
esac
fi
if [ $objectcache == 'true' ] ; then
case $WPCACHE in
w3tc)
$W3TC_OPTION_SET objectcache.enabled true --type=boolean --path=${SERVER_WEBROOT} &>> /var/log/run.log
$W3TC_OPTION_SET objectcache.engine redis --path=${SERVER_WEBROOT} &>> /var/log/run.log
$W3TC_OPTION_SET objectcache.redis.servers ${REDIS_HOST}:${REDIS_PORT} --path=${SERVER_WEBROOT} &>> /var/log/run.log
$W3TC_OPTION_SET objectcache.redis.password ${REDIS_PSWD} --path=${SERVER_WEBROOT} &>> /var/log/run.log
;;
lscwp)
$LSCWP_OPTION_SET object true --path=${SERVER_WEBROOT} &>> /var/log/run.log;
$LSCWP_OPTION_SET object-kind 1 --path=${SERVER_WEBROOT} &>> /var/log/run.log;
$LSCWP_OPTION_SET object-host '' --path=${SERVER_WEBROOT} &>> /var/log/run.log;
[[ ! -z "${REDIS_HOST}" ]] && $LSCWP_OPTION_SET object-host ${REDIS_HOST} --path=${SERVER_WEBROOT} &>> /var/log/run.log;
$LSCWP_OPTION_SET object-port '' --path=${SERVER_WEBROOT} &>> /var/log/run.log;
[[ ! -z "${REDIS_PORT}" ]] && $LSCWP_OPTION_SET object-port ${REDIS_PORT} --path=${SERVER_WEBROOT} &>> /var/log/run.log;
$LSCWP_OPTION_SET object-user '' --path=${SERVER_WEBROOT} &>> /var/log/run.log;
[[ ! -z "${REDIS_USER}" ]] && $LSCWP_OPTION_SET object-user ${REDIS_USER} --path=${SERVER_WEBROOT} &>> /var/log/run.log;
$LSCWP_OPTION_SET object-pswd '' --path=${SERVER_WEBROOT} &>> /var/log/run.log;
[[ ! -z "${REDIS_PSWD}" ]] && $LSCWP_OPTION_SET object-pswd ${REDIS_PSWD} --path=${SERVER_WEBROOT} &>> /var/log/run.log;
;;
esac
fi
if [ $edgeportCDN == 'true' ] ; then
if ! $(${WP} core is-installed --network --path=${SERVER_WEBROOT}); then
case $WPCACHE in
w3tc)
generateCdnContent;
checkCdnStatus;
$W3TC_OPTION_SET cdn.enabled false --type=boolean --path=${SERVER_WEBROOT} &>> /var/log/run.log
$W3TC_OPTION_SET cdn.engine mirror --path=${SERVER_WEBROOT} &>> /var/log/run.log
$W3TC_OPTION_SET cdn.mirror.domain ${CDN_URL} --path=${SERVER_WEBROOT} &>> /var/log/run.log
;;
lscwp)
generateCdnContent;
checkCdnStatus;
CDN_ORI=$(${WP} option get siteurl --path=${SERVER_WEBROOT} | cut -d'/' -f3)
PROTOCOL=$(${WP} option get siteurl --path=${SERVER_WEBROOT} | cut -d':' -f1)
$LSCWP_OPTION_SET cdn false --path=${SERVER_WEBROOT} &>> /var/log/run.log
$LSCWP_OPTION_SET cdn-mapping[url][0] ${PROTOCOL}://${CDN_URL}/ --path=${SERVER_WEBROOT} &>> /var/log/run.log
$LSCWP_OPTION_SET cdn-ori "//${CDN_ORI}/" --path=${SERVER_WEBROOT} &>> /var/log/run.log
;;
esac
fi
fi
if [ $multisite == 'true' ] ; then
cd ~/bin/ && ${WP} option update permalink_structure '' --path=/var/www/webroot/ROOT/ &>> /var/log/run.log;
cd ~/bin/ && ${WP} rewrite structure '' --hard --path=/var/www/webroot/ROOT/ &>> /var/log/run.log;
${WP} cache flush --path=${SERVER_WEBROOT};
case $WPCACHE in
w3tc)
${WP} plugin deactivate w3-total-cache --path=${SERVER_WEBROOT} &>> /var/log/run.log;
[[ ${mode} == 'subdir' ]] && ${WP} core multisite-convert --path=${SERVER_WEBROOT} &>> /var/log/run.log;
[[ ${mode} == 'subdom' ]] && ${WP} core multisite-convert --path=${SERVER_WEBROOT} --subdomains &>> /var/log/run.log;
${WP} plugin activate w3-total-cache --path=${SERVER_WEBROOT} &>> /var/log/run.log;
;;
lscwp)
${WP} plugin deactivate litespeed-cache --path=${SERVER_WEBROOT} &>> /var/log/run.log;
[[ ${mode} == 'subdir' ]] && ${WP} core multisite-convert --path=${SERVER_WEBROOT} &>> /var/log/run.log;
[[ ${mode} == 'subdom' ]] && ${WP} core multisite-convert --path=${SERVER_WEBROOT} --subdomains &>> /var/log/run.log;
${WP} plugin activate litespeed-cache --network --path=${SERVER_WEBROOT} &>> /var/log/run.log;
${WP} cache flush --path=${SERVER_WEBROOT};
echo "Configuring litespeed.conf.cache" >> /var/log/run.log;
${WP} db query "UPDATE wp_sitemeta set meta_value = 1 where meta_key = 'litespeed.conf.cache'" --path=${SERVER_WEBROOT} &>> /var/log/run.log;
${WP} db query "select meta_value from wp_sitemeta where meta_key = 'litespeed.conf.cache'" --path=${SERVER_WEBROOT} &>> /var/log/run.log;
echo "Configuring litespeed.conf.object" >> /var/log/run.log;
${WP} db query "UPDATE wp_sitemeta set meta_value = 1 where meta_key = 'litespeed.conf.object'" --path=${SERVER_WEBROOT} &>> /var/log/run.log;
echo "Configuring litespeed.conf.object-kind" >> /var/log/run.log;
${WP} db query "UPDATE wp_sitemeta set meta_value = 1 where meta_key = 'litespeed.conf.object-kind'" --path=${SERVER_WEBROOT} &>> /var/log/run.log;
echo "Configuring litespeed.conf.object-host" >> /var/log/run.log;
${WP} db query "UPDATE wp_sitemeta set meta_value = '/var/run/redis/redis.sock' where meta_key = 'litespeed.conf.object-host'" --path=${SERVER_WEBROOT} &>> /var/log/run.log;
echo "Configuring litespeed.conf.object-port" >> /var/log/run.log;
${WP} db query "UPDATE wp_sitemeta set meta_value = 0 where meta_key = 'litespeed.conf.object-port'" --path=${SERVER_WEBROOT} &>> /var/log/run.log;
;;
esac
${WP} cache flush --path=${SERVER_WEBROOT};
fi
if [ $url != 'false' ] ; then
if ! $(${WP} core is-installed --network --path=${SERVER_WEBROOT}); then
old_url=$(${WP} option get siteurl --path=${SERVER_WEBROOT})
old_domain=$(${WP} option get siteurl --path=${SERVER_WEBROOT} | cut -d'/' -f3)
new_domain=$(echo $url | cut -d'/' -f3)
${WP} search-replace "${old_url}" "${url}" --skip-columns=guid --all-tables --path=${SERVER_WEBROOT} &>> /var/log/run.log
${WP} search-replace "${old_domain}" "${new_domain}" --skip-columns=guid --all-tables --path=${SERVER_WEBROOT} &>> /var/log/run.log
${CACHE_FLUSH} &>> /var/log/run.log
${WP} cache flush --path=${SERVER_WEBROOT} &>> /var/log/run.log
fi
fi
if [ $domain != 'false' ] ; then
old_domain=$(${WP} option get siteurl --path=${SERVER_WEBROOT} | cut -d'/' -f3)
${WP} search-replace "${old_domain}" "${domain}" --skip-columns=guid --all-tables --path=${SERVER_WEBROOT} &>> /var/log/run.log
${CACHE_FLUSH} &>> /var/log/run.log
${WP} cache flush --path=${SERVER_WEBROOT} &>> /var/log/run.log
if $(${WP} core is-installed --network --path=${SERVER_WEBROOT}); then
${WP} config set DOMAIN_CURRENT_SITE ${domain} --path=${SERVER_WEBROOT}
fi
fi
if [ $woocommerce == 'true' ] ; then
${WP} plugin install woocommerce --activate --path=${SERVER_WEBROOT} &>> /var/log/run.log
fi

View File

@ -0,0 +1,52 @@
var SCALE = "scale-",
DOWN = "down",
UP = "up",
scaleUp = SCALE + UP,
scaleDown = SCALE + DOWN,
addNode = "ADD_NODE",
removeNode = "REMOVE_NODE",
count = getParam('count'),
ENV_NAME = "${env.name}",
triggersToEdit = [],
triggerActions,
customData,
triggers,
upLimit,
resp;
resp = jelastic.environment.trigger.GetTriggers(ENV_NAME, session, addNode + ";" + removeNode);
if (resp.result != 0) return resp;
triggers = resp.array;
for (var i = 0, n = triggers.length; i < n; i++) {
if ([scaleUp, scaleDown].indexOf(String(triggers[i].name)) != -1) {
triggerActions = triggers[i].actions;
for (var l = 0, m = triggerActions.length; l < m; l++) {
customData = triggerActions[l].customData;
if (triggers[i].name == scaleUp) upLimit = customData.limit;
if ((triggerActions[l].type == addNode && customData.limit < count) || triggerActions[l].type == removeNode) {
triggers[i].actions[l].customData.limit = count;
triggersToEdit.push({
scale: triggers[i].name.indexOf(UP) != -1 ? UP : DOWN,
trigger: triggers[i]
});
}
}
}
}
for (var i = 0, n = triggersToEdit.length; i < n; i++) {
trigger = triggersToEdit[i].trigger;
if (triggersToEdit[i].scale == DOWN && trigger.actions[0].customData.limit >= upLimit) trigger.actions[0].customData.limit = upLimit - 1;
resp = jelastic.environment.trigger.EditTrigger(ENV_NAME, session, trigger.id, trigger);
if (resp.result != 0) return resp;
}
return {result: 0};

View File

@ -0,0 +1,30 @@
**WordPress environment**: [${globals.PROTOCOL}://${env.domain}/](${globals.PROTOCOL}://${env.domain}/)
Use the following credentials to access the admin panel:
**Admin Panel**: [${globals.PROTOCOL}://${env.domain}/wp-admin/](${globals.PROTOCOL}://${env.domain}/wp-admin/)
**Login**: ${user.email}
**Password**: ${globals.WP_ADMIN_PASS}
Use the following credentials to access the LiteSpeed ADC admin console:
**Admin Console**: [https://node${nodes.bl.master.id}-${env.domain}:4848](https://node${nodes.bl.master.id}-${env.domain}:4848)
**Login**: admin
**Password**: ${globals.LS_ADMIN_PASS}
**Note:** Every time when you need to make settings customization you should apply it to all the load balancer nodes via their admin panels. To access every load balancer admin panel use the same URL and just substitute the ${nodeId} value with respective one for every load balancer node.
Use the following credentials to access the LiteSpeed WEB Server admin console:
**Admin Console**: [https://node${nodes.cp.master.id}-${env.domain}:4848](https://node${nodes.cp.master.id}-${env.domain}:4848)
**Login**: admin
**Password**: ${globals.LS_ADMIN_PASS}
**Note:** Every time when you need to make settings customization you should apply it to all the web server nodes via their admin panels. To access every web server admin panel use the same URL and just substitute the ${nodeId} value with respective one for every web server node.
Manage the database nodes using the next credentials:
**phpMyAdmin Panel**: [https://node${nodes.sqldb.master.id}-${env.domain}/](https://node${nodes.sqldb.master.id}-${env.domain}/)
**Username**: ${globals.DB_USER}
**Password**: ${globals.DB_PASS}

View File

@ -0,0 +1,17 @@
**WordPress environment**: [${globals.PROTOCOL}://${env.domain}/](${globals.PROTOCOL}://${env.domain}/)
Use the following credentials to access the admin panel:
**Admin Panel**: [${globals.PROTOCOL}://${env.domain}/wp-admin/](${globals.PROTOCOL}://${env.domain}/wp-admin/)
**Login**: ${user.email}
**Password**: ${globals.WP_ADMIN_PASS}
The instructions below can help you with further managing your WordPress:
* [Bind custom domain](https://docs.jelastic.com/custom-domain-via-cname)
* [Share access to the environment](http://docs.jelastic.com/share-environment)
* [Adjust automatic vertical scaling settings](http://docs.jelastic.com/automatic-vertical-scaling)
* [Configure automatic horizontal scaling](http://docs.jelastic.com/automatic-horizontal-scaling)
* [Monitor the statistics](http://docs.jelastic.com/view-app-statistics) & [view log files](https://docs.jelastic.com/view-log-files)
* [Attach Public IP](https://docs.jelastic.com/public-ip)
* [Access environment via SSH](https://docs.jelastic.com/ssh-access)