Skip to content

Commit 913bb50

Browse files
committed
Version [1.0.1]
1 parent 1247b8d commit 913bb50

File tree

7 files changed

+61
-22
lines changed

7 files changed

+61
-22
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88

99

10+
## Version [1.0.1] - 2024-16-07
11+
12+
### Fixed
13+
14+
- DMB: Introduced a Riven startup check for the symlinked directory to ensure the Zurg startup processes have finished before starting Riven
15+
- DMB: Introduced a Rclone startup check for the Zurg WebDAV URL to ensure the Zurg startup processes have finished before starting Rclone
16+
17+
1018
## Version [1.0.0] - 2024-25-06
1119

1220
### Breaking Changes

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ services:
8383
## Riven Required Settings
8484
- RIVEN_ENABLED=true
8585
- ORIGIN=http://0.0.0.0:3000 # See Riven documentation for more details
86+
- BACKEND_URL=http://127.0.0.1:8080 # Required to be left as is
8687
## Riven Optional Settings
8788
# - PLEX_TOKEN=
8889
# - PLEX_ADDRESS=

healthcheck.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -29,32 +29,32 @@ def check_processes(process_info):
2929
"zurg_rd": {
3030
"regex": re.compile(rf'/zurg/RD/zurg.*--preload', re.IGNORECASE),
3131
"error_message": "The Zurg RD process is not running.",
32-
"should_run": str(ZURG).lower() == 'true' and RDAPIKEY
32+
"should_run": str(ZURG).lower() == 'true' and RDAPIKEY
3333
},
3434
"zurg_ad": {
3535
"regex": re.compile(rf'/zurg/AD/zurg.*--preload', re.IGNORECASE),
3636
"error_message": "The Zurg AD process is not running.",
37-
"should_run": str(ZURG).lower() == 'true' and ADAPIKEY
37+
"should_run": str(ZURG).lower() == 'true' and ADAPIKEY
3838
},
3939
"riven_frontend": {
4040
"regex": re.compile(r'node build'),
4141
"error_message": "The Riven frontend process is not running.",
42-
"should_run": str(RIVEN).lower() == 'true'
42+
"should_run": str(RIVEN).lower() == 'true' and os.path.exists(f'/data/{RCLONEMN}/__all__')
4343
},
4444
"riven_backend": {
4545
"regex": re.compile(r'/venv/bin/python backend/main.py'),
4646
"error_message": "The Riven backend process is not running.",
47-
"should_run": str(RIVEN).lower() == 'true'
47+
"should_run": str(RIVEN).lower() == 'true' and os.path.exists(f'/data/{RCLONEMN}/__all__')
4848
},
4949
"rclonemn_rd": {
5050
"regex": re.compile(rf'rclone {mount_type} {re.escape(RCLONEMN_RD)}:'),
5151
"error_message": f"The Rclone RD process for {RCLONEMN_RD} is not running.",
52-
"should_run": str(ZURG).lower() == 'true' and RDAPIKEY
52+
"should_run": str(ZURG).lower() == 'true' and RDAPIKEY and os.path.exists(f'/healthcheck/{RCLONEMN}')
5353
},
5454
"rclonemn_ad": {
5555
"regex": re.compile(rf'rclone {mount_type} {re.escape(RCLONEMN_AD)}:'),
5656
"error_message": f"The Rclone AD process for {RCLONEMN_AD} is not running.",
57-
"should_run": str(ZURG).lower() == 'true' and ADAPIKEY
57+
"should_run": str(ZURG).lower() == 'true' and ADAPIKEY and os.path.exists(f'/healthcheck/{RCLONEMN}')
5858
}
5959
}
6060

main.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
def main():
1010
logger = get_logger()
1111

12-
version = '1.0.0'
12+
version = '1.0.1'
1313

