Skip to content

Commit 68c202d

Browse files
yebinamakonan-abhi
authored andcommitted
Image import "web-download" check downloaded size
If the downloaded data size is different from the expected one, the task "web-download" in the image import process will now fail. Change-Id: Ie260486d795a6f4af1632f6f3708abc92fb47a3a Closes-Bug: #1895663
1 parent ab15197 commit 68c202d

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

glance/async_/flows/_internal_plugins/web_download.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def __init__(self, task_id, task_type, image_repo, image_id, uri):
4141
self.image_repo = image_repo
4242
self.image_id = image_id
4343
self.uri = uri
44+
self._path = None
4445
super(_WebDownload, self).__init__(
4546
name='%s-WebDownload-%s' % (task_type, task_id))
4647

@@ -117,8 +118,19 @@ def execute(self):
117118
{"error": encodeutils.exception_to_unicode(e),
118119
"task_id": self.task_id})
119120

120-
path = self.store.add(self.image_id, data, 0)[0]
121-
return path
121+
self._path, bytes_written = self.store.add(self.image_id, data, 0)[0:2]
122+
try:
123+
content_length = int(data.headers['content-length'])
124+
if bytes_written != content_length:
125+
msg = (_("Task %(task_id)s failed because downloaded data "
126+
"size %(data_size)i is different from expected %("
127+
"expected)i") %
128+
{"task_id": self.task_id, "data_size": bytes_written,
129+
"expected": content_length})
130+
raise exception.ImportTaskError(msg)
131+
except (KeyError, ValueError):
132+
pass
133+
return self._path
122134

123135
def revert(self, result, **kwargs):
124136
if isinstance(result, failure.Failure):

glance/tests/unit/async_/flows/test_web_download.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,50 @@ def test_web_download(self, mock_add):
6666
self.image_id, self.uri)
6767
with mock.patch.object(script_utils,
6868
'get_image_data_iter') as mock_iter:
69-
mock_iter.return_value = b"dddd"
70-
web_download_task.execute()
71-
mock_add.assert_called_once_with(self.image_id, b"dddd", 0)
69+
mock_add.return_value = ["path", 4]
70+
mock_iter.return_value.headers = {}
71+
self.assertEqual(web_download_task.execute(), "path")
72+
mock_add.assert_called_once_with(self.image_id,
73+
mock_iter.return_value, 0)
74+
75+
@mock.patch.object(filesystem.Store, 'add')
76+
def test_web_download_with_content_length(self, mock_add):
77+
web_download_task = web_download._WebDownload(
78+
self.task.task_id, self.task_type, self.task_repo,
79+
self.image_id, self.uri)
80+
with mock.patch.object(script_utils,
81+
'get_image_data_iter') as mock_iter:
82+
mock_iter.return_value.headers = {'content-length': '4'}
83+
mock_add.return_value = ["path", 4]
84+
self.assertEqual(web_download_task.execute(), "path")
85+
mock_add.assert_called_once_with(self.image_id,
86+
mock_iter.return_value, 0)
87+
88+
@mock.patch.object(filesystem.Store, 'add')
89+
def test_web_download_with_invalid_content_length(self, mock_add):
90+
web_download_task = web_download._WebDownload(
91+
self.task.task_id, self.task_type, self.task_repo,
92+
self.image_id, self.uri)
93+
with mock.patch.object(script_utils,
94+
'get_image_data_iter') as mock_iter:
95+
mock_iter.return_value.headers = {'content-length': "not_valid"}
96+
mock_add.return_value = ["path", 4]
97+
self.assertEqual(web_download_task.execute(), "path")
98+
mock_add.assert_called_once_with(self.image_id,
99+
mock_iter.return_value, 0)
100+
101+
@mock.patch.object(filesystem.Store, 'add')
102+
def test_web_download_fails_when_data_size_different(self, mock_add):
103+
web_download_task = web_download._WebDownload(
104+
self.task.task_id, self.task_type, self.task_repo,
105+
self.image_id, self.uri)
106+
with mock.patch.object(script_utils,
107+
'get_image_data_iter') as mock_iter:
108+
mock_iter.return_value.headers = {'content-length': '4'}
109+
mock_add.return_value = ["path", 3]
110+
self.assertRaises(
111+
glance.common.exception.ImportTaskError,
112+
web_download_task.execute)
72113

73114
def test_web_download_node_staging_uri_is_none(self):
74115
self.config(node_staging_uri=None)

0 commit comments

Comments
 (0)