dar-backup 0.8.0__py3-none-any.whl → 0.8.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dar_backup/Changelog.md +8 -0
- dar_backup/README.md +1 -1
- dar_backup/__about__.py +1 -1
- dar_backup/command_runner.py +49 -15
- {dar_backup-0.8.0.dist-info → dar_backup-0.8.1.dist-info}/METADATA +2 -2
- {dar_backup-0.8.0.dist-info → dar_backup-0.8.1.dist-info}/RECORD +9 -9
- {dar_backup-0.8.0.dist-info → dar_backup-0.8.1.dist-info}/WHEEL +0 -0
- {dar_backup-0.8.0.dist-info → dar_backup-0.8.1.dist-info}/entry_points.txt +0 -0
- {dar_backup-0.8.0.dist-info → dar_backup-0.8.1.dist-info}/licenses/LICENSE +0 -0
dar_backup/Changelog.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
<!-- markdownlint-disable MD024 -->
|
|
2
2
|
# dar-backup Changelog
|
|
3
3
|
|
|
4
|
+
## v2-beta-0.8.1 - 2025-07-16
|
|
5
|
+
|
|
6
|
+
Github link: [v2-beta-0.8.1](https://github.com/per2jensen/dar-backup/tree/v2-beta-0.8.1/v2)
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- FIX: runner now logs an error and fills more data into the returned CommandResult.
|
|
11
|
+
|
|
4
12
|
## v2-beta-0.8.0 - 2025-06-13
|
|
5
13
|
|
|
6
14
|
Github link: [v2-beta-0.8.0](https://github.com/per2jensen/dar-backup/tree/v2-beta-0.8.0/v2)
|
dar_backup/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://pypi.org/project/dar-backup/)
|
|
10
10
|
[](https://pypi.org/project/dar-backup/)
|
|
11
11
|
[](https://github.com/per2jensen/dar-backup/blob/main/v2/doc/weekly_clones.png)
|
|
12
|
-
[](https://github.com/per2jensen/dar-backup/blob/main/v2/doc/weekly_clones.png)
|
|
12
|
+
[](https://github.com/per2jensen/dar-backup/blob/main/v2/doc/weekly_clones.png) <sub>🎯 Stats powered by [ClonePulse](https://github.com/per2jensen/clonepulse)</sub>
|
|
13
13
|
|
|
14
14
|
The wonderful 'dar' [Disk Archiver](https://github.com/Edrusb/DAR) is used for
|
|
15
15
|
the heavy lifting, together with the [parchive](https://github.com/Parchive/par2cmdline) suite in these scripts.
|
dar_backup/__about__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "0.8.
|
|
1
|
+
__version__ = "0.8.1"
|
|
2
2
|
|
|
3
3
|
__license__ = '''Licensed under GNU GENERAL PUBLIC LICENSE v3, see the supplied file "LICENSE" for details.
|
|
4
4
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW, not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
dar_backup/command_runner.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import subprocess
|
|
4
4
|
import logging
|
|
5
|
+
import traceback
|
|
5
6
|
import threading
|
|
6
7
|
import os
|
|
7
8
|
import sys
|
|
@@ -12,14 +13,24 @@ from dar_backup.util import get_logger
|
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class CommandResult:
|
|
15
|
-
def __init__(self, returncode: int, stdout: str, stderr: str):
|
|
16
|
+
def __init__(self, returncode: int, stdout: str, stderr: str, stack: str = None):
|
|
16
17
|
self.returncode = returncode
|
|
17
18
|
self.stdout = stdout
|
|
18
19
|
self.stderr = stderr
|
|
20
|
+
self.stack = stack
|
|
19
21
|
|
|
20
22
|
def __repr__(self):
|
|
21
|
-
return f"<CommandResult returncode={self.returncode}>"
|
|
22
|
-
|
|
23
|
+
return f"<CommandResult returncode={self.returncode}\nstdout={self.stdout}\nstderr={self.stderr}\nstack={self.stack}>"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def __str__(self):
|
|
27
|
+
return (
|
|
28
|
+
f"CommandResult:\n"
|
|
29
|
+
f" Return code: {self.returncode}\n"
|
|
30
|
+
f" STDOUT:\n{self.stdout}\n"
|
|
31
|
+
f" STDERR:\n{self.stderr}\n"
|
|
32
|
+
f" Stacktrace:\n{self.stack if self.stack else '<none>'}"
|
|
33
|
+
)
|
|
23
34
|
|
|
24
35
|
class CommandRunner:
|
|
25
36
|
def __init__(
|
|
@@ -74,22 +85,29 @@ class CommandRunner:
|
|
|
74
85
|
) -> CommandResult:
|
|
75
86
|
timeout = timeout or self.default_timeout
|
|
76
87
|
|
|
77
|
-
#log the command to be executed
|
|
78
88
|
command = f"Executing command: {' '.join(cmd)} (timeout={timeout}s)"
|
|
79
|
-
self.command_logger.info(command)
|
|
80
|
-
self.logger.debug(command)
|
|
81
|
-
|
|
82
|
-
process = subprocess.Popen(
|
|
83
|
-
cmd,
|
|
84
|
-
stdout=subprocess.PIPE if capture_output else None,
|
|
85
|
-
stderr=subprocess.PIPE if capture_output else None,
|
|
86
|
-
text=False,
|
|
87
|
-
bufsize=-1
|
|
88
|
-
)
|
|
89
|
+
self.command_logger.info(command)
|
|
90
|
+
self.logger.debug(command)
|
|
89
91
|
|
|
90
92
|
stdout_lines = []
|
|
91
93
|
stderr_lines = []
|
|
92
94
|
|
|
95
|
+
try:
|
|
96
|
+
process = subprocess.Popen(
|
|
97
|
+
cmd,
|
|
98
|
+
stdout=subprocess.PIPE if capture_output else None,
|
|
99
|
+
stderr=subprocess.PIPE if capture_output else None,
|
|
100
|
+
text=False,
|
|
101
|
+
bufsize=-1
|
|
102
|
+
)
|
|
103
|
+
except Exception as e:
|
|
104
|
+
stack = traceback.format_exc()
|
|
105
|
+
return CommandResult(
|
|
106
|
+
returncode=-1,
|
|
107
|
+
stdout='',
|
|
108
|
+
stderr=str(e),
|
|
109
|
+
stack=stack
|
|
110
|
+
)
|
|
93
111
|
|
|
94
112
|
def stream_output(stream, lines, level):
|
|
95
113
|
try:
|
|
@@ -123,11 +141,27 @@ class CommandRunner:
|
|
|
123
141
|
process.kill()
|
|
124
142
|
self.logger.error(f"Command timed out: {' '.join(cmd)}")
|
|
125
143
|
return CommandResult(-1, ''.join(stdout_lines), ''.join(stderr_lines))
|
|
144
|
+
except Exception as e:
|
|
145
|
+
stack = traceback.format_exc()
|
|
146
|
+
self.logger.error(f"Command execution failed: {' '.join(cmd)} with error: {e}")
|
|
147
|
+
return CommandResult(-1, ''.join(stdout_lines), ''.join(stderr_lines), stack)
|
|
126
148
|
|
|
127
149
|
for t in threads:
|
|
128
150
|
t.join()
|
|
129
151
|
|
|
152
|
+
|
|
130
153
|
if check and process.returncode != 0:
|
|
131
154
|
self.logger.error(f"Command failed with exit code {process.returncode}")
|
|
155
|
+
return CommandResult(
|
|
156
|
+
process.returncode,
|
|
157
|
+
''.join(stdout_lines),
|
|
158
|
+
''.join(stderr_lines),
|
|
159
|
+
stack=traceback.format_stack()
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
return CommandResult(
|
|
163
|
+
process.returncode,
|
|
164
|
+
''.join(stdout_lines),
|
|
165
|
+
''.join(stderr_lines),
|
|
166
|
+
)
|
|
132
167
|
|
|
133
|
-
return CommandResult(process.returncode, ''.join(stdout_lines), ''.join(stderr_lines))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dar-backup
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: A script to do full, differential and incremental backups using dar. Some files are restored from the backups during verification, after which par2 redundancy files are created. The script also has a cleanup feature to remove old backups and par2 files.
|
|
5
5
|
Project-URL: GPG Public Key, https://keys.openpgp.org/search?q=dar-backup@pm.me
|
|
6
6
|
Project-URL: Homepage, https://github.com/per2jensen/dar-backup/tree/main/v2
|
|
@@ -727,7 +727,7 @@ Description-Content-Type: text/markdown
|
|
|
727
727
|
[](https://pypi.org/project/dar-backup/)
|
|
728
728
|
[](https://pypi.org/project/dar-backup/)
|
|
729
729
|
[](https://github.com/per2jensen/dar-backup/blob/main/v2/doc/weekly_clones.png)
|
|
730
|
-
[](https://github.com/per2jensen/dar-backup/blob/main/v2/doc/weekly_clones.png)
|
|
730
|
+
[](https://github.com/per2jensen/dar-backup/blob/main/v2/doc/weekly_clones.png) <sub>🎯 Stats powered by [ClonePulse](https://github.com/per2jensen/clonepulse)</sub>
|
|
731
731
|
|
|
732
732
|
The wonderful 'dar' [Disk Archiver](https://github.com/Edrusb/DAR) is used for
|
|
733
733
|
the heavy lifting, together with the [parchive](https://github.com/Parchive/par2cmdline) suite in these scripts.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
dar_backup/.darrc,sha256=-aerqivZmOsW_XBCh9IfbYTUvw0GkzDSr3Vx4GcNB1g,2113
|
|
2
|
-
dar_backup/Changelog.md,sha256=
|
|
3
|
-
dar_backup/README.md,sha256=
|
|
4
|
-
dar_backup/__about__.py,sha256=
|
|
2
|
+
dar_backup/Changelog.md,sha256=T6w4NGFjBg2rgyTmgScKPFwdJx_M3XkEnU7aG3NQMyo,12094
|
|
3
|
+
dar_backup/README.md,sha256=S8wpgaqa2LzXXZiQEzoOV1qjrpf9m1baYmvzGYtgEcE,59990
|
|
4
|
+
dar_backup/__about__.py,sha256=SSWyynCpdSF2lIcROjGdr29Z-m523S9BbEc-ytO_L30,344
|
|
5
5
|
dar_backup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
dar_backup/clean_log.py,sha256=pmmyPmLWbm3_3sHwJt9V_xBwUF8v015iS17ypJAGAZ4,6023
|
|
7
7
|
dar_backup/cleanup.py,sha256=_ggDcpMCB1MhXStvYussp_PdGfhIFtEutT5BNrNkMSY,13297
|
|
8
|
-
dar_backup/command_runner.py,sha256=
|
|
8
|
+
dar_backup/command_runner.py,sha256=_aaLk8j44tFNYBv9FJTpUaIFE_iIKEO1W1xDaiO5HJg,5599
|
|
9
9
|
dar_backup/config_settings.py,sha256=2UAHvatrVO4ark6lCn2Q7qBvZN6DUMK2ftlNrKpzlWc,5792
|
|
10
10
|
dar_backup/dar-backup.conf,sha256=46V2zdvjj_aThFY11wWlffjmoiChYmatdf5DXCsmmao,1208
|
|
11
11
|
dar_backup/dar-backup.conf.j2,sha256=z3epGo6nB_Jh3liTOp93wJO_HKUsf7qghe9cdtFH7cY,2021
|
|
@@ -18,8 +18,8 @@ dar_backup/installer.py,sha256=xSXh77qquIZbUTSY3AbhERQbS7bnrPE__M_yqpszdhM,6883
|
|
|
18
18
|
dar_backup/manager.py,sha256=d1zliFpSuWc8JhjKqLMC-xOhp5kSIcfeGkMZOVuZcM0,27143
|
|
19
19
|
dar_backup/rich_progress.py,sha256=SfwFxebBl6jnDQMUQr4McknkW1yQWaJVo1Ju1OD3okA,3221
|
|
20
20
|
dar_backup/util.py,sha256=iTOGsZyIdkvh9tIu7hD_IXi-9HO6GhVgqact5GGInEY,26063
|
|
21
|
-
dar_backup-0.8.
|
|
22
|
-
dar_backup-0.8.
|
|
23
|
-
dar_backup-0.8.
|
|
24
|
-
dar_backup-0.8.
|
|
25
|
-
dar_backup-0.8.
|
|
21
|
+
dar_backup-0.8.1.dist-info/METADATA,sha256=UPCRBCwXlLLjGVGZC-BVqCZXOCYa82lccd8W16I2sCg,102681
|
|
22
|
+
dar_backup-0.8.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
23
|
+
dar_backup-0.8.1.dist-info/entry_points.txt,sha256=pOK9M8cHeAcGIatrYzkm_1O89kPk0enyYONALYjFBx4,286
|
|
24
|
+
dar_backup-0.8.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
25
|
+
dar_backup-0.8.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|