1414
ascii_art = f'''
1515

rclone/rclone.py

+39-14
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,37 @@ def get_port_from_config(config_file_path, key_type):
1111
return port
1212
except Exception as e:
1313
logger.error(f"Error reading port from config file: {e}")
14-
return '9999'
14+
return '9999'
1515

1616
def obscure_password(password):
1717
"""Obscure the password using rclone."""
1818
try:
1919
result = subprocess.run(["rclone", "obscure", password], check=True, stdout=subprocess.PIPE)
2020
return result.stdout.decode().strip()
2121
except subprocess.CalledProcessError as e:
22-
print("Error obscuring password:", e)
22+
logger.error(f"Error obscuring password: {e}")
2323
return None
2424

25+
def wait_for_url(url, endpoint="/dav/", timeout=600):
26+
start_time = time.time()
27+
logger.info(f"Waiting to start the rclone process until the Zurg WebDAV {url}{endpoint} is accessible.")
28+
while time.time() - start_time < timeout:
29+
try:
30+
response = requests.get(f"{url}{endpoint}")
31+
if response.status_code == 207:
32+
logger.debug(f"Zurg WebDAV {url}{endpoint} is accessible.")
33+
return True
34+
else:
35+
logger.debug(f"Received status code {response.status_code} while waiting for {url}{endpoint} to be accessible.")
36+
except requests.ConnectionError as e:
37+
logger.debug(f"Connection error while waiting for the Zurg WebDAV {url}{endpoint} to be accessible: {e}")
38+
time.sleep(5)
39+
logger.error(f"Timeout: Zurg WebDAV {url}{endpoint} is not accessible after {timeout} seconds.")
40+
return False
41+
2542
def setup():
2643
logger.info("Checking rclone flags")
27-
44+
2845
try:
2946
if not RCLONEMN:
3047
raise Exception("Please set a name for the rclone mount")
@@ -84,28 +101,36 @@ def setup():
84101
logger.info(f"Configuring rclone for {mn}")
85102
subprocess.run(["umount", f"/data/{mn}"], check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
86103
os.makedirs(f"/data/{mn}", exist_ok=True)
104+
87105
if NFSMOUNT is not None and NFSMOUNT.lower() == "true":
88106
if NFSPORT:
89-
port = NFSPORT
107+
port = NFSPORT
90108
logger.info(f"Setting up rclone NFS mount server for {mn} at 0.0.0.0:{port}")
91109
rclone_command = ["rclone", "serve", "nfs", f"{mn}:", "--config", "/config/rclone.config", "--addr", f"0.0.0.0:{port}", "--vfs-cache-mode=full", "--dir-cache-time=10"]
92-
else:
93-
port = random.randint(8001, 8999)
110+
else:
111+
port = random.randint(8001, 8999)
94112
logger.info(f"Setting up rclone NFS mount server for {mn} at 0.0.0.0:{port}")
95-
rclone_command = ["rclone", "serve", "nfs", f"{mn}:", "--config", "/config/rclone.config", "--addr", f"0.0.0.0:{port}", "--vfs-cache-mode=full", "--dir-cache-time=10"]
113+
rclone_command = ["rclone", "serve", "nfs", f"{mn}:", "--config", "/config/rclone.config", "--addr", f"0.0.0.0:{port}", "--vfs-cache-mode=full", "--dir-cache-time=10"]
96114
else:
97115
rclone_command = ["rclone", "mount", f"{mn}:", f"/data/{mn}", "--config", "/config/rclone.config", "--allow-other", "--poll-interval=0", "--dir-cache-time=10"]
98116
if not RIVEN or idx != len(mount_names) - 1:
99117
rclone_command.append("--daemon")
100-
101-
logger.info(f"Starting rclone{' daemon' if '--daemon' in rclone_command else ''} for {mn}")
102-
process_name = "rclone"
103-
subprocess_logger = SubprocessLogger(logger, process_name)
104-
process = subprocess.Popen(rclone_command, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
105-
subprocess_logger.start_monitoring_stderr(process, mn, process_name)
118+
119+
url = f"http://localhost:{rd_port if mn == RCLONEMN_RD else ad_port}"
120+
if os.path.exists(f"/healthcheck/{mn}"):
121+
os.rmdir(f"/healthcheck/{mn}")
122+
if wait_for_url(url):
123+
os.makedirs(f"/healthcheck/{mn}") # makdir for healthcheck. Don't like it, but it works for now...
124+
logger.info(f"The Zurg WebDAV URL {url}/dav is accessible. Starting rclone{' daemon' if '--daemon' in rclone_command else ''} for {mn}")
125+
process_name = "rclone"
126+
subprocess_logger = SubprocessLogger(logger, process_name)
127+
process = subprocess.Popen(rclone_command, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
128+
subprocess_logger.start_monitoring_stderr(process, mn, process_name)
129+
else:
130+
logger.error(f"The Zurg WebDav URL {url}/dav is not accessible within the timeout period. Skipping rclone setup for {mn}")
106131

107132
logger.info("rclone startup complete")
108133

109134
except Exception as e:
110135
logger.error(e)
111-
exit(1)
136+
exit(1)

riven_/update.py

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ def __init__(self):
88
self.backend_process = None
99

1010
def start_process(self, process_name, config_dir=None):
11+
directory = f"/data/{RCLONEMN}/__all__"
12+
while not os.path.exists(directory):
13+
self.logger.info(f"Waiting for symlink directory {directory} to become available before starting Riven")
14+
time.sleep(10)
1115
if process_name == 'Riven_frontend':
1216
command = ["node", "build"]
1317
config_dir = "./riven/frontend"

zurg/setup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ def setup_zurg_instance(config_dir, token, key_type):
120120
else:
121121
port = random.randint(9001, 9999)
122122
logger.debug(f"Selected port {port} for Zurg w/ {key_type} instance")
123-
update_port(config_file_path, port)
123+
update_port(config_file_path, port)
124+
124125

125126
if ZURGUSER and ZURGPASS:
126127
update_creds(config_file_path, ZURGUSER, ZURGPASS)

0 commit comments

Comments
 (0)