-
Notifications
You must be signed in to change notification settings - Fork 0
/
server_create
278 lines (220 loc) · 8.69 KB
/
server_create
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#!/bin/bash
# This script is used to setup a Parse-serer and a MongoDB database.
# Variables for new database (edit these as needed)
export MONGO_PASSWORD=""
export PARSE_APP_ID="fmd-md"
export PARSE_MASTER_KEY=""
export PARSE_PORT="4000"
export SERVER_IP=""
export MONGO_BIND_IP="0.0.0.0"
export MONGO_PORT="27017"
export CLASSES='["DatabasePruning", "Endpoints", "UserSession", "FollowUp"]'
# Variables for old database connection
export OLD_PARSE_APP_ID=""
export OLD_PARSE_PORT="4000"
export OLD_SERVER_IP=""
# Check for existing swap space and add if none exists
if free | awk '/Swap:/ {exit !$2}'; then
echo "Swap exists."
else
echo "No swap space detected. Adding swap space..."
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Make the swap file permanent by adding it to /etc/fstab
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
fi
# Set non-interactive frontend for automatic handling of all prompts
export DEBIAN_FRONTEND=noninteractive
# Update System and Install Necessary Packages
apt-get update && apt-get upgrade -y -o Dpkg::Options::="--force-confold"
apt-get install -y -o Dpkg::Options::="--force-confold" git npm gnupg curl
# MongoDB Installation
wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -
echo "deb [arch=amd64,arm64] http://repo.mongodb.org/apt/debian $(lsb_release -cs)/mongodb-org/7.0 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
apt-get update
apt-get install -y -o Dpkg::Options::="--force-confold" mongodb-org
# Start MongoDB and Configure Autostart
sudo systemctl start mongod
sudo systemctl enable mongod
# Non-blocking status check
if systemctl is-active --quiet mongod; then
echo "MongoDB is active and running."
else
echo "Failed to start MongoDB."
exit 1
fi
# MongoDB Configuration for Remote Connections and Security
cat > /etc/mongod.conf <<EOF
# Security settings
security:
authorization: enabled
# Network-related settings
net:
port: $MONGO_PORT
bindIp: $MONGO_BIND_IP
# Storage settings
storage:
dbPath: /var/lib/mongodb
# System log settings
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
EOF
# Ensure the MongoDB data and log directories exist and have the correct permissions
sudo mkdir -p /var/lib/mongodb
sudo mkdir -p /var/log/mongodb
sudo chown -R mongodb:mongodb /var/lib/mongodb
sudo chown -R mongodb:mongodb /var/log/mongodb
# Restart MongoDB to apply the new configuration
sudo systemctl restart mongod
# Check if MongoDB is ready before continuing
while ! echo 'exit' | mongosh --quiet; do
echo "Waiting for MongoDB to initialize..."
sleep 1
done
# Adding MongoDB Admin User
mongosh <<EOF
use admin
db.createUser({
user: 'admin',
pwd: '$MONGO_PASSWORD',
roles: [
{ role: 'userAdminAnyDatabase', db: 'admin' },
{ role: 'readWriteAnyDatabase', db: 'admin' },
{ role: 'dbAdminAnyDatabase', db: 'admin' }
]
})
EOF
# Adding FMD Database
mongosh <<EOF
use admin
db.auth('admin', '$MONGO_PASSWORD')
use FMD
db.createUser({
user: 'fmd_admin',
pwd: '$MONGO_PASSWORD',
roles: [
{ role: 'dbOwner', db: 'FMD' }
]
})
EOF
# PM2 Installation
npm install pm2 -g
# Install UFW and Allow Port for Parse Server
sudo apt install ufw
sudo ufw allow ssh
sudo ufw allow $PARSE_PORT
sudo ufw allow $MONGO_PORT
# Automatically respond with "yes" to the UFW enable prompt
echo "y" | sudo ufw enable
# Install Parse Server
npm install -g parse-server mongodb-runner
# Environment Variables for Parse Server
export PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION=true
# Start Parse Server with PM2
echo "Starting Parse Server with Master Key: $PARSE_MASTER_KEY"
pm2 start parse-server -- --appId $PARSE_APP_ID --masterKey $PARSE_MASTER_KEY --databaseURI mongodb://fmd_admin:$MONGO_PASSWORD@$SERVER_IP:$MONGO_PORT/FMD --port $PARSE_PORT --allowExpiredAuthDataToken true --encodeParseObjectInCloudFunction true
pm2 save
pm2 startup
# Ensure PM2 restarts on reboot
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u $(whoami) --hp $(echo $HOME)
# Ensure the Parse JavaScript SDK and Axios is installed
npm install parse
npm install axios
npm install winston
# Create migration script with logging
echo "Creating migration script..."
cat << 'EOF' > migrate_data.js
const Parse = require('parse/node');
const axios = require('axios');
const { createLogger, format, transports } = require('winston');
const logger = createLogger({
format: format.combine(
format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
format.printf(({ timestamp, level, message }) => `${timestamp} ${level.toUpperCase()}: ${message}`)
),
transports: [
new transports.File({ filename: 'dataMigration.log' })
]
});
Parse.initialize(process.env.PARSE_APP_ID, '', process.env.PARSE_MASTER_KEY);
Parse.serverURL = `http://${process.env.SERVER_IP}:${process.env.PARSE_PORT}/parse`;
async function migrateData(classes) {
for (const className of classes) {
logger.info(`Migrating class ${className}...`);
const oldParseURL = `http://${process.env.OLD_SERVER_IP}:${process.env.OLD_PARSE_PORT}/parse/classes/${className}`;
let skip = 0; // Track how many records have been fetched
const limit = 100; // Define the limit per request
let hasMoreData = true;
while (hasMoreData) {
logger.info(`Fetching data from: ${oldParseURL} with skip ${skip} and limit ${limit}`);
try {
const response = await axios.get(`${oldParseURL}?skip=${skip}&limit=${limit}`, {
headers: {
'X-Parse-Application-Id': process.env.OLD_PARSE_APP_ID,
},
});
if (response.data && response.data.results) {
const records = response.data.results;
for (const record of records) {
const NewClass = Parse.Object.extend(className);
const newObj = new NewClass();
for (const key in record) {
if (!["objectId", "className"].includes(key)) {
if (key === 'createdAt' || key === 'updatedAt') {
// Ensure the date is parsed correctly
const originalDate = record[key].iso ? new Date(record[key].iso) : new Date(record[key]);
const dateKey = 'original' + key.charAt(0).toUpperCase() + key.slice(1); // Creates 'originalCreatedAt' or 'originalUpdatedAt'
newObj.set(dateKey, originalDate);
} else {
newObj.set(key, record[key]);
}
}
}
// Set the original ID from old database
newObj.set('originalId', record.objectId);
try {
await newObj.save();
logger.info(`Migrated record with new ID ${newObj.id} for class ${className}.`);
} catch (error) {
logger.error(`Error saving record for class ${className}: ${error.message}`);
}
}
// Check if there are more records to fetch
if (records.length < limit) {
hasMoreData = false;
} else {
skip += limit; // Move the skip forward
}
} else {
logger.info(`No data found for class ${className}.`);
hasMoreData = false;
}
} catch (error) {
logger.error(`Error migrating class ${className}: ${error.message}`);
hasMoreData = false; // Stop in case of an error
}
}
}
}
migrateData(process.argv.slice(2)).catch(error => logger.error(`Unhandled Error: ${error.message}`));
EOF
# Convert CLASSES to a space-separated string
classes=$(echo $CLASSES | sed 's/\[//; s/\]//; s/,/ /g; s/\"//g')
# Run the script passing in the classes
echo "Running migration"
node migrate_data.js $classes > dataMigration.log 2>&1
echo "Migration complete"
# Finish setup and close down class creation
export PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION=false
pm2 restart parse-server --update-env
pm2 save
# Ensure PM2 restarts on reboot
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u $(whoami) --hp $(echo $HOME)
# Modify UFW rules to close mongo port after changes are done
sudo ufw delete allow $MONGO_PORT
sudo ufw reload
echo "Setup and data migration completed."