Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if Include folders/files do exists (in case they are removed) #1718

Draft
wants to merge 19 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Back In Time

Version 1.4.4-dev (development of upcoming release)
* Fix bug: Check if Include folders/files do exists (in case they are removed) (1586) (@rafaelhdr)
rafaelhdr marked this conversation as resolved.
Show resolved Hide resolved
* Feature: Support SSH proxy (jump) host (#1688) (@cgrinham, Christie Grinham)
* Removed: Context menu in LogViewDialog (#1578)
* Refactor: Replace Config.user() with getpass.getuser() (#1694)
Expand Down
10 changes: 10 additions & 0 deletions common/backintime.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@

parsers = {}

def warningOnTakeSnapshot(config):
hasMissing, missing = snapshots.hasMissing(config.include())
if hasMissing:
msgMissing = ', '.join(missing)
msg = f'{_("The following folders are missing")}: {msgMissing}'
logger.warning(msg)
return True

rafaelhdr marked this conversation as resolved.
Show resolved Hide resolved
def takeSnapshotAsync(cfg, checksum = False):
"""
Fork a new backintime process with 'backup' command which will
Expand All @@ -56,6 +64,7 @@ def takeSnapshotAsync(cfg, checksum = False):
Args:
cfg (config.Config): config that should be used
"""
warningOnTakeSnapshot(cfg)
rafaelhdr marked this conversation as resolved.
Show resolved Hide resolved
cmd = []
if cfg.ioniceOnUser():
cmd.extend(('ionice', '-c2', '-n7'))
Expand Down Expand Up @@ -94,6 +103,7 @@ def takeSnapshot(cfg, force = True):
Returns:
bool: ``True`` if there was an error
"""
warningOnTakeSnapshot(cfg)
rafaelhdr marked this conversation as resolved.
Show resolved Hide resolved
tools.envLoad(cfg.cronEnvFile())
ret = snapshots.Snapshots(cfg).backup(force)
return ret
Expand Down
8 changes: 8 additions & 0 deletions common/po/pt_BR.po
Original file line number Diff line number Diff line change
Expand Up @@ -1724,6 +1724,14 @@ msgstr "AVISO"
msgid "Exclude {path} from future snapshots?"
msgstr "Excluir {path} de snapshots futuros?"

#: qt/app.py:1189
msgid "The following folders are missing"
msgstr "As seguintes pastas estão faltando"

#: qt/app.py:1189
msgid "Do you want to proceed?"
msgstr "Deseja prosseguir?"

rafaelhdr marked this conversation as resolved.
Show resolved Hide resolved
#~ msgid " and add your user to group 'fuse'"
#~ msgstr " e adicionar seu usuário para grupo 'fuse'"

Expand Down
19 changes: 19 additions & 0 deletions common/snapshots.py
Original file line number Diff line number Diff line change
Expand Up @@ -3104,6 +3104,25 @@ def lastSnapshot(cfg):
return sids[0]


def hasMissing(included):
"""
Check if there are missing files or folders in a snapshot.

Args:
included (list): list of tuples (item, info)

Returns:
tuple: (bool, str) where bool is ``True`` if there are
missing files or folders and str is a message
describing the missing files or folders
"""
notFound = []
for path, info in included:
if not os.path.exists(path):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if os.path.exists() does also work for files (though folders are files), could you please (manually) check this with a configuration that contains a "missing" and an "existing" file (positive and negative test)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I just did it and it worked fine :)

I tested via CLI:

➜  /tmp cd /tmp                                                                                                                                                                                                                          /0.0s
➜  /tmp touch test.txt                                                                                                                                                                                                                   /0.0s
➜  /tmp python
Python 3.12.4 (main, Jun  7 2024, 06:33:07) [GCC 14.1.1 20240522] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.path.exists("/tmp")
True
>>> os.path.exists("/tmp/test.txt")
True
>>> os.path.exists("/wrong")
False
>>> os.path.exists("/tmp/wrong.txt")
False

I tested w/ CLI, and got correct results w/ this warning:

WARNING: The following **files/**folders are missing: /home/rafaelhdr/RMFolder, /home/rafaelhdr/RMFIle

And also via GUI with real snapshots (w/ existent folder, removed folder, existent file and removed file).

Screenshot from 2024-07-26 10-06-02

notFound.append(path)
return bool(notFound), notFound
rafaelhdr marked this conversation as resolved.
Show resolved Hide resolved


if __name__ == '__main__':
config = config.Config()
snapshots = Snapshots(config)
Expand Down
15 changes: 15 additions & 0 deletions qt/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1182,11 +1182,26 @@ def updateTimeLine(self, refreshSnapshotsList = True):
item = self.timeLine.addSnapshot(sid)
self.timeLine.checkSelection()

def validateOnTakeSnapshot(self):
hasMissing, missing = snapshots.hasMissing(self.config.include())
if hasMissing:
msgMissing = '\n'.join(missing)
msg = f'{_("The following folders are missing")}:\n\n{msgMissing}\n\n{_("Do you want to proceed?")}'
rafaelhdr marked this conversation as resolved.
Show resolved Hide resolved
answer = messagebox.warningYesNo(self, msg)
buhtz marked this conversation as resolved.
Show resolved Hide resolved
return answer == QMessageBox.StandardButton.Yes
return True

def btnTakeSnapshotClicked(self):
proceed = self.validateOnTakeSnapshot()
if not proceed:
return
backintime.takeSnapshotAsync(self.config)
self.updateTakeSnapshot(True)

def btnTakeSnapshotChecksumClicked(self):
proceed = self.validateOnTakeSnapshot()
if not proceed:
return
backintime.takeSnapshotAsync(self.config, checksum = True)
self.updateTakeSnapshot(True)
rafaelhdr marked this conversation as resolved.
Show resolved Hide resolved

Expand Down