|
| 1 | +#!/usr/bin/python3 |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | + |
| 4 | +issues = {} # Returned issues dict |
| 5 | +buildHooks = {} # Options, and others hooks |
| 6 | +haltOnErrors = True |
| 7 | + |
| 8 | +import os |
| 9 | +import sys |
| 10 | + |
| 11 | +global templatesDirectory |
| 12 | +global currentServiceName # Name of the current service |
| 13 | +global generateRandomString |
| 14 | + |
| 15 | +from deps.consts import templatesDirectory |
| 16 | +from deps.common_functions import generateRandomString |
| 17 | + |
| 18 | + |
| 19 | +# Main wrapper function. Required to make local vars work correctly |
| 20 | +def main(): |
| 21 | + |
| 22 | + global toRun # Switch for which function to run when executed |
| 23 | + global buildHooks # Where to place the options menu result |
| 24 | + global issues # Returned issues dict |
| 25 | + global haltOnErrors # Turn on to allow erroring |
| 26 | + |
| 27 | + # runtime vars |
| 28 | + portConflicts = [] |
| 29 | + |
| 30 | + # This lets the menu know whether to put " >> Options " or not |
| 31 | + # This function is REQUIRED. |
| 32 | + def checkForOptionsHook(): |
| 33 | + try: |
| 34 | + buildHooks["options"] = callable(runOptionsMenu) |
| 35 | + except: |
| 36 | + buildHooks["options"] = False |
| 37 | + return buildHooks |
| 38 | + return buildHooks |
| 39 | + |
| 40 | + # This function is REQUIRED. |
| 41 | + def checkForPreBuildHook(): |
| 42 | + try: |
| 43 | + buildHooks["preBuildHook"] = callable(preBuild) |
| 44 | + except: |
| 45 | + buildHooks["preBuildHook"] = False |
| 46 | + return buildHooks |
| 47 | + return buildHooks |
| 48 | + |
| 49 | + # This function is REQUIRED. |
| 50 | + def checkForPostBuildHook(): |
| 51 | + try: |
| 52 | + buildHooks["postBuildHook"] = callable(postBuild) |
| 53 | + except: |
| 54 | + buildHooks["postBuildHook"] = False |
| 55 | + return buildHooks |
| 56 | + return buildHooks |
| 57 | + |
| 58 | + # This function is REQUIRED. |
| 59 | + def checkForRunChecksHook(): |
| 60 | + try: |
| 61 | + buildHooks["runChecksHook"] = callable(runChecks) |
| 62 | + except: |
| 63 | + buildHooks["runChecksHook"] = False |
| 64 | + return buildHooks |
| 65 | + return buildHooks |
| 66 | + |
| 67 | + # This service will not check anything unless this is set |
| 68 | + # This function is optional, and will run each time the menu is rendered |
| 69 | + def runChecks(): |
| 70 | + checkForIssues() |
| 71 | + return [] |
| 72 | + |
| 73 | + # This function is optional, and will run after the docker-compose.yml file is written to disk. |
| 74 | + def postBuild(): |
| 75 | + return True |
| 76 | + |
| 77 | + # This function is optional, and will run just before the build docker-compose.yml code. |
| 78 | + def preBuild(): |
| 79 | + return True |
| 80 | + |
| 81 | + # ##################################### |
| 82 | + # Supporting functions below |
| 83 | + # ##################################### |
| 84 | + |
| 85 | + def doCustomSetup() : |
| 86 | + |
| 87 | + import os |
| 88 | + import re |
| 89 | + import subprocess |
| 90 | + from os.path import exists |
| 91 | + |
| 92 | + def copyUdevRulesFile(templates,rules) : |
| 93 | + |
| 94 | + # the expected location of the rules file in the template is the absolute path ... |
| 95 | + SOURCE_PATH = templates + '/' + currentServiceName + '/' + rules |
| 96 | + |
| 97 | + # the rules file should be installed at the following absolute path... |
| 98 | + TARGET_PATH = '/etc/udev/rules.d' + '/' + rules |
| 99 | + |
| 100 | + # does the target already exist? |
| 101 | + if not exists(TARGET_PATH) : |
| 102 | + |
| 103 | + # no! does the source path exist? |
| 104 | + if exists(SOURCE_PATH) : |
| 105 | + |
| 106 | + # yes! we should copy the source to the target |
| 107 | + subprocess.call(['sudo', 'cp', SOURCE_PATH, TARGET_PATH]) |
| 108 | + |
| 109 | + # sudo cp sets root ownership but not necessarily correct mode |
| 110 | + subprocess.call(['sudo', 'chmod', '644', TARGET_PATH]) |
| 111 | + |
| 112 | + def setEnvironment (path, key, value) : |
| 113 | + |
| 114 | + # assume the variable should be written |
| 115 | + shouldWrite = True |
| 116 | + |
| 117 | + # does the target file already exist? |
| 118 | + if exists(path) : |
| 119 | + |
| 120 | + # yes! open the file so we can search it |
| 121 | + env_file = open(path, 'r+') |
| 122 | + |
| 123 | + # prepare to read by lines |
| 124 | + env_data = env_file.readlines() |
| 125 | + |
| 126 | + # we are searching for... |
| 127 | + expression = '^' + key + '=' |
| 128 | + |
| 129 | + # search by line |
| 130 | + for line in env_data: |
| 131 | + if re.search(expression, line) : |
| 132 | + shouldWrite = False |
| 133 | + break |
| 134 | + |
| 135 | + else : |
| 136 | + |
| 137 | + # no! create the file |
| 138 | + env_file = open(path, 'w') |
| 139 | + |
| 140 | + # should the variable be written? |
| 141 | + if shouldWrite : |
| 142 | + print(key + '=' + value, file=env_file) |
| 143 | + |
| 144 | + # done with the environment file |
| 145 | + env_file.close() |
| 146 | + |
| 147 | + copyUdevRulesFile( |
| 148 | + os.path.realpath(templatesDirectory), |
| 149 | + '88-tty-iotstack-' + currentServiceName + '.rules' |
| 150 | + ) |
| 151 | + |
| 152 | + # the environment file is located at ... |
| 153 | + DOT_ENV_PATH = os.path.realpath('.') + '/.env' |
| 154 | + |
| 155 | + # check/set environment variables |
| 156 | + setEnvironment(DOT_ENV_PATH,'ESPHOME_USERNAME',currentServiceName) |
| 157 | + setEnvironment(DOT_ENV_PATH,'ESPHOME_PASSWORD',generateRandomString()) |
| 158 | + |
| 159 | + |
| 160 | + def checkForIssues(): |
| 161 | + doCustomSetup() # done here because is called least-frequently |
| 162 | + return True |
| 163 | + |
| 164 | + if haltOnErrors: |
| 165 | + eval(toRun)() |
| 166 | + else: |
| 167 | + try: |
| 168 | + eval(toRun)() |
| 169 | + except: |
| 170 | + pass |
| 171 | + |
| 172 | +if currentServiceName == 'esphome': |
| 173 | + main() |
| 174 | +else: |
| 175 | + print("Error. '{}' Tried to run 'plex' config".format(currentServiceName)) |
0 commit comments