)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"5bc36a139a5b485015492f8027aa69e3b928b784","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Dmitry Tantsur \u003cdtantsur@redhat.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2014-04-18 19:33:56 +0200"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Implement caching for master images"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch introduces caching for master images."},{"line_number":10,"context_line":"Images are eligable for deletion, if their link count equals 1."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":8,"id":"AAAAXH%2F%2FoM4%3D","line":7,"updated":"2014-04-18 18:20:45.000000000","message":"there was already some rudimentary caching in place -- so this is misleading.\n\nThe patch may improve caching, or it may cache after the instance is deleted, but afaict the existing code already reused a cached image if \u003e1 instance required it.","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"20e33eb0a2691b25ea465b309247bee3afe6a734","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Dmitry Tantsur \u003cdtantsur@redhat.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2014-04-18 19:33:56 +0200"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Implement caching for master images"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch introduces caching for master images."},{"line_number":10,"context_line":"Images are eligable for deletion, if their link count equals 1."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":8,"id":"AAAAXH%2F%2Fn28%3D","line":7,"in_reply_to":"AAAAXH%2F%2FoM4%3D","updated":"2014-04-18 18:35:29.000000000","message":"Done","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"b55bc0c645f27b0b4de1179eb1042aa909da6a44","unresolved":false,"context_lines":[{"line_number":18,"context_line":"  into configurable value or no more images eligable for deletion."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"In the follow-up patch, we need to include Glance checksum into file name"},{"line_number":21,"context_line":"so when image is changed in Glance, it will always be redownloaded."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"As this change required rethinking how we cache images, I also"},{"line_number":24,"context_line":"did a refactor and grouped related functions under ImageCache class."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"bad4c104_f201863a","line":21,"updated":"2014-04-29 14:38:55.000000000","message":"We decided in IRC that this is not necessary, so this paragraph should be removed.","commit_id":"ba6d0229f0a39dbace5773a1cf87f753b5cc90f2"}],"ironic/drivers/modules/image_cache.py":[{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"5bc36a139a5b485015492f8027aa69e3b928b784","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        master_file_name \u003d service_utils.parse_image_ref(uuid)[0]"},{"line_number":62,"context_line":"        master_path \u003d os.path.join(self._master_dir, master_file_name)"},{"line_number":63,"context_line":"        if _link_image(master_path, dest_path):"},{"line_number":64,"context_line":"            # Master image was present - clean up cache and exit"},{"line_number":65,"context_line":"            # Cache does not grow on this path - not cleaning up"},{"line_number":66,"context_line":"            return"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2FoFI%3D","line":64,"updated":"2014-04-18 18:20:45.000000000","message":"these two comments are contradictory","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"20e33eb0a2691b25ea465b309247bee3afe6a734","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        master_file_name \u003d service_utils.parse_image_ref(uuid)[0]"},{"line_number":62,"context_line":"        master_path \u003d os.path.join(self._master_dir, master_file_name)"},{"line_number":63,"context_line":"        if _link_image(master_path, dest_path):"},{"line_number":64,"context_line":"            # Master image was present - clean up cache and exit"},{"line_number":65,"context_line":"            # Cache does not grow on this path - not cleaning up"},{"line_number":66,"context_line":"            return"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn3Y%3D","line":64,"in_reply_to":"AAAAXH%2F%2FoFI%3D","updated":"2014-04-18 18:35:29.000000000","message":"Done","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"5bc36a139a5b485015492f8027aa69e3b928b784","unresolved":false,"context_lines":[{"line_number":76,"context_line":"                #TODO(ghe): logging when image cannot be created"},{"line_number":77,"context_line":"                fd, tmp_path \u003d tempfile.mkstemp(dir\u003dself._master_dir)"},{"line_number":78,"context_line":"                os.close(fd)"},{"line_number":79,"context_line":"                images.fetch_to_raw(self._ctx, uuid, tmp_path,"},{"line_number":80,"context_line":"                                    self._image_service)"},{"line_number":81,"context_line":"                _create_image(tmp_path, master_path, dest_path)"},{"line_number":82,"context_line":"            finally:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn%2Fo%3D","line":79,"updated":"2014-04-18 18:20:45.000000000","message":"you shouldn\u0027t be downloading while holding the @lockutils.synchronized(\u0027get_image\u0027, \u0027ironic-\u0027) lock -- you should release that lock as soon as the external lockfile is created.\n\nAs this stands, you\u0027ll be serializing *all* downloads.","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"20e33eb0a2691b25ea465b309247bee3afe6a734","unresolved":false,"context_lines":[{"line_number":76,"context_line":"                #TODO(ghe): logging when image cannot be created"},{"line_number":77,"context_line":"                fd, tmp_path \u003d tempfile.mkstemp(dir\u003dself._master_dir)"},{"line_number":78,"context_line":"                os.close(fd)"},{"line_number":79,"context_line":"                images.fetch_to_raw(self._ctx, uuid, tmp_path,"},{"line_number":80,"context_line":"                                    self._image_service)"},{"line_number":81,"context_line":"                _create_image(tmp_path, master_path, dest_path)"},{"line_number":82,"context_line":"            finally:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn3s%3D","line":79,"in_reply_to":"AAAAXH%2F%2Fn%2Fo%3D","updated":"2014-04-18 18:35:29.000000000","message":"It seems to me that neither fetch_image nor _download_image are protected by lockutils, only creating of lock file inside _try_lock_download","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"5bc36a139a5b485015492f8027aa69e3b928b784","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                _remove_download_lock(lock_file)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"            # We increased cache size - need to clean up"},{"line_number":86,"context_line":"            self.clean_up()"},{"line_number":87,"context_line":"        else:"},{"line_number":88,"context_line":"            # If the download of the image is in progress (lock file present)"},{"line_number":89,"context_line":"            # we wait until the lock disappears and create the link."}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2FoEQ%3D","line":86,"updated":"2014-04-18 18:20:45.000000000","message":"doing clean_up before deleting the lock file is going to delay other threads from using the downloaded file unnecessarily","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"20e33eb0a2691b25ea465b309247bee3afe6a734","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                _remove_download_lock(lock_file)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"            # We increased cache size - need to clean up"},{"line_number":86,"context_line":"            self.clean_up()"},{"line_number":87,"context_line":"        else:"},{"line_number":88,"context_line":"            # If the download of the image is in progress (lock file present)"},{"line_number":89,"context_line":"            # we wait until the lock disappears and create the link."}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn4M%3D","line":86,"in_reply_to":"AAAAXH%2F%2FoEQ%3D","updated":"2014-04-18 18:35:29.000000000","message":"lock is deleted on line 83 above","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"5bc36a139a5b485015492f8027aa69e3b928b784","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        listing \u003d (os.path.join(self._master_dir, x)"},{"line_number":111,"context_line":"                   for x in os.listdir(self._master_dir))"},{"line_number":112,"context_line":"        listing \u003d ((f, _last_used_time(f)) for f in listing"},{"line_number":113,"context_line":"                   if os.path.isfile(f) and os.stat(f).st_nlink \u003d\u003d 1)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"        survived \u003d self._clean_up_too_old(listing)"},{"line_number":116,"context_line":"        self._clean_up_ensure_cache_size(survived)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2FoL0%3D","line":113,"updated":"2014-04-18 18:20:45.000000000","message":"that this is not removing files with \u003e1 link is not clearly documented anywhere, and the method names here all indicate age, not link count, so it\u0027s not obvious reading the code either","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"20e33eb0a2691b25ea465b309247bee3afe6a734","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        listing \u003d (os.path.join(self._master_dir, x)"},{"line_number":111,"context_line":"                   for x in os.listdir(self._master_dir))"},{"line_number":112,"context_line":"        listing \u003d ((f, _last_used_time(f)) for f in listing"},{"line_number":113,"context_line":"                   if os.path.isfile(f) and os.stat(f).st_nlink \u003d\u003d 1)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"        survived \u003d self._clean_up_too_old(listing)"},{"line_number":116,"context_line":"        self._clean_up_ensure_cache_size(survived)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn3c%3D","line":113,"in_reply_to":"AAAAXH%2F%2FoL0%3D","updated":"2014-04-18 18:35:29.000000000","message":"Ok, will write a comment","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"5bc36a139a5b485015492f8027aa69e3b928b784","unresolved":false,"context_lines":[{"line_number":191,"context_line":"    \"\"\"Get image file lock to avoid downloading the same image"},{"line_number":192,"context_line":"    simultaneously."},{"line_number":193,"context_line":"    \"\"\""},{"line_number":194,"context_line":"    if not os.path.exists(lock_file):"},{"line_number":195,"context_line":"        open(lock_file, \u0027w\u0027)"},{"line_number":196,"context_line":"        return True"},{"line_number":197,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2FoIU%3D","line":194,"updated":"2014-04-18 18:20:45.000000000","message":"why is this using a lockfile, within @lockutils? lockutils already provides both thread-based and process-based lock mechanisms","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"20e33eb0a2691b25ea465b309247bee3afe6a734","unresolved":false,"context_lines":[{"line_number":191,"context_line":"    \"\"\"Get image file lock to avoid downloading the same image"},{"line_number":192,"context_line":"    simultaneously."},{"line_number":193,"context_line":"    \"\"\""},{"line_number":194,"context_line":"    if not os.path.exists(lock_file):"},{"line_number":195,"context_line":"        open(lock_file, \u0027w\u0027)"},{"line_number":196,"context_line":"        return True"},{"line_number":197,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn3A%3D","line":194,"in_reply_to":"AAAAXH%2F%2FoIU%3D","updated":"2014-04-18 18:35:29.000000000","message":"Here lockutils is protecting the moment between exists check and file creating. Will investigate, whether lock file can be replaced here completely, provided we want lock only one specific download","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"53fc692ee06c258656d55968cbed040fdc41be89","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        listing \u003d sorted(listing,"},{"line_number":159,"context_line":"                         key\u003dlambda entry: entry[1],"},{"line_number":160,"context_line":"                         reverse\u003dTrue)"},{"line_number":161,"context_line":"        total_listing \u003d (os.path.join(self._master_dir, f)"},{"line_number":162,"context_line":"                         for f in os.listdir(self._master_dir))"},{"line_number":163,"context_line":"        total_size \u003d sum(os.path.getsize(f)"},{"line_number":164,"context_line":"                         for f in total_listing)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FNao%3D","line":161,"updated":"2014-04-23 10:15:01.000000000","message":"total_listing will contain files with stat.st_nlink \u003e 1, it is correct?","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3db21d6da77b6645a43ef1b90c062ab6d63f8c99","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        listing \u003d sorted(listing,"},{"line_number":159,"context_line":"                         key\u003dlambda entry: entry[1],"},{"line_number":160,"context_line":"                         reverse\u003dTrue)"},{"line_number":161,"context_line":"        total_listing \u003d (os.path.join(self._master_dir, f)"},{"line_number":162,"context_line":"                         for f in os.listdir(self._master_dir))"},{"line_number":163,"context_line":"        total_size \u003d sum(os.path.getsize(f)"},{"line_number":164,"context_line":"                         for f in total_listing)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FMEY%3D","line":161,"in_reply_to":"AAAAXH%2F%2FMRc%3D","updated":"2014-04-23 13:17:17.000000000","message":"Indeed, that help is from previous implementation, will fix","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"b754d4496874351b3ae7b315b7d624b8d9016b3c","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        listing \u003d sorted(listing,"},{"line_number":159,"context_line":"                         key\u003dlambda entry: entry[1],"},{"line_number":160,"context_line":"                         reverse\u003dTrue)"},{"line_number":161,"context_line":"        total_listing \u003d (os.path.join(self._master_dir, f)"},{"line_number":162,"context_line":"                         for f in os.listdir(self._master_dir))"},{"line_number":163,"context_line":"        total_size \u003d sum(os.path.getsize(f)"},{"line_number":164,"context_line":"                         for f in total_listing)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FMRc%3D","line":161,"in_reply_to":"AAAAXH%2F%2FMjM%3D","updated":"2014-04-23 12:52:16.000000000","message":"But help string misinforms\n\n help\u003d\u0027Maximum size (in MiB) of cache for old master images\u0027\n                                          ^^^","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8d54eec8c99845dea8a74c037698cb5a33387840","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        listing \u003d sorted(listing,"},{"line_number":159,"context_line":"                         key\u003dlambda entry: entry[1],"},{"line_number":160,"context_line":"                         reverse\u003dTrue)"},{"line_number":161,"context_line":"        total_listing \u003d (os.path.join(self._master_dir, f)"},{"line_number":162,"context_line":"                         for f in os.listdir(self._master_dir))"},{"line_number":163,"context_line":"        total_size \u003d sum(os.path.getsize(f)"},{"line_number":164,"context_line":"                         for f in total_listing)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FMjM%3D","line":161,"in_reply_to":"AAAAXH%2F%2FNao%3D","updated":"2014-04-23 12:19:34.000000000","message":"Yes, so that we don\u0027t consider cache empty when actually we have gigs of files with links","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"53fc692ee06c258656d55968cbed040fdc41be89","unresolved":false,"context_lines":[{"line_number":163,"context_line":"        total_size \u003d sum(os.path.getsize(f)"},{"line_number":164,"context_line":"                         for f in total_listing)"},{"line_number":165,"context_line":"        while total_size \u003e self._cache_size and listing:"},{"line_number":166,"context_line":"            file_name, last_used, stat \u003d listing.pop()"},{"line_number":167,"context_line":"            try:"},{"line_number":168,"context_line":"                os.unlink(file_name)"},{"line_number":169,"context_line":"            except EnvironmentError:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FNds%3D","line":166,"updated":"2014-04-23 10:15:01.000000000","message":"I see \u0027stat\u0027 not present in l147.","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8d54eec8c99845dea8a74c037698cb5a33387840","unresolved":false,"context_lines":[{"line_number":163,"context_line":"        total_size \u003d sum(os.path.getsize(f)"},{"line_number":164,"context_line":"                         for f in total_listing)"},{"line_number":165,"context_line":"        while total_size \u003e self._cache_size and listing:"},{"line_number":166,"context_line":"            file_name, last_used, stat \u003d listing.pop()"},{"line_number":167,"context_line":"            try:"},{"line_number":168,"context_line":"                os.unlink(file_name)"},{"line_number":169,"context_line":"            except EnvironmentError:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FMjA%3D","line":166,"in_reply_to":"AAAAXH%2F%2FNds%3D","updated":"2014-04-23 12:19:34.000000000","message":"Good catch, I wonder how I missed it...","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"53fc692ee06c258656d55968cbed040fdc41be89","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        while total_size \u003e self._cache_size and listing:"},{"line_number":166,"context_line":"            file_name, last_used, stat \u003d listing.pop()"},{"line_number":167,"context_line":"            try:"},{"line_number":168,"context_line":"                os.unlink(file_name)"},{"line_number":169,"context_line":"            except EnvironmentError:"},{"line_number":170,"context_line":"                LOG.warn(_(\"Failed to unlink %(path)s while \""},{"line_number":171,"context_line":"                           \"cleaning cache dir %(dir)s\") %"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FNfI%3D","line":168,"updated":"2014-04-23 10:15:01.000000000","message":"There is inconsistency, we use utils.unlink_without_raise() w/o warning in l145.","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"f4af26358217028e799f94c1e602599b87d606b5","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        while total_size \u003e self._cache_size and listing:"},{"line_number":166,"context_line":"            file_name, last_used, stat \u003d listing.pop()"},{"line_number":167,"context_line":"            try:"},{"line_number":168,"context_line":"                os.unlink(file_name)"},{"line_number":169,"context_line":"            except EnvironmentError:"},{"line_number":170,"context_line":"                LOG.warn(_(\"Failed to unlink %(path)s while \""},{"line_number":171,"context_line":"                           \"cleaning cache dir %(dir)s\") %"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FLxg%3D","line":168,"in_reply_to":"AAAAXH%2F%2FMS4%3D","updated":"2014-04-23 13:48:22.000000000","message":"Ah, I remembered, we can\u0027t use utils.unlink_without_raise, because we subtract size only if removal succeeds","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3db21d6da77b6645a43ef1b90c062ab6d63f8c99","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        while total_size \u003e self._cache_size and listing:"},{"line_number":166,"context_line":"            file_name, last_used, stat \u003d listing.pop()"},{"line_number":167,"context_line":"            try:"},{"line_number":168,"context_line":"                os.unlink(file_name)"},{"line_number":169,"context_line":"            except EnvironmentError:"},{"line_number":170,"context_line":"                LOG.warn(_(\"Failed to unlink %(path)s while \""},{"line_number":171,"context_line":"                           \"cleaning cache dir %(dir)s\") %"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FMEQ%3D","line":168,"in_reply_to":"AAAAXH%2F%2FMS4%3D","updated":"2014-04-23 13:17:17.000000000","message":"ack","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"b754d4496874351b3ae7b315b7d624b8d9016b3c","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        while total_size \u003e self._cache_size and listing:"},{"line_number":166,"context_line":"            file_name, last_used, stat \u003d listing.pop()"},{"line_number":167,"context_line":"            try:"},{"line_number":168,"context_line":"                os.unlink(file_name)"},{"line_number":169,"context_line":"            except EnvironmentError:"},{"line_number":170,"context_line":"                LOG.warn(_(\"Failed to unlink %(path)s while \""},{"line_number":171,"context_line":"                           \"cleaning cache dir %(dir)s\") %"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FMS4%3D","line":168,"in_reply_to":"AAAAXH%2F%2FMi0%3D","updated":"2014-04-23 12:52:16.000000000","message":"I think ignore better because we have warning l177.","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8d54eec8c99845dea8a74c037698cb5a33387840","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        while total_size \u003e self._cache_size and listing:"},{"line_number":166,"context_line":"            file_name, last_used, stat \u003d listing.pop()"},{"line_number":167,"context_line":"            try:"},{"line_number":168,"context_line":"                os.unlink(file_name)"},{"line_number":169,"context_line":"            except EnvironmentError:"},{"line_number":170,"context_line":"                LOG.warn(_(\"Failed to unlink %(path)s while \""},{"line_number":171,"context_line":"                           \"cleaning cache dir %(dir)s\") %"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FMi0%3D","line":168,"in_reply_to":"AAAAXH%2F%2FNfI%3D","updated":"2014-04-23 12:19:34.000000000","message":"Indeed. What do you think would be better: to warn or to ignore?","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"53fc692ee06c258656d55968cbed040fdc41be89","unresolved":false,"context_lines":[{"line_number":174,"context_line":"                total_size -\u003d stat.st_size"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"        if total_size \u003e self._cache_size:"},{"line_number":177,"context_line":"            LOG.info(_(\"After cleaning up cache dir %(dir)s\""},{"line_number":178,"context_line":"                       \"cache size %(actual)d is still larger than \""},{"line_number":179,"context_line":"                       \"threshold %(expected)d\") %"},{"line_number":180,"context_line":"                     {\u0027dir\u0027: self._master_dir, \u0027actual\u0027: total_size,"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FNo4%3D","line":177,"updated":"2014-04-23 10:15:01.000000000","message":"Missing \" \" at end of line.","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"8d54eec8c99845dea8a74c037698cb5a33387840","unresolved":false,"context_lines":[{"line_number":174,"context_line":"                total_size -\u003d stat.st_size"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"        if total_size \u003e self._cache_size:"},{"line_number":177,"context_line":"            LOG.info(_(\"After cleaning up cache dir %(dir)s\""},{"line_number":178,"context_line":"                       \"cache size %(actual)d is still larger than \""},{"line_number":179,"context_line":"                       \"threshold %(expected)d\") %"},{"line_number":180,"context_line":"                     {\u0027dir\u0027: self._master_dir, \u0027actual\u0027: total_size,"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAXH%2F%2FMiw%3D","line":177,"in_reply_to":"AAAAXH%2F%2FNo4%3D","updated":"2014-04-23 12:19:34.000000000","message":"Done","commit_id":"1ef3e08ba6be81752eb813d5cd9d79bb7ffe11a5"},{"author":{"_account_id":7419,"name":"Imre Farkas","email":"farkas.imre@gmail.com","username":"ifarkas"},"change_message_id":"75eb2211cbf181280e8ea487cedd585a4b1ef3cc","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            else:"},{"line_number":92,"context_line":"                return"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"            self._download_image(uuid, master_path, dest_path)"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        # NOTE(dtantsur): we increased cache size - time to clean up"},{"line_number":97,"context_line":"        self.clean_up()"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAXX%2F%2F6p4%3D","line":94,"updated":"2014-04-25 10:12:11.000000000","message":"You need to pass ctx here as well.","commit_id":"3fe82a6171f10e140e4ad38d303b379c97dde49a"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"72b9ee08641f870540d2e54b40bd2219941e0d90","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            else:"},{"line_number":92,"context_line":"                return"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"            self._download_image(uuid, master_path, dest_path)"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"        # NOTE(dtantsur): we increased cache size - time to clean up"},{"line_number":97,"context_line":"        self.clean_up()"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAXX%2F%2F6Cw%3D","line":94,"in_reply_to":"AAAAXX%2F%2F6p4%3D","updated":"2014-04-25 11:47:44.000000000","message":"Oh, stupid me! Using too many mocks does let you down sometimes... Thanks, Imre!","commit_id":"3fe82a6171f10e140e4ad38d303b379c97dde49a"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"b55bc0c645f27b0b4de1179eb1042aa909da6a44","unresolved":false,"context_lines":[{"line_number":70,"context_line":"            return"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        #TODO(ghe): have hard links and counts the same behaviour in all fs"},{"line_number":73,"context_line":"        #TODO(dtantsur): include Glance checksum into file name"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        master_file_name \u003d service_utils.parse_image_ref(uuid)[0]"},{"line_number":76,"context_line":"        master_path \u003d os.path.join(self._master_dir, master_file_name)"}],"source_content_type":"text/x-python","patch_set":17,"id":"bad4c104_f2afc629","line":73,"updated":"2014-04-29 14:38:55.000000000","message":"Can be removed.","commit_id":"ba6d0229f0a39dbace5773a1cf87f753b5cc90f2"},{"author":{"_account_id":6623,"name":"Roman Prykhodchenko","email":"me@romcheg.me","username":"prykhodchenko"},"change_message_id":"d0c5d21b87c969ce63b17600042648789fc4c0ba","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        # serialize _all_ downloads; take general lock when required"},{"line_number":79,"context_line":"        # TODO(dtantsur): lock expiration time"},{"line_number":80,"context_line":"        with lockutils.lock(\u0027download-image:%s\u0027 % master_file_name, \u0027ironic-\u0027):"},{"line_number":81,"context_line":"            if os.path.exists(dest_path):"},{"line_number":82,"context_line":"                return"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":18,"id":"bad4c104_fb3ec128","line":81,"updated":"2014-04-29 15:54:25.000000000","message":"I think there should be some logging","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bca71da71032e62dc76eddd08785efa51741623a","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        # serialize _all_ downloads; take general lock when required"},{"line_number":79,"context_line":"        # TODO(dtantsur): lock expiration time"},{"line_number":80,"context_line":"        with lockutils.lock(\u0027download-image:%s\u0027 % master_file_name, \u0027ironic-\u0027):"},{"line_number":81,"context_line":"            if os.path.exists(dest_path):"},{"line_number":82,"context_line":"                return"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":18,"id":"9ad9bd40_fc5a404f","line":81,"in_reply_to":"bad4c104_fb3ec128","updated":"2014-04-30 09:53:31.000000000","message":"Done","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"},{"author":{"_account_id":6623,"name":"Roman Prykhodchenko","email":"me@romcheg.me","username":"prykhodchenko"},"change_message_id":"d0c5d21b87c969ce63b17600042648789fc4c0ba","unresolved":false,"context_lines":[{"line_number":85,"context_line":"                # NOTE(dtantsur): ensure we\u0027re not in the middle of clean up"},{"line_number":86,"context_line":"                with lockutils.lock(\u0027master_image\u0027, \u0027ironic-\u0027):"},{"line_number":87,"context_line":"                    os.link(master_path, dest_path)"},{"line_number":88,"context_line":"            except OSError:"},{"line_number":89,"context_line":"                pass"},{"line_number":90,"context_line":"            else:"},{"line_number":91,"context_line":"                return"}],"source_content_type":"text/x-python","patch_set":18,"id":"bad4c104_5befadb0","line":88,"updated":"2014-04-29 15:54:25.000000000","message":"Logging might be helpful here as well.","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bca71da71032e62dc76eddd08785efa51741623a","unresolved":false,"context_lines":[{"line_number":85,"context_line":"                # NOTE(dtantsur): ensure we\u0027re not in the middle of clean up"},{"line_number":86,"context_line":"                with lockutils.lock(\u0027master_image\u0027, \u0027ironic-\u0027):"},{"line_number":87,"context_line":"                    os.link(master_path, dest_path)"},{"line_number":88,"context_line":"            except OSError:"},{"line_number":89,"context_line":"                pass"},{"line_number":90,"context_line":"            else:"},{"line_number":91,"context_line":"                return"}],"source_content_type":"text/x-python","patch_set":18,"id":"9ad9bd40_3c55881d","line":88,"in_reply_to":"bad4c104_5befadb0","updated":"2014-04-30 09:53:31.000000000","message":"Done","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"},{"author":{"_account_id":6623,"name":"Roman Prykhodchenko","email":"me@romcheg.me","username":"prykhodchenko"},"change_message_id":"d0c5d21b87c969ce63b17600042648789fc4c0ba","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            self._download_image(uuid, master_path, dest_path, ctx\u003dctx)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        # NOTE(dtantsur): we increased cache size - time to clean up"},{"line_number":96,"context_line":"        self.clean_up()"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def _download_image(self, uuid, master_path, dest_path, ctx\u003dNone):"},{"line_number":99,"context_line":"        \"\"\"Download image from Glance and store at a given path."}],"source_content_type":"text/x-python","patch_set":18,"id":"bad4c104_9b093598","line":96,"updated":"2014-04-29 15:54:25.000000000","message":"My thoughts about cleaning up after fetching an image are the following:\n\nPros: If after fetching an image the size of the cache is bigger than allowed, it will fix be shrink.\n\nCons: If fetching an image is going to exceed the maximum cache size the cache should be cleaned up before that in order to prevent certain problems.\n\nTo catch all of the mentioned problems it is possible to check for the size of the image and invoke clean up before fetching the image whether the maximum size of the cache will be exceeded","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bca71da71032e62dc76eddd08785efa51741623a","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            self._download_image(uuid, master_path, dest_path, ctx\u003dctx)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        # NOTE(dtantsur): we increased cache size - time to clean up"},{"line_number":96,"context_line":"        self.clean_up()"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def _download_image(self, uuid, master_path, dest_path, ctx\u003dNone):"},{"line_number":99,"context_line":"        \"\"\"Download image from Glance and store at a given path."}],"source_content_type":"text/x-python","patch_set":18,"id":"9ad9bd40_371a036f","line":96,"in_reply_to":"bad4c104_9b093598","updated":"2014-04-30 09:53:31.000000000","message":"While it makes some sense, I suggest not bother with it here. My point is that there\u0027s already a way for cache to exceed cache_size many-many times, if all images in cache are required (link count \u003e1). So while we can do it (will create a follow-up, if you insist), that won\u0027t on it\u0027s own fix problems with disk usage. What do you think?","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"},{"author":{"_account_id":6623,"name":"Roman Prykhodchenko","email":"me@romcheg.me","username":"prykhodchenko"},"change_message_id":"d0c5d21b87c969ce63b17600042648789fc4c0ba","unresolved":false,"context_lines":[{"line_number":165,"context_line":"            file_name, last_used, stat \u003d listing.pop()"},{"line_number":166,"context_line":"            try:"},{"line_number":167,"context_line":"                os.unlink(file_name)"},{"line_number":168,"context_line":"            except EnvironmentError:"},{"line_number":169,"context_line":"                pass"},{"line_number":170,"context_line":"            else:"},{"line_number":171,"context_line":"                total_size -\u003d stat.st_size"}],"source_content_type":"text/x-python","patch_set":18,"id":"bad4c104_3b774904","line":168,"updated":"2014-04-29 15:54:25.000000000","message":"Logging might be useful here","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bca71da71032e62dc76eddd08785efa51741623a","unresolved":false,"context_lines":[{"line_number":165,"context_line":"            file_name, last_used, stat \u003d listing.pop()"},{"line_number":166,"context_line":"            try:"},{"line_number":167,"context_line":"                os.unlink(file_name)"},{"line_number":168,"context_line":"            except EnvironmentError:"},{"line_number":169,"context_line":"                pass"},{"line_number":170,"context_line":"            else:"},{"line_number":171,"context_line":"                total_size -\u003d stat.st_size"}],"source_content_type":"text/x-python","patch_set":18,"id":"9ad9bd40_17625fd8","line":168,"in_reply_to":"bad4c104_3b774904","updated":"2014-04-30 09:53:31.000000000","message":"Will do, though some time before (patchset 4 or around) I was asked to remove logging from here :)","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"}],"ironic/drivers/modules/pxe.py":[{"author":{"_account_id":8003,"name":"Aleksandr Gordeev","email":"agordeev@mirantis.com","username":"agordeev"},"change_message_id":"9c19b5c03b46db55728cd917c267b28ca86cf47f","unresolved":false,"context_lines":[{"line_number":266,"context_line":"        os.link(path, dest_path)"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"IMAGE_CACHE_SIZE \u003d 10  # TODO(dtantsur): should it be configurable?"},{"line_number":270,"context_line":""},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"@lockutils.synchronized(\u0027master_image\u0027, \u0027ironic-\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9SMA%3D","line":269,"updated":"2014-04-07 12:17:05.000000000","message":"Indeed, it should be configurable. I think it\u0027s worth adding to pxe_opts. At least I don\u0027t see any objection for keeping its value hardcoded","commit_id":"7e370cea94d7b7edf9d4e86285da6ae3fe406595"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"8eda1c4af74ea8b17b631c5737c01f3f148146ca","unresolved":false,"context_lines":[{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""},{"line_number":277,"context_line":"    listing \u003d ((f, os.stat(f)) for f in"},{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAW3%2F%2F9Ew%3D","line":276,"updated":"2014-04-09 09:31:08.000000000","message":"nit/suggestion: As we can disable the cache, I think it would make sense to avoid doing all this computation by checking the CONF.pxe.image_cache_size value before.\n\ne.g\n\nif CONF.pxe.image_cache_size \u003c\u003d 0:\n    return","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"616ca392bc6007ff6e7c433a16531ff30ab0ede4","unresolved":false,"context_lines":[{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""},{"line_number":277,"context_line":"    listing \u003d ((f, os.stat(f)) for f in"},{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAW3%2F%2F8NI%3D","line":276,"in_reply_to":"AAAAW3%2F%2F8fQ%3D","updated":"2014-04-09 10:57:16.000000000","message":"Oh I err \u003c/me slap face\u003e I see it there now... (Gotta drink more coffee)","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"eb68e69a7bf52fe3439e1078f899a0bd89676d45","unresolved":false,"context_lines":[{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""},{"line_number":277,"context_line":"    listing \u003d ((f, os.stat(f)) for f in"},{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAW3%2F%2F8fQ%3D","line":276,"in_reply_to":"AAAAW3%2F%2F8u0%3D","updated":"2014-04-09 10:20:53.000000000","message":"\u003eL284 will return an empty list\n\nonly if L283 removed. If cache disabled no images should be cached.","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"352eacb1a7336ac78cdaa13336841b3fac891a2e","unresolved":false,"context_lines":[{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""},{"line_number":277,"context_line":"    listing \u003d ((f, os.stat(f)) for f in"},{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAW3%2F%2F8u0%3D","line":276,"in_reply_to":"AAAAW3%2F%2F8zU%3D","updated":"2014-04-09 10:01:58.000000000","message":"Hi yuriy, I see your point, and I think I could argue about 0 meaning \u0027no cache\u0027.\n\nThe docstring says:\n\nhelp\u003d\u0027Number of old master images to cache, 0 to disable\u0027\n\nAnd with this implementation if CONF.pxe.image_cache_size is 0, the L284 will return an empty list and no images will be removed.","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"c42585a26277e2ea63681175219cedce7e3d55f4","unresolved":false,"context_lines":[{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""},{"line_number":277,"context_line":"    listing \u003d ((f, os.stat(f)) for f in"},{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAW3%2F%2F8zU%3D","line":276,"in_reply_to":"AAAAW3%2F%2F9Ew%3D","updated":"2014-04-09 09:48:56.000000000","message":"Lucas, we should do total cleanup for this case, not return.","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"49b0bd2cdd00d28fb93acc1ccc792657abf8c943","unresolved":false,"context_lines":[{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"},{"line_number":280,"context_line":"    to_unlink \u003d [f for (f, stat) in sorted(listing,"},{"line_number":281,"context_line":"                                           key\u003dlambda s: s[1].st_mtime)"},{"line_number":282,"context_line":"                 if stat.st_nlink \u003d\u003d 1]"},{"line_number":283,"context_line":"    if CONF.pxe.image_cache_size:"},{"line_number":284,"context_line":"        to_unlink \u003d to_unlink[:-CONF.pxe.image_cache_size]"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAWX%2F%2F%2Fzs%3D","line":281,"updated":"2014-04-07 23:56:07.000000000","message":"Wouldn\u0027t st_atime be more appropriate? If I downloaded an image a week ago but just used it 10 mins ago, I\u0027d think that image is more likely to be accessed again than an image I downloaded 3 days ago and haven\u0027t accessed since.","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"a0be818ea9847ad9ffff6e8a7360aebc962e87af","unresolved":false,"context_lines":[{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"},{"line_number":280,"context_line":"    to_unlink \u003d [f for (f, stat) in sorted(listing,"},{"line_number":281,"context_line":"                                           key\u003dlambda s: s[1].st_mtime)"},{"line_number":282,"context_line":"                 if stat.st_nlink \u003d\u003d 1]"},{"line_number":283,"context_line":"    if CONF.pxe.image_cache_size:"},{"line_number":284,"context_line":"        to_unlink \u003d to_unlink[:-CONF.pxe.image_cache_size]"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAWn%2F%2F9Ew%3D","line":281,"in_reply_to":"AAAAWX%2F%2F%2Fzs%3D","updated":"2014-04-08 09:17:38.000000000","message":"Josh, FS can be mounted with \u0027noatime\u0027 option.","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"8eda1c4af74ea8b17b631c5737c01f3f148146ca","unresolved":false,"context_lines":[{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"},{"line_number":280,"context_line":"    to_unlink \u003d [f for (f, stat) in sorted(listing,"},{"line_number":281,"context_line":"                                           key\u003dlambda s: s[1].st_mtime)"},{"line_number":282,"context_line":"                 if stat.st_nlink \u003d\u003d 1]"},{"line_number":283,"context_line":"    if CONF.pxe.image_cache_size:"},{"line_number":284,"context_line":"        to_unlink \u003d to_unlink[:-CONF.pxe.image_cache_size]"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAW3%2F%2F9FI%3D","line":281,"in_reply_to":"AAAAWn%2F%2F428%3D","updated":"2014-04-09 09:31:08.000000000","message":"good points about atime","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"056b09fe77f7d97695adcb483689e81824b0eecf","unresolved":false,"context_lines":[{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"},{"line_number":280,"context_line":"    to_unlink \u003d [f for (f, stat) in sorted(listing,"},{"line_number":281,"context_line":"                                           key\u003dlambda s: s[1].st_mtime)"},{"line_number":282,"context_line":"                 if stat.st_nlink \u003d\u003d 1]"},{"line_number":283,"context_line":"    if CONF.pxe.image_cache_size:"},{"line_number":284,"context_line":"        to_unlink \u003d to_unlink[:-CONF.pxe.image_cache_size]"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAWn%2F%2F428%3D","line":281,"in_reply_to":"AAAAWn%2F%2F5GQ%3D","updated":"2014-04-08 17:50:28.000000000","message":"Makes sense, thank you","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":10380,"name":"Josh Gachnang","email":"josh@pcsforeducation.com","username":"JoshNang"},"change_message_id":"678c21646e29a8a2e911a6e22658abe1dbaf316e","unresolved":false,"context_lines":[{"line_number":278,"context_line":"               (os.path.join(image_dir, f) for f in os.listdir(image_dir))"},{"line_number":279,"context_line":"               if os.path.isfile(f))"},{"line_number":280,"context_line":"    to_unlink \u003d [f for (f, stat) in sorted(listing,"},{"line_number":281,"context_line":"                                           key\u003dlambda s: s[1].st_mtime)"},{"line_number":282,"context_line":"                 if stat.st_nlink \u003d\u003d 1]"},{"line_number":283,"context_line":"    if CONF.pxe.image_cache_size:"},{"line_number":284,"context_line":"        to_unlink \u003d to_unlink[:-CONF.pxe.image_cache_size]"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAWn%2F%2F5GQ%3D","line":281,"in_reply_to":"AAAAWn%2F%2F9Ew%3D","updated":"2014-04-08 17:23:03.000000000","message":"This is true. I was under the impression that atime would get updated with mtime in that case (so they\u0027d always be the same), but I was mistaken. Something like \"lambda s: max(s[1].st_mtime, s[1].st_atime)\" would be best of both worlds.","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"8eda1c4af74ea8b17b631c5737c01f3f148146ca","unresolved":false,"context_lines":[{"line_number":280,"context_line":"    to_unlink \u003d [f for (f, stat) in sorted(listing,"},{"line_number":281,"context_line":"                                           key\u003dlambda s: s[1].st_mtime)"},{"line_number":282,"context_line":"                 if stat.st_nlink \u003d\u003d 1]"},{"line_number":283,"context_line":"    if CONF.pxe.image_cache_size:"},{"line_number":284,"context_line":"        to_unlink \u003d to_unlink[:-CONF.pxe.image_cache_size]"},{"line_number":285,"context_line":"    for file_name in to_unlink:"},{"line_number":286,"context_line":"        utils.unlink_without_raise(file_name)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAW3%2F%2F9DI%3D","line":283,"updated":"2014-04-09 09:31:08.000000000","message":"(continuing comment L276...)\n\nThis check would also be removed","commit_id":"2d15c9abca306ea2f61ba88f4f4bd8d5a63e377c"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"73a250b1a9e11c018ccb2a81910a327c4ed9f919","unresolved":false,"context_lines":[{"line_number":270,"context_line":""},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"@lockutils.synchronized(\u0027master_image\u0027, \u0027ironic-\u0027)"},{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAW3%2F%2F7B4%3D","line":273,"updated":"2014-04-09 13:29:53.000000000","message":"Maybe a problem with dir-based cleaning. If caching disabled and some images are downloading at this moment (stat.st_nlink \u003d\u003d 1) they will be removed.\n\nAs variant change l285 like:\n if image_file_name in to_unlink:","commit_id":"e945f098d2db1e6c4060d3d630b94d48a9424177"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"63b8a075baeaffccf47b701fdea844456c0b1c3e","unresolved":false,"context_lines":[{"line_number":270,"context_line":""},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"@lockutils.synchronized(\u0027master_image\u0027, \u0027ironic-\u0027)"},{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAW3%2F%2F6xc%3D","line":273,"in_reply_to":"AAAAW3%2F%2F68s%3D","updated":"2014-04-09 14:02:19.000000000","message":"Maybe use file-based cleaning like old code, we will check should be one image will be removed or not\n\n def _unlink_master_image(image_dir, image_uuid):\n ... your code\n\n file_path \u003d os.path.join(image_dir, image_uuid)\n if file_path in to_unlink:\n     utils.unlink_without_raise(file_path)","commit_id":"e945f098d2db1e6c4060d3d630b94d48a9424177"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"850334aa87eda74fe8b81cf96c15180ed9c8e428","unresolved":false,"context_lines":[{"line_number":270,"context_line":""},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"@lockutils.synchronized(\u0027master_image\u0027, \u0027ironic-\u0027)"},{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAW3%2F%2F6Rc%3D","line":273,"in_reply_to":"AAAAW3%2F%2F6dk%3D","updated":"2014-04-09 14:50:25.000000000","message":"This is intentional. The alternative would be to create background GC process, but this would be much more complicated, I think.","commit_id":"e945f098d2db1e6c4060d3d630b94d48a9424177"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"d4fe2b12937d13db90bb1208b6c65aa016aec0fe","unresolved":false,"context_lines":[{"line_number":270,"context_line":""},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"@lockutils.synchronized(\u0027master_image\u0027, \u0027ironic-\u0027)"},{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAW3%2F%2F6dk%3D","line":273,"in_reply_to":"AAAAW3%2F%2F6tQ%3D","updated":"2014-04-09 14:44:45.000000000","message":"Yes, after investigate the code I think there is no problem. But _clean_up_images() called only for clean_up() method for _one_ node, and not only images for this node can be deleted.","commit_id":"e945f098d2db1e6c4060d3d630b94d48a9424177"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"ad7c35dc79c625808ea1d4b584cc7a676aa9fed7","unresolved":false,"context_lines":[{"line_number":270,"context_line":""},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"@lockutils.synchronized(\u0027master_image\u0027, \u0027ironic-\u0027)"},{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAW3%2F%2F6tQ%3D","line":273,"in_reply_to":"AAAAW3%2F%2F6xc%3D","updated":"2014-04-09 14:09:31.000000000","message":"Yes, but who is going to clean images that did not fall into to_unlink _for now_?\n\nAgain, are you sure that @lockutils.synchronized(\u0027master_image\u0027, \u0027ironic-\u0027) does NOT prevent it? I see the same lock against _create_master_image and that makes me think that you\u0027ll never be simultaneously downloading (more precisely, moving downloaded file from temporary location), and cleaning up.","commit_id":"e945f098d2db1e6c4060d3d630b94d48a9424177"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"7b296c0541ac609db8dd6af4e22ed7dca7af7b81","unresolved":false,"context_lines":[{"line_number":270,"context_line":""},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"@lockutils.synchronized(\u0027master_image\u0027, \u0027ironic-\u0027)"},{"line_number":273,"context_line":"def _clean_up_images(image_dir):"},{"line_number":274,"context_line":"    \"\"\"Clean up directory with images, keeping small cache of"},{"line_number":275,"context_line":"    the latest images that no longer have links to them."},{"line_number":276,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAW3%2F%2F68s%3D","line":273,"in_reply_to":"AAAAW3%2F%2F7B4%3D","updated":"2014-04-09 13:36:19.000000000","message":"Ouch. That\u0027s a problem. Won\u0027t @lockutils.synchronized(\u0027master_image\u0027, \u0027ironic-\u0027) prevent it?\n\nThis variant will not work: someone has to clean this image_file_name afterwards.","commit_id":"e945f098d2db1e6c4060d3d630b94d48a9424177"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"5bc36a139a5b485015492f8027aa69e3b928b784","unresolved":false,"context_lines":[{"line_number":270,"context_line":"    image_cache \u003d PXEImageCache(CONF.pxe.tftp_master_path, ctx\u003dctx)"},{"line_number":271,"context_line":"    for label in pxe_info:"},{"line_number":272,"context_line":"        (uuid, path) \u003d pxe_info[label]"},{"line_number":273,"context_line":"        if not os.path.exists(path):"},{"line_number":274,"context_line":"            image_cache.fetch_image(uuid, path)"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn9w%3D","line":273,"updated":"2014-04-18 18:20:45.000000000","message":"this \"if not os.path.exists(path)\" is racey -- what if two threads pass this at the same time, and both start fetch_image?\n\nfetch_image() is providing the lock synchronization around concurrent downloads, so it should also handle checking if the requested file already exists, and then there would be no need for this if statement.","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"20e33eb0a2691b25ea465b309247bee3afe6a734","unresolved":false,"context_lines":[{"line_number":270,"context_line":"    image_cache \u003d PXEImageCache(CONF.pxe.tftp_master_path, ctx\u003dctx)"},{"line_number":271,"context_line":"    for label in pxe_info:"},{"line_number":272,"context_line":"        (uuid, path) \u003d pxe_info[label]"},{"line_number":273,"context_line":"        if not os.path.exists(path):"},{"line_number":274,"context_line":"            image_cache.fetch_image(uuid, path)"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn2U%3D","line":273,"in_reply_to":"AAAAXH%2F%2Fn9w%3D","updated":"2014-04-18 18:35:29.000000000","message":"Very good catch, thank you","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"5bc36a139a5b485015492f8027aa69e3b928b784","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    LOG.debug(_(\"Fetching image %(ami)s for node %(uuid)s\") %"},{"line_number":300,"context_line":"              {\u0027ami\u0027: uuid, \u0027uuid\u0027: node.uuid})"},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"    if not os.path.exists(image_path):"},{"line_number":303,"context_line":"        image_cache \u003d PXEImageCache(CONF.pxe.instance_master_path, ctx\u003dctx)"},{"line_number":304,"context_line":"        image_cache.fetch_image(uuid, image_path)"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn9s%3D","line":302,"updated":"2014-04-18 18:20:45.000000000","message":"ditto as above","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":2889,"name":"Aeva Black","email":"aeva.online@gmail.com","username":"tenbrae"},"change_message_id":"5bc36a139a5b485015492f8027aa69e3b928b784","unresolved":false,"context_lines":[{"line_number":553,"context_line":"        d_info \u003d _parse_driver_info(node)"},{"line_number":554,"context_line":"        for label in pxe_info:"},{"line_number":555,"context_line":"            path \u003d pxe_info[label][1]"},{"line_number":556,"context_line":"            utils.unlink_without_raise(path)"},{"line_number":557,"context_line":"        PXEImageCache(CONF.pxe.tftp_master_path).clean_up()"},{"line_number":558,"context_line":""},{"line_number":559,"context_line":"        utils.unlink_without_raise(_get_pxe_config_file_path("}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn8Q%3D","line":556,"updated":"2014-04-18 18:20:45.000000000","message":"because these files were created via the ImageCache() class, they need to be deleted that same way, to avoid dangling links and deleting files that other instances still need.","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"20e33eb0a2691b25ea465b309247bee3afe6a734","unresolved":false,"context_lines":[{"line_number":553,"context_line":"        d_info \u003d _parse_driver_info(node)"},{"line_number":554,"context_line":"        for label in pxe_info:"},{"line_number":555,"context_line":"            path \u003d pxe_info[label][1]"},{"line_number":556,"context_line":"            utils.unlink_without_raise(path)"},{"line_number":557,"context_line":"        PXEImageCache(CONF.pxe.tftp_master_path).clean_up()"},{"line_number":558,"context_line":""},{"line_number":559,"context_line":"        utils.unlink_without_raise(_get_pxe_config_file_path("}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2Fn2M%3D","line":556,"in_reply_to":"AAAAXH%2F%2Fn8Q%3D","updated":"2014-04-18 18:35:29.000000000","message":"Good catch also!","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"5c12161862efefd59d52e32cdc358411a36f9b59","unresolved":false,"context_lines":[{"line_number":553,"context_line":"        d_info \u003d _parse_driver_info(node)"},{"line_number":554,"context_line":"        for label in pxe_info:"},{"line_number":555,"context_line":"            path \u003d pxe_info[label][1]"},{"line_number":556,"context_line":"            utils.unlink_without_raise(path)"},{"line_number":557,"context_line":"        PXEImageCache(CONF.pxe.tftp_master_path).clean_up()"},{"line_number":558,"context_line":""},{"line_number":559,"context_line":"        utils.unlink_without_raise(_get_pxe_config_file_path("}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAXH%2F%2FWNo%3D","line":556,"in_reply_to":"AAAAXH%2F%2Fn8Q%3D","updated":"2014-04-22 11:57:07.000000000","message":"Hi, thought again about this, and I don\u0027t think it\u0027s necessary. These are per-node images, they are not handled by ImageCache (clean_up does not touch master images with links to them), not are they shared between instances. There could be a lot of useful refactoring here, but I don\u0027t think it\u0027s worse doing, provided master images caching will be eventually replaced by IPA","commit_id":"a02860604ffd086760a32b6522b7fc4422e7e082"},{"author":{"_account_id":6623,"name":"Roman Prykhodchenko","email":"me@romcheg.me","username":"prykhodchenko"},"change_message_id":"d0c5d21b87c969ce63b17600042648789fc4c0ba","unresolved":false,"context_lines":[{"line_number":73,"context_line":"    cfg.StrOpt(\u0027pxe_bootfile_name\u0027,"},{"line_number":74,"context_line":"               default\u003d\u0027pxelinux.0\u0027,"},{"line_number":75,"context_line":"               help\u003d\u0027Neutron bootfile DHCP parameter.\u0027),"},{"line_number":76,"context_line":"    cfg.IntOpt(\u0027image_cache_size\u0027,"},{"line_number":77,"context_line":"               default\u003d1024,"},{"line_number":78,"context_line":"               help\u003d\u0027Maximum size (in MiB) of cache for master images, \u0027"},{"line_number":79,"context_line":"               \u0027including those in use\u0027),"}],"source_content_type":"text/x-python","patch_set":18,"id":"bad4c104_d8ed838d","line":76,"updated":"2014-04-29 15:54:25.000000000","message":"I think it might be reasonable to move these options to the image_cache module.","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"bca71da71032e62dc76eddd08785efa51741623a","unresolved":false,"context_lines":[{"line_number":73,"context_line":"    cfg.StrOpt(\u0027pxe_bootfile_name\u0027,"},{"line_number":74,"context_line":"               default\u003d\u0027pxelinux.0\u0027,"},{"line_number":75,"context_line":"               help\u003d\u0027Neutron bootfile DHCP parameter.\u0027),"},{"line_number":76,"context_line":"    cfg.IntOpt(\u0027image_cache_size\u0027,"},{"line_number":77,"context_line":"               default\u003d1024,"},{"line_number":78,"context_line":"               help\u003d\u0027Maximum size (in MiB) of cache for master images, \u0027"},{"line_number":79,"context_line":"               \u0027including those in use\u0027),"}],"source_content_type":"text/x-python","patch_set":18,"id":"9ad9bd40_375f6310","line":76,"in_reply_to":"bad4c104_d8ed838d","updated":"2014-04-30 09:53:31.000000000","message":"Done","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"d31c0bb9ceb2ed723c0f414621cde70edbfaf00c","unresolved":false,"context_lines":[{"line_number":73,"context_line":"    cfg.StrOpt(\u0027pxe_bootfile_name\u0027,"},{"line_number":74,"context_line":"               default\u003d\u0027pxelinux.0\u0027,"},{"line_number":75,"context_line":"               help\u003d\u0027Neutron bootfile DHCP parameter.\u0027),"},{"line_number":76,"context_line":"    cfg.IntOpt(\u0027image_cache_size\u0027,"},{"line_number":77,"context_line":"               default\u003d1024,"},{"line_number":78,"context_line":"               help\u003d\u0027Maximum size (in MiB) of cache for master images, \u0027"},{"line_number":79,"context_line":"               \u0027including those in use\u0027),"}],"source_content_type":"text/x-python","patch_set":18,"id":"9ad9bd40_f7509b60","line":76,"in_reply_to":"bad4c104_d8ed838d","updated":"2014-04-30 10:09:28.000000000","message":"Thought again about it: what if we late reuse image_cache for something where these values are completely different? Or we decide to have different values for instance and tftp caches?","commit_id":"e9dbba4d031f747bf75cae62b627e36f04f91a7d"}],"ironic/tests/drivers/test_image_cache.py":[{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"9188051a50cfaa63cf8b6c7b9b77915bbb99798f","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        files \u003d [os.path.join(self.master_dir, str(i))"},{"line_number":119,"context_line":"                 for i in range(2)]"},{"line_number":120,"context_line":"        for filename in files:"},{"line_number":121,"context_line":"            open(filename, \u0027w\u0027).close()"},{"line_number":122,"context_line":"        # NOTE(dtantsur): Can\u0027t alter ctime, have to set mtime to the future"},{"line_number":123,"context_line":"        new_current_time \u003d time.time() + 900"},{"line_number":124,"context_line":"        os.utime(files[0], (new_current_time - 100, new_current_time - 100))"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAXX%2F%2FtoE%3D","line":121,"updated":"2014-04-28 14:25:14.000000000","message":"touch defined l29","commit_id":"c42b3192f83cd5fdd107c7c7651478f4a1d99c5c"},{"author":{"_account_id":7711,"name":"Yuriy Zveryanskyy","email":"yzveryanskyy@mirantis.com","username":"yuriyz"},"change_message_id":"9188051a50cfaa63cf8b6c7b9b77915bbb99798f","unresolved":false,"context_lines":[{"line_number":138,"context_line":"        files \u003d [os.path.join(self.master_dir, str(i))"},{"line_number":139,"context_line":"                 for i in range(2)]"},{"line_number":140,"context_line":"        for filename in files:"},{"line_number":141,"context_line":"            open(filename, \u0027w\u0027).close()"},{"line_number":142,"context_line":"            os.link(filename, filename + \u0027copy\u0027)"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"        new_current_time \u003d time.time() + 900"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAXX%2F%2FtnQ%3D","line":141,"updated":"2014-04-28 14:25:14.000000000","message":"ditto","commit_id":"c42b3192f83cd5fdd107c7c7651478f4a1d99c5c"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"b55bc0c645f27b0b4de1179eb1042aa909da6a44","unresolved":false,"context_lines":[{"line_number":158,"context_line":"                 for i in range(6)]"},{"line_number":159,"context_line":"        for filename in files:"},{"line_number":160,"context_line":"            with open(filename, \u0027w\u0027) as fp:"},{"line_number":161,"context_line":"                fp.write(\u0027123\u0027)"},{"line_number":162,"context_line":"        # NOTE(dtantsur): Make 3 files \u0027newer\u0027 to check that"},{"line_number":163,"context_line":"        # old ones are deleted first"},{"line_number":164,"context_line":"        new_current_time \u003d time.time() + 100"}],"source_content_type":"text/x-python","patch_set":17,"id":"bad4c104_d59e2c56","line":161,"updated":"2014-04-29 14:38:55.000000000","message":"Should we be actually writing to disk in unit tests?","commit_id":"ba6d0229f0a39dbace5773a1cf87f753b5cc90f2"}]}
