Coverage for gws-app/gws/server/control.py: 0%

59 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-17 01:37 +0200

1"""Server control. 

2 

3Following workflows are supported: 

4 

51) Server start. This is called only once upon the container start. 

6 

7 - (empty TMP_DIR completely in bin/gws) 

8 - configure 

9 - store the config 

10 - write server configs 

11 - (the actual invocation of the server start script takes place in bin/gws) 

12 

132) Server reconfigure. Can be called anytime, e.g. by the monitor 

14 

15 - configure 

16 - store the config 

17 - write server configs 

18 - empty the TRANSIENT_DIR 

19 - reload all backends 

20 - reload nginx 

21 

223) Server reload. Can be called anytime, e.g. by the monitor 

23 

24 - write server configs 

25 - empty the TRANSIENT_DIR 

26 - reload all backends 

27 - reload nginx 

28 

29 

304) Configure (debugging) 

31 

32 - configure 

33 - store the config 

34 

35 

365) Configtest (debugging) 

37 

38 - configure 

39 

40 

41 

42""" 

43 

44import shlex 

45import time 

46 

47import gws 

48import gws.config 

49import gws.lib.datetimex 

50import gws.lib.osx 

51 

52from . import manager 

53 

54# see bin/gws 

55_SERVER_START_SCRIPT = f'{gws.c.VAR_DIR}/server.sh' 

56 

57_PID_PATHS = { 

58 'web': f'{gws.c.PIDS_DIR}/web.uwsgi.pid', 

59 'spool': f'{gws.c.PIDS_DIR}/spool.uwsgi.pid', 

60 'mapproxy': f'{gws.c.PIDS_DIR}/mapproxy.uwsgi.pid', 

61 'nginx': f'{gws.c.PIDS_DIR}/nginx.pid', 

62} 

63 

64def start(manifest_path=None, config_path=None): 

65 if app_is_running('web'): 

66 gws.log.error(f'server already running') 

67 gws.u.exit(1) 

68 root = configure_and_store(manifest_path, config_path, is_starting=True) 

69 root.app.serverMgr.create_server_configs(gws.c.SERVER_DIR, _SERVER_START_SCRIPT, _PID_PATHS) 

70 

71 

72def reconfigure(manifest_path=None, config_path=None): 

73 if not app_is_running('web'): 

74 gws.log.error(f'server not running') 

75 gws.u.exit(1) 

76 root = configure_and_store(manifest_path, config_path, is_starting=False) 

77 root.app.serverMgr.create_server_configs(gws.c.SERVER_DIR, _SERVER_START_SCRIPT, _PID_PATHS) 

78 reload_all() 

79 

80 

81def configure_and_store(manifest_path=None, config_path=None, is_starting=False): 

82 root = configure(manifest_path, config_path, is_starting) 

83 gws.config.store(root) 

84 return root 

85 

86 

87def configure(manifest_path=None, config_path=None, is_starting=False): 

88 def _before_init(cfg): 

89 autorun = gws.u.get(cfg, 'server.autoRun') 

90 if autorun: 

91 gws.log.info(f'AUTORUN: {autorun!r}') 

92 gws.lib.osx.run(autorun, echo=True) 

93 

94 return gws.config.configure( 

95 manifest_path=manifest_path, 

96 config_path=config_path, 

97 before_init=_before_init if is_starting else None, 

98 fallback_config=_FALLBACK_CONFIG, 

99 ) 

100 

101 

102## 

103 

104def reload_all(): 

105 gws.lib.osx.run(['rm', '-fr', gws.c.TRANSIENT_DIR]) 

106 gws.u.ensure_system_dirs() 

107 

108 reload_app('spool') 

109 reload_app('mapproxy') 

110 reload_app('web') 

111 

112 reload_nginx() 

113 return True 

114 

115 

116def reload_app(srv): 

117 if not app_is_running(srv): 

118 gws.log.debug(f'reload: {srv=} not running') 

119 return 

120 gws.log.info(f'reloading {srv}...') 

121 gws.lib.osx.run(['uwsgi', '--reload', _PID_PATHS[srv]]) 

122 

123 

124def reload_nginx(): 

125 gws.log.info(f'reloading nginx...') 

126 gws.lib.osx.run(['nginx', '-c', gws.c.SERVER_DIR + '/nginx.conf', '-s', 'reload']) 

127 

128 

129def app_is_running(srv): 

130 try: 

131 with open(_PID_PATHS[srv]) as fp: 

132 pid = int(fp.read()) 

133 except (FileNotFoundError, ValueError): 

134 pid = 0 

135 gws.log.debug(f'found {pid=} for {srv=}') 

136 return pid and pid in gws.lib.osx.running_pids() 

137 

138 

139## 

140 

141 

142_FALLBACK_CONFIG = { 

143 'server': { 

144 'mapproxy': {'enabled': False}, 

145 'monitor': {'enabled': False}, 

146 'log': {'level': 'INFO'}, 

147 'qgis': {'host': 'qgis', 'port': 80}, 

148 'spool': {'enabled': False}, 

149 'web': {'enabled': True, 'workers': 1}, 

150 'autoRun': '', 

151 'timeout': 60, 

152 'timeZone': 'UTC', 

153 } 

154}