diff options
Diffstat (limited to 'server/initializers/installer.ts')
-rw-r--r-- | server/initializers/installer.ts | 199 |
1 files changed, 0 insertions, 199 deletions
diff --git a/server/initializers/installer.ts b/server/initializers/installer.ts deleted file mode 100644 index 2406a5936..000000000 --- a/server/initializers/installer.ts +++ /dev/null | |||
@@ -1,199 +0,0 @@ | |||
1 | import { ensureDir, readdir, remove } from 'fs-extra' | ||
2 | import passwordGenerator from 'password-generator' | ||
3 | import { join } from 'path' | ||
4 | import { isTestOrDevInstance } from '@server/helpers/core-utils' | ||
5 | import { generateRunnerRegistrationToken } from '@server/helpers/token-generator' | ||
6 | import { getNodeABIVersion } from '@server/helpers/version' | ||
7 | import { RunnerRegistrationTokenModel } from '@server/models/runner/runner-registration-token' | ||
8 | import { UserRole } from '@shared/models' | ||
9 | import { logger } from '../helpers/logger' | ||
10 | import { buildUser, createApplicationActor, createUserAccountAndChannelAndPlaylist } from '../lib/user' | ||
11 | import { ApplicationModel } from '../models/application/application' | ||
12 | import { OAuthClientModel } from '../models/oauth/oauth-client' | ||
13 | import { applicationExist, clientsExist, usersExist } from './checker-after-init' | ||
14 | import { CONFIG } from './config' | ||
15 | import { DIRECTORIES, FILES_CACHE, LAST_MIGRATION_VERSION } from './constants' | ||
16 | import { sequelizeTypescript } from './database' | ||
17 | |||
18 | async function installApplication () { | ||
19 | try { | ||
20 | await Promise.all([ | ||
21 | // Database related | ||
22 | sequelizeTypescript.sync() | ||
23 | .then(() => { | ||
24 | return Promise.all([ | ||
25 | createApplicationIfNotExist(), | ||
26 | createOAuthClientIfNotExist(), | ||
27 | createOAuthAdminIfNotExist(), | ||
28 | createRunnerRegistrationTokenIfNotExist() | ||
29 | ]) | ||
30 | }), | ||
31 | |||
32 | // Directories | ||
33 | removeCacheAndTmpDirectories() | ||
34 | .then(() => createDirectoriesIfNotExist()) | ||
35 | ]) | ||
36 | } catch (err) { | ||
37 | logger.error('Cannot install application.', { err }) | ||
38 | process.exit(-1) | ||
39 | } | ||
40 | } | ||
41 | |||
42 | // --------------------------------------------------------------------------- | ||
43 | |||
44 | export { | ||
45 | installApplication | ||
46 | } | ||
47 | |||
48 | // --------------------------------------------------------------------------- | ||
49 | |||
50 | function removeCacheAndTmpDirectories () { | ||
51 | const cacheDirectories = Object.keys(FILES_CACHE) | ||
52 | .map(k => FILES_CACHE[k].DIRECTORY) | ||
53 | |||
54 | const tasks: Promise<any>[] = [] | ||
55 | |||
56 | // Cache directories | ||
57 | for (const dir of cacheDirectories) { | ||
58 | tasks.push(removeDirectoryOrContent(dir)) | ||
59 | } | ||
60 | |||
61 | tasks.push(removeDirectoryOrContent(CONFIG.STORAGE.TMP_DIR)) | ||
62 | |||
63 | return Promise.all(tasks) | ||
64 | } | ||
65 | |||
66 | async function removeDirectoryOrContent (dir: string) { | ||
67 | try { | ||
68 | await remove(dir) | ||
69 | } catch (err) { | ||
70 | logger.debug('Cannot remove directory %s. Removing content instead.', dir, { err }) | ||
71 | |||
72 | const files = await readdir(dir) | ||
73 | |||
74 | for (const file of files) { | ||
75 | await remove(join(dir, file)) | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | function createDirectoriesIfNotExist () { | ||
81 | const storage = CONFIG.STORAGE | ||
82 | const cacheDirectories = Object.keys(FILES_CACHE) | ||
83 | .map(k => FILES_CACHE[k].DIRECTORY) | ||
84 | |||
85 | const tasks: Promise<void>[] = [] | ||
86 | for (const key of Object.keys(storage)) { | ||
87 | const dir = storage[key] | ||
88 | tasks.push(ensureDir(dir)) | ||
89 | } | ||
90 | |||
91 | // Cache directories | ||
92 | for (const dir of cacheDirectories) { | ||
93 | tasks.push(ensureDir(dir)) | ||
94 | } | ||
95 | |||
96 | tasks.push(ensureDir(DIRECTORIES.HLS_STREAMING_PLAYLIST.PRIVATE)) | ||
97 | tasks.push(ensureDir(DIRECTORIES.HLS_STREAMING_PLAYLIST.PUBLIC)) | ||
98 | tasks.push(ensureDir(DIRECTORIES.VIDEOS.PUBLIC)) | ||
99 | tasks.push(ensureDir(DIRECTORIES.VIDEOS.PRIVATE)) | ||
100 | |||
101 | // Resumable upload directory | ||
102 | tasks.push(ensureDir(DIRECTORIES.RESUMABLE_UPLOAD)) | ||
103 | |||
104 | return Promise.all(tasks) | ||
105 | } | ||
106 | |||
107 | async function createOAuthClientIfNotExist () { | ||
108 | const exist = await clientsExist() | ||
109 | // Nothing to do, clients already exist | ||
110 | if (exist === true) return undefined | ||
111 | |||
112 | logger.info('Creating a default OAuth Client.') | ||
113 | |||
114 | const id = passwordGenerator(32, false, /[a-z0-9]/) | ||
115 | const secret = passwordGenerator(32, false, /[a-zA-Z0-9]/) | ||
116 | const client = new OAuthClientModel({ | ||
117 | clientId: id, | ||
118 | clientSecret: secret, | ||
119 | grants: [ 'password', 'refresh_token' ], | ||
120 | redirectUris: null | ||
121 | }) | ||
122 | |||
123 | const createdClient = await client.save() | ||
124 | logger.info('Client id: ' + createdClient.clientId) | ||
125 | logger.info('Client secret: ' + createdClient.clientSecret) | ||
126 | |||
127 | return undefined | ||
128 | } | ||
129 | |||
130 | async function createOAuthAdminIfNotExist () { | ||
131 | const exist = await usersExist() | ||
132 | // Nothing to do, users already exist | ||
133 | if (exist === true) return undefined | ||
134 | |||
135 | logger.info('Creating the administrator.') | ||
136 | |||
137 | const username = 'root' | ||
138 | const role = UserRole.ADMINISTRATOR | ||
139 | const email = CONFIG.ADMIN.EMAIL | ||
140 | let validatePassword = true | ||
141 | let password = '' | ||
142 | |||
143 | // Do not generate a random password for test and dev environments | ||
144 | if (isTestOrDevInstance()) { | ||
145 | password = 'test' | ||
146 | |||
147 | if (process.env.NODE_APP_INSTANCE) { | ||
148 | password += process.env.NODE_APP_INSTANCE | ||
149 | } | ||
150 | |||
151 | // Our password is weak so do not validate it | ||
152 | validatePassword = false | ||
153 | } else if (process.env.PT_INITIAL_ROOT_PASSWORD) { | ||
154 | password = process.env.PT_INITIAL_ROOT_PASSWORD | ||
155 | } else { | ||
156 | password = passwordGenerator(16, true) | ||
157 | } | ||
158 | |||
159 | const user = buildUser({ | ||
160 | username, | ||
161 | email, | ||
162 | password, | ||
163 | role, | ||
164 | emailVerified: true, | ||
165 | videoQuota: -1, | ||
166 | videoQuotaDaily: -1 | ||
167 | }) | ||
168 | |||
169 | await createUserAccountAndChannelAndPlaylist({ userToCreate: user, channelNames: undefined, validateUser: validatePassword }) | ||
170 | logger.info('Username: ' + username) | ||
171 | logger.info('User password: ' + password) | ||
172 | } | ||
173 | |||
174 | async function createApplicationIfNotExist () { | ||
175 | const exist = await applicationExist() | ||
176 | // Nothing to do, application already exist | ||
177 | if (exist === true) return undefined | ||
178 | |||
179 | logger.info('Creating application account.') | ||
180 | |||
181 | const application = await ApplicationModel.create({ | ||
182 | migrationVersion: LAST_MIGRATION_VERSION, | ||
183 | nodeVersion: process.version, | ||
184 | nodeABIVersion: getNodeABIVersion() | ||
185 | }) | ||
186 | |||
187 | return createApplicationActor(application.id) | ||
188 | } | ||
189 | |||
190 | async function createRunnerRegistrationTokenIfNotExist () { | ||
191 | const total = await RunnerRegistrationTokenModel.countTotal() | ||
192 | if (total !== 0) return undefined | ||
193 | |||
194 | const token = new RunnerRegistrationTokenModel({ | ||
195 | registrationToken: generateRunnerRegistrationToken() | ||
196 | }) | ||
197 | |||
198 | await token.save() | ||
199 | } | ||