)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"0102c78b2956e6b97450f4e93e746f254c98b164","unresolved":false,"context_lines":[{"line_number":11,"context_line":"bios configuration state."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"These devices can no longer be disabled from the bios settings"},{"line_number":14,"context_line":"so the simplest course of action seem sot be to handle the"},{"line_number":15,"context_line":"existence of a read-only device."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"In the event of secure erase, this is treated as a hard failure"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3fa7e38b_8db790d7","line":14,"updated":"2020-01-29 18:17:38.000000000","message":"nit: typo","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"}],"ironic_python_agent/hardware.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3a75e8866f98b6c2b8364324fe939ae87b777de9","unresolved":false,"context_lines":[{"line_number":1161,"context_line":"        :returns: True if the device is read-only."},{"line_number":1162,"context_line":"        \"\"\""},{"line_number":1163,"context_line":"        try:"},{"line_number":1164,"context_line":"            dev_name \u003d str(block_device.name).lstrip(\u0027/dev/\u0027)"},{"line_number":1165,"context_line":""},{"line_number":1166,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1167,"context_line":"                flag \u003d f.read().strip()"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_351cac79","line":1164,"updated":"2020-01-29 08:04:25.000000000","message":"*strip accepts a list of characters to strip, not a string. It sort of works here, but is dangerous.","commit_id":"1081f2c3e5b0c6b1c5103d961bea56e88a0a6684"},{"author":{"_account_id":23851,"name":"Riccardo Pittau","email":"elfosardo@gmail.com","username":"elfosardo"},"change_message_id":"bfba38cfe8e0365772c900559d1d9210593f63b5","unresolved":false,"context_lines":[{"line_number":1161,"context_line":"        :returns: True if the device is read-only."},{"line_number":1162,"context_line":"        \"\"\""},{"line_number":1163,"context_line":"        try:"},{"line_number":1164,"context_line":"            dev_name \u003d str(block_device.name).lstrip(\u0027/dev/\u0027)"},{"line_number":1165,"context_line":""},{"line_number":1166,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1167,"context_line":"                flag \u003d f.read().strip()"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_38d4a34a","line":1164,"in_reply_to":"3fa7e38b_351cac79","updated":"2020-01-29 08:20:25.000000000","message":"if the device always starts with /dev/, we could even use str(block_device.name)[5:]","commit_id":"1081f2c3e5b0c6b1c5103d961bea56e88a0a6684"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"5919e461bec9ff110b944105dfb9e1c2676e25ad","unresolved":false,"context_lines":[{"line_number":1161,"context_line":"        :returns: True if the device is read-only."},{"line_number":1162,"context_line":"        \"\"\""},{"line_number":1163,"context_line":"        try:"},{"line_number":1164,"context_line":"            dev_name \u003d str(block_device.name).lstrip(\u0027/dev/\u0027)"},{"line_number":1165,"context_line":""},{"line_number":1166,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1167,"context_line":"                flag \u003d f.read().strip()"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_67e596a2","line":1164,"in_reply_to":"3fa7e38b_38d4a34a","updated":"2020-01-29 14:28:56.000000000","message":"Gah, I need a rule in our tox ruels that flags lstrip/rstrip usage by me....","commit_id":"1081f2c3e5b0c6b1c5103d961bea56e88a0a6684"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3a75e8866f98b6c2b8364324fe939ae87b777de9","unresolved":false,"context_lines":[{"line_number":1168,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1169,"context_line":"                    return True"},{"line_number":1170,"context_line":"        except IOError:"},{"line_number":1171,"context_line":"            LOG.warning(\"Could not determine if %s is a read-only device\","},{"line_number":1172,"context_line":"                        block_device.name)"},{"line_number":1173,"context_line":"        return False"},{"line_number":1174,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_b5197c87","line":1171,"updated":"2020-01-29 08:04:25.000000000","message":"nit: let\u0027s log the error message","commit_id":"1081f2c3e5b0c6b1c5103d961bea56e88a0a6684"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"6502b4705b3ba3adbc93fb7aec724b9a36703ef6","unresolved":false,"context_lines":[{"line_number":1163,"context_line":"        try:"},{"line_number":1164,"context_line":"            dev_name \u003d str(block_device.name)[5:]"},{"line_number":1165,"context_line":""},{"line_number":1166,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1167,"context_line":"                flag \u003d f.read().strip()"},{"line_number":1168,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1169,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_f2cb7f6f","line":1166,"updated":"2020-01-29 17:06:14.000000000","message":"Do failed-SSDs mounting as read only show up here? If so, this workaround could lead to a security issue where drives aren\u0027t wiped.","commit_id":"8a25bfc5e82e3cc1f71e5e4c162b5b9232ac268e"},{"author":{"_account_id":10342,"name":"Jay Faulkner","display_name":"JayF","email":"jay@jvf.cc","username":"JayF","status":"youtube.com/@oss-gr / podcast.gr-oss.io"},"change_message_id":"5ce02e8ac46dbdf3e3fdcc8eeeb473ed292365d7","unresolved":false,"context_lines":[{"line_number":1163,"context_line":"        try:"},{"line_number":1164,"context_line":"            dev_name \u003d str(block_device.name)[5:]"},{"line_number":1165,"context_line":""},{"line_number":1166,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1167,"context_line":"                flag \u003d f.read().strip()"},{"line_number":1168,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1169,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_725eaf79","line":1166,"in_reply_to":"3fa7e38b_9289eb25","updated":"2020-01-29 17:20:35.000000000","message":"From my IRC comments:\n\nI have a previous experience from many years ago, where a failing SSD went into firmware-read-only and linux eventually marked it as read-only after enough I/O errors. That experience is why I\u0027m concerned about this case.","commit_id":"8a25bfc5e82e3cc1f71e5e4c162b5b9232ac268e"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"2a3212f6846eb1ab0c42e582332cd9b736332b49","unresolved":false,"context_lines":[{"line_number":1163,"context_line":"        try:"},{"line_number":1164,"context_line":"            dev_name \u003d str(block_device.name)[5:]"},{"line_number":1165,"context_line":""},{"line_number":1166,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1167,"context_line":"                flag \u003d f.read().strip()"},{"line_number":1168,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1169,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_9289eb25","line":1166,"in_reply_to":"3fa7e38b_f2cb7f6f","updated":"2020-01-29 17:09:10.000000000","message":"I think the only way to know is to brick and SSD and see.... If memory serves, the device is not even visible as a disk when it is booted in a security locked state which should mean there is no ro flag file.","commit_id":"8a25bfc5e82e3cc1f71e5e4c162b5b9232ac268e"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0f0b2671737c3f619c9fdd1c105a4dbd4197de56","unresolved":false,"context_lines":[{"line_number":1029,"context_line":"                       \u0027conductor has not signaled this is a permitted \u0027"},{"line_number":1030,"context_line":"                       \u0027case.\u0027 % {\u0027device\u0027: block_device.name})"},{"line_number":1031,"context_line":"                LOG.error(msg)"},{"line_number":1032,"context_line":"                raise errors.BlockDeviceEraseError(msg)"},{"line_number":1033,"context_line":"        # Note(TheJulia) Use try/except to capture and log the failure"},{"line_number":1034,"context_line":"        # and then revert to attempting to shred the volume if enabled."},{"line_number":1035,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_5ee13531","line":1032,"range":{"start_line":1032,"start_character":0,"end_line":1032,"end_character":55},"updated":"2020-01-30 10:29:05.000000000","message":"Given that we\u0027re going to backport this, will it be a bit safer to just to LOG.warning here and proceed? It will prevent false negatives if something is wrongly declared \u0027ro\u0027?","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"8265fad39e20336dbd815181a3a0c6b4c7d0e920","unresolved":false,"context_lines":[{"line_number":1029,"context_line":"                       \u0027conductor has not signaled this is a permitted \u0027"},{"line_number":1030,"context_line":"                       \u0027case.\u0027 % {\u0027device\u0027: block_device.name})"},{"line_number":1031,"context_line":"                LOG.error(msg)"},{"line_number":1032,"context_line":"                raise errors.BlockDeviceEraseError(msg)"},{"line_number":1033,"context_line":"        # Note(TheJulia) Use try/except to capture and log the failure"},{"line_number":1034,"context_line":"        # and then revert to attempting to shred the volume if enabled."},{"line_number":1035,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_41f075fd","line":1032,"range":{"start_line":1032,"start_character":0,"end_line":1032,"end_character":55},"in_reply_to":"3fa7e38b_5ee13531","updated":"2020-01-30 14:02:42.000000000","message":"If a device is wrongly declared RO, then it is likely failed or something fishy that should have already failed in the code path.","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"0102c78b2956e6b97450f4e93e746f254c98b164","unresolved":false,"context_lines":[{"line_number":1173,"context_line":""},{"line_number":1174,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1175,"context_line":"                flag \u003d f.read().strip()"},{"line_number":1176,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1177,"context_line":"                    return True"},{"line_number":1178,"context_line":"        except IOError as e:"},{"line_number":1179,"context_line":"            LOG.warning(\"Could not determine if %s is a read-only device. \""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_2df8dc7b","line":1176,"updated":"2020-01-29 18:17:38.000000000","message":"would it be more secure to always fail unless this `ro` file is read and contains `0`?\n\nFail close, so to speak.","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"7711d783458f84b4d810d7a0f10472b46b2803b4","unresolved":false,"context_lines":[{"line_number":1173,"context_line":""},{"line_number":1174,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1175,"context_line":"                flag \u003d f.read().strip()"},{"line_number":1176,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1177,"context_line":"                    return True"},{"line_number":1178,"context_line":"        except IOError as e:"},{"line_number":1179,"context_line":"            LOG.warning(\"Could not determine if %s is a read-only device. \""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_4868a6f1","line":1176,"in_reply_to":"3fa7e38b_2df8dc7b","updated":"2020-01-29 23:19:28.000000000","message":"Effectively only going to return true if the device is read-only, so I think in essence it does because otherwise it would be swapping around the entire meaning.","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"67f664fbb93e7671357bb903f173c2d7c4997cbb","unresolved":false,"context_lines":[{"line_number":1173,"context_line":""},{"line_number":1174,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1175,"context_line":"                flag \u003d f.read().strip()"},{"line_number":1176,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1177,"context_line":"                    return True"},{"line_number":1178,"context_line":"        except IOError as e:"},{"line_number":1179,"context_line":"            LOG.warning(\"Could not determine if %s is a read-only device. \""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_be8709b4","line":1176,"in_reply_to":"3fa7e38b_3eceb92c","updated":"2020-01-30 11:08:26.000000000","message":"No, scratch that! I now think we are good with the code at hand.","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ab150b909072b6fe144457947950d080e7a8ea11","unresolved":false,"context_lines":[{"line_number":1173,"context_line":""},{"line_number":1174,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1175,"context_line":"                flag \u003d f.read().strip()"},{"line_number":1176,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1177,"context_line":"                    return True"},{"line_number":1178,"context_line":"        except IOError as e:"},{"line_number":1179,"context_line":"            LOG.warning(\"Could not determine if %s is a read-only device. \""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_b33f42b1","line":1176,"in_reply_to":"3fa7e38b_4868a6f1","updated":"2020-01-30 09:12:22.000000000","message":"Let me rephrase:\n\n    def _is_read_only_device(fl):\n        if open(fl).read().strip() \u003d\u003d \u00270\u0027:\n            return False\n        else:\n            return True\n\nAssuming the decision made by this function can have security implications, it seemingly makes sense to play it safe i.e. take the dangerous path (which is to report rw) only if everything worked out.","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0f0b2671737c3f619c9fdd1c105a4dbd4197de56","unresolved":false,"context_lines":[{"line_number":1173,"context_line":""},{"line_number":1174,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1175,"context_line":"                flag \u003d f.read().strip()"},{"line_number":1176,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1177,"context_line":"                    return True"},{"line_number":1178,"context_line":"        except IOError as e:"},{"line_number":1179,"context_line":"            LOG.warning(\"Could not determine if %s is a read-only device. \""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_beadc9e8","line":1176,"in_reply_to":"3fa7e38b_b33f42b1","updated":"2020-01-30 10:29:05.000000000","message":"We already default to assuming \u0027rw\u0027, not sure what your proposal improves.","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"0edbed16e5895f50d9c1c34eb65d92d1d3dacbf1","unresolved":false,"context_lines":[{"line_number":1173,"context_line":""},{"line_number":1174,"context_line":"            with open(\u0027/sys/block/%s/ro\u0027 % dev_name, \u0027r\u0027) as f:"},{"line_number":1175,"context_line":"                flag \u003d f.read().strip()"},{"line_number":1176,"context_line":"                if flag \u003d\u003d \u00271\u0027:"},{"line_number":1177,"context_line":"                    return True"},{"line_number":1178,"context_line":"        except IOError as e:"},{"line_number":1179,"context_line":"            LOG.warning(\"Could not determine if %s is a read-only device. \""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_3eceb92c","line":1176,"in_reply_to":"3fa7e38b_beadc9e8","updated":"2020-01-30 11:02:06.000000000","message":"I am thinking that defaulting to \u0027ro\u0027 is safer than defaulting to \u0027rw\u0027.\n\nBecause \u0027ro\u0027 fails cleaning rather than handing over potentially non-cleaned node to the next tenant.","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"7711d783458f84b4d810d7a0f10472b46b2803b4","unresolved":false,"context_lines":[{"line_number":1019,"context_line":"            return"},{"line_number":1020,"context_line":"        info \u003d node.get(\u0027driver_internal_info\u0027, {})"},{"line_number":1021,"context_line":"        if self._is_read_only_device(block_device):"},{"line_number":1022,"context_line":"            if info.get(\u0027agent_erase_skip_read_only\u0027, False):"},{"line_number":1023,"context_line":"                LOG.info(\"Skipping erase of read-only device %s\","},{"line_number":1024,"context_line":"                         block_device.name)"},{"line_number":1025,"context_line":"                return"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_c4fb1e47","line":1022,"range":{"start_line":1022,"start_character":25,"end_line":1022,"end_character":51},"updated":"2020-01-29 23:19:28.000000000","message":"This will need to be added via an ironic patch, but doesn\u0027t block this from merging.","commit_id":"cd7b2693f873bde72706f8b6ab8c1f21e68f0fd1"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"0f0b2671737c3f619c9fdd1c105a4dbd4197de56","unresolved":false,"context_lines":[{"line_number":1019,"context_line":"            return"},{"line_number":1020,"context_line":"        info \u003d node.get(\u0027driver_internal_info\u0027, {})"},{"line_number":1021,"context_line":"        if self._is_read_only_device(block_device):"},{"line_number":1022,"context_line":"            if info.get(\u0027agent_erase_skip_read_only\u0027, False):"},{"line_number":1023,"context_line":"                LOG.info(\"Skipping erase of read-only device %s\","},{"line_number":1024,"context_line":"                         block_device.name)"},{"line_number":1025,"context_line":"                return"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_7ecf51b2","line":1022,"range":{"start_line":1022,"start_character":25,"end_line":1022,"end_character":51},"in_reply_to":"3fa7e38b_c4fb1e47","updated":"2020-01-30 10:29:05.000000000","message":"Agreed","commit_id":"cd7b2693f873bde72706f8b6ab8c1f21e68f0fd1"}],"releasenotes/notes/fix-cleaning-read-only-device-c8a0f4cc2f434d99.yaml":[{"author":{"_account_id":23851,"name":"Riccardo Pittau","email":"elfosardo@gmail.com","username":"elfosardo"},"change_message_id":"d4bb04ed8f26a86c49bb4b0638ebfd1d39680a31","unresolved":false,"context_lines":[{"line_number":2,"context_line":"fixes:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Fixes an issue where cleaning would fail on devices that are read-only at"},{"line_number":5,"context_line":"    the hadware level. Typically these are virtual devices being offered to"},{"line_number":6,"context_line":"    the operating system for purposes like OS self-installation."}],"source_content_type":"text/x-yaml","patch_set":2,"id":"3fa7e38b_12a65b0e","line":5,"range":{"start_line":5,"start_character":8,"end_line":5,"end_character":15},"updated":"2020-01-29 16:52:43.000000000","message":"nit: hardware","commit_id":"8a25bfc5e82e3cc1f71e5e4c162b5b9232ac268e"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"0102c78b2956e6b97450f4e93e746f254c98b164","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"fixes:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Fixes an issue where cleaning would fail on devices that are read-only at"},{"line_number":5,"context_line":"    the hadware level. Typically these are virtual devices being offered to"},{"line_number":6,"context_line":"    the operating system for purposes like OS self-installation."}],"source_content_type":"text/x-yaml","patch_set":3,"id":"3fa7e38b_ed688422","line":4,"updated":"2020-01-29 18:17:38.000000000","message":"Will ironic still fail cleaning if a read-only device is hit?","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"dd49dd87f30e8aef642bcaa9be09a80757dbc0ec","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"fixes:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Fixes an issue where cleaning would fail on devices that are read-only at"},{"line_number":5,"context_line":"    the hadware level. Typically these are virtual devices being offered to"},{"line_number":6,"context_line":"    the operating system for purposes like OS self-installation."}],"source_content_type":"text/x-yaml","patch_set":3,"id":"3fa7e38b_ad784cc1","line":4,"in_reply_to":"3fa7e38b_ed688422","updated":"2020-01-29 18:27:47.000000000","message":"I need to revise this. I\u0027ll do it in a little bit.","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"0102c78b2956e6b97450f4e93e746f254c98b164","unresolved":false,"context_lines":[{"line_number":2,"context_line":"fixes:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Fixes an issue where cleaning would fail on devices that are read-only at"},{"line_number":5,"context_line":"    the hadware level. Typically these are virtual devices being offered to"},{"line_number":6,"context_line":"    the operating system for purposes like OS self-installation."}],"source_content_type":"text/x-yaml","patch_set":3,"id":"3fa7e38b_2d7bfcf2","line":5,"range":{"start_line":5,"start_character":8,"end_line":5,"end_character":15},"updated":"2020-01-29 18:17:38.000000000","message":"typo","commit_id":"ff3586c8e41cd8a7f0ec8a4f4bc2a2c6e4fbc956"}]}
