Repository: pytorch/ignite

Issue:
Checkpoint handler save files with wrong permissions
## 🐛 Bug description

Hi @vfdev-5 ,

We always run programs in dockers, usually it's root user, and found an issue that: pure PyTorch program saves model(torch.save) and has the read permission for non-root users, but ignite Checkpoint handler saves model and only has read permission for root users.
You can reproduce this issue by below 2 MONAI examples:
1. https://github.com/Project-MONAI/tutorials/blob/master/3d_segmentation/torch/unet_training_dict.py
The saved model will be:
```
-rw-r--r-- 1 root root 19253862 Mar 26 02:08 best_metric_model_segmentation3d_dict.pth
```
2. https://github.com/Project-MONAI/tutorials/blob/master/3d_segmentation/ignite/unet_training_dict.py
The saved model will be:
```
-rw------- 1 root root 57738580 Mar 26 01:54 net_checkpoint_50.pt
```

ignite version is 0.4.4, could you please help take a look at this issue?
As we are close to MONAI and Clara next release, it's an urgent bug for us.

Thanks in advance.


Discussion:
sdesrozis: It misses mkl libs for tpu...
vfdev-5: I think it is the new pytorch release that fails our ci :)

Patch:
diff --git a/ignite/handlers/checkpoint.py b/ignite/handlers/checkpoint.py
index d503615e..8f3c0594 100644
--- a/ignite/handlers/checkpoint.py
+++ b/ignite/handlers/checkpoint.py
@@ -1,6 +1,7 @@
 import collections.abc as collections
 import numbers
 import os
+import stat
 import tempfile
 import warnings
 from abc import ABCMeta, abstractmethod
@@ -708,7 +709,9 @@ class DiskSaver(BaseSaveHandler):
             else:
                 if tmp is not None:
                     tmp.close()
-                    os.rename(tmp.name, path)
+                    os.replace(tmp.name, path)
+                    # append group/others read mode
+                    os.chmod(path, os.stat(path).st_mode | stat.S_IRGRP | stat.S_IROTH)
 
     @idist.one_rank_only()
     def remove(self, filename: str) -> None:


Test patch:
diff --git a/tests/ignite/handlers/test_checkpoint.py b/tests/ignite/handlers/test_checkpoint.py
index 2f1a3ff9..f21f1f6a 100644
--- a/tests/ignite/handlers/test_checkpoint.py
+++ b/tests/ignite/handlers/test_checkpoint.py
@@ -1,4 +1,5 @@
 import os
+import stat
 import warnings
 from collections import OrderedDict
 from unittest.mock import MagicMock
@@ -581,6 +582,12 @@ def test_disk_saver_atomic(dirname):
             pass
         fp = os.path.join(saver.dirname, fname)
         assert os.path.exists(fp) == expected
+
+        if expected:
+            # related to https://github.com/pytorch/ignite/issues/1876
+            mode = stat.filemode(os.stat(fp).st_mode)
+            assert [mode[1], mode[4], mode[7]] == ["r", "r", "r"], mode
+
         if expected:
             saver.remove(fname)