]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - packages/peertube-runner/shared/config-manager.ts
Merge remote-tracking branch 'weblate/develop' into develop
[github/Chocobozzz/PeerTube.git] / packages / peertube-runner / shared / config-manager.ts
CommitLineData
1772b383
C
1import envPaths from 'env-paths'
2import { ensureDir, pathExists, readFile, remove, writeFile } from 'fs-extra'
3import { merge } from 'lodash'
4import { logger } from 'packages/peertube-runner/shared/logger'
5import { dirname, join } from 'path'
6import { parse, stringify } from '@iarna/toml'
7
8const paths = envPaths('peertube-runner')
9
10type Config = {
11 jobs: {
12 concurrency: number
13 }
14
15 ffmpeg: {
16 threads: number
17 nice: number
18 }
19
20 registeredInstances: {
21 url: string
22 runnerToken: string
23 runnerName: string
24 runnerDescription?: string
25 }[]
26}
27
28export class ConfigManager {
29 private static instance: ConfigManager
30
31 private config: Config = {
32 jobs: {
33 concurrency: 2
34 },
35 ffmpeg: {
36 threads: 2,
37 nice: 20
38 },
39 registeredInstances: []
40 }
41
42 private id: string
43 private configFilePath: string
44
45 private constructor () {}
46
47 init (id: string) {
48 this.id = id
49 this.configFilePath = join(this.getConfigDir(), 'config.toml')
50 }
51
52 async load () {
53 logger.info(`Using ${this.configFilePath} as configuration file`)
54
55 if (this.isTestInstance()) {
56 logger.info('Removing configuration file as we are using the "test" id')
57 await remove(this.configFilePath)
58 }
59
60 await ensureDir(dirname(this.configFilePath))
61
62 if (!await pathExists(this.configFilePath)) {
63 await this.save()
64 }
65
66 const file = await readFile(this.configFilePath, 'utf-8')
67
68 this.config = merge(this.config, parse(file))
69 }
70
71 save () {
72 return writeFile(this.configFilePath, stringify(this.config))
73 }
74
75 // ---------------------------------------------------------------------------
76
77 async setRegisteredInstances (registeredInstances: {
78 url: string
79 runnerToken: string
80 runnerName: string
81 runnerDescription?: string
82 }[]) {
83 this.config.registeredInstances = registeredInstances
84
85 await this.save()
86 }
87
88 // ---------------------------------------------------------------------------
89
90 getConfig () {
91 return this.deepFreeze(this.config)
92 }
93
94 // ---------------------------------------------------------------------------
95
96 getTranscodingDirectory () {
97 return join(paths.cache, this.id, 'transcoding')
98 }
99
100 getSocketDirectory () {
101 return join(paths.data, this.id)
102 }
103
104 getSocketPath () {
105 return join(this.getSocketDirectory(), 'peertube-runner.sock')
106 }
107
108 getConfigDir () {
109 return join(paths.config, this.id)
110 }
111
112 // ---------------------------------------------------------------------------
113
114 isTestInstance () {
6403a6bd 115 return typeof this.id === 'string' && this.id.match(/^test-\d$/)
1772b383
C
116 }
117
118 // ---------------------------------------------------------------------------
119
120 // Thanks: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
121 private deepFreeze <T extends object> (object: T) {
122 const propNames = Reflect.ownKeys(object)
123
124 // Freeze properties before freezing self
125 for (const name of propNames) {
126 const value = object[name]
127
128 if ((value && typeof value === 'object') || typeof value === 'function') {
129 this.deepFreeze(value)
130 }
131 }
132
133 return Object.freeze({ ...object })
134 }
135
136 static get Instance () {
137 return this.instance || (this.instance = new this())
138 }
139}