1 import envPaths from 'env-paths'
2 import { ensureDir, pathExists, readFile, remove, writeFile } from 'fs-extra'
3 import { merge } from 'lodash'
4 import { logger } from 'packages/peertube-runner/shared/logger'
5 import { dirname, join } from 'path'
6 import { parse, stringify } from '@iarna/toml'
8 const paths = envPaths('peertube-runner')
20 registeredInstances: {
24 runnerDescription?: string
28 export class ConfigManager {
29 private static instance: ConfigManager
31 private config: Config = {
39 registeredInstances: []
43 private configFilePath: string
45 private constructor () {}
49 this.configFilePath = join(this.getConfigDir(), 'config.toml')
53 logger.info(`Using ${this.configFilePath} as configuration file`)
55 if (this.isTestInstance()) {
56 logger.info('Removing configuration file as we are using the "test" id')
57 await remove(this.configFilePath)
60 await ensureDir(dirname(this.configFilePath))
62 if (!await pathExists(this.configFilePath)) {
66 const file = await readFile(this.configFilePath, 'utf-8')
68 this.config = merge(this.config, parse(file))
72 return writeFile(this.configFilePath, stringify(this.config))
75 // ---------------------------------------------------------------------------
77 async setRegisteredInstances (registeredInstances: {
81 runnerDescription?: string
83 this.config.registeredInstances = registeredInstances
88 // ---------------------------------------------------------------------------
91 return this.deepFreeze(this.config)
94 // ---------------------------------------------------------------------------
96 getTranscodingDirectory () {
97 return join(paths.cache, this.id, 'transcoding')
100 getSocketDirectory () {
101 return join(paths.data, this.id)
105 return join(this.getSocketDirectory(), 'peertube-runner.sock')
109 return join(paths.config, this.id)
112 // ---------------------------------------------------------------------------
115 return typeof this.id === 'string' && this.id.match(/^test-\d$/)
118 // ---------------------------------------------------------------------------
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)
124 // Freeze properties before freezing self
125 for (const name of propNames) {
126 const value = object[name]
128 if ((value && typeof value === 'object') || typeof value === 'function') {
129 this.deepFreeze(value)
133 return Object.freeze({ ...object })
136 static get Instance () {
137 return this.instance || (this.instance = new this())