)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"d9cc629a79ace50b02996d214bdc3b863456e889","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"f85a7b3d_ef64bb22","updated":"2024-11-13 21:47:11.000000000","message":"For reference, this particular log is the reason I reverted to lazy importing the configdrive object only in the function it\u0027s needed, pretty sure that may not have been the \"best\" solution (?).\n\n```| Check: Database Index Status                                         |\n| Result: Success                                                      |\n| Details: None                                                        |\n+----------------------------------------------------------------------+\n| Check: Allocations Name Field Length Check                           |\n| Result: Success                                                      |\n| Details: None                                                        |\n+----------------------------------------------------------------------+\n| Check: Policy File JSON to YAML Migration                            |\n| Result: Success                                                      |\n| Details: None                                                        |\n+----------------------------------------------------------------------+\n| Check: Hardware Types and Interfaces Check                           |\n| Result: Failure                                                      |\n| Details: Some hardware types cannot be loaded: Driver, hardware type |\n|   or interface fake-hardware could not be loaded. Reason:            |\n|   cannot import name \u0027ConfigDrive\u0027 from \u0027ironic.objects\u0027             |\n|   (/opt/stack/ironic/ironic/objects/__init__.py).                    |\n+----------------------------------------------------------------------+\n+ /opt/stack/ironic/devstack/lib/ironic:init_ironic:1 :   exit_trap\n+ ./stack.sh:exit_trap:540                 :   local r\u003d2\n++ ./stack.sh:exit_trap:541                 :   jobs -p\n+ ./stack.sh:exit_trap:541                 :   jobs\u003d32840\n+ ./stack.sh:exit_trap:544                 :   [[ -n 32840 ]]\n+ ./stack.sh:exit_trap:544                 :   [[ -n /opt/stack/logs/devstacklog.txt.2024-11-01-153837 ]]\n+ ./stack.sh:exit_trap:544                 :   [[ True \u003d\u003d \\T\\r\\u\\e ]]\n+ ./stack.sh:exit_trap:545                 :   echo \u0027exit_trap: cleaning up child processes\u0027\nexit_trap: cleaning up child processes\n+ ./stack.sh:exit_trap:546                 :   kill 32840\n+ ./stack.sh:exit_trap:550                 :   \u0027[\u0027 -f /tmp/tmp.ve3AYmHTDA \u0027]\u0027\n+ ./stack.sh:exit_trap:551                 :   rm /tmp/tmp.ve3AYmHTDA\n+ ./stack.sh:exit_trap:555                 :   kill_spinner\n+ ./stack.sh:kill_spinner:450              :   \u0027[\u0027 \u0027!\u0027 -z \u0027\u0027 \u0027]\u0027\n+ ./stack.sh:exit_trap:557                 :   [[ 2 -ne 0 ]]\n+ ./stack.sh:exit_trap:558                 :   echo \u0027Error on exit\u0027\nError on exit\n+ ./stack.sh:exit_trap:560                 :   type -p generate-subunit\n+ ./stack.sh:exit_trap:561                 :   generate-subunit 1730475514 564 fail\n+ ./stack.sh:exit_trap:563                 :   [[ -z /opt/stack/logs ]]\n+ ./stack.sh:exit_trap:566                 :   /opt/stack/data/venv/bin/python3 /opt/stack/devstack/tools/worlddump.py -d /opt/stack/logs\n+ ./stack.sh:exit_trap:575                 :   exit 2\n*** FINISHED ***```","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"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":"d2f4510268a01853f0f83eed32f7a64ed3117e01","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"1440639f_59a055bc","updated":"2024-11-13 20:15:09.000000000","message":"Should we have an online data migration to move existing node[].instance_info{\u0027configdrive\u0027} fields into the new configdrive table. (probably no).\n\nThere\u0027s some API scaffolding missing here; how does a operator see the configdrive now? We sanitize it away in cases of show_instance_secrets\u003dFalse (the common case); but operator admins may need to see the content for troubleshooting. This implies to me that we need to add a new endpoint; e.g. /v1/node/{node_ident}/configdrive to get the current configdrive (and associated new microversion).\n\nAdditionally, since configdrive used to be in instance_info, which means it got cleared automatically during cleaning. Now that configdrive is in a separate table, we\u0027ll need to explicitly add code to clean it up during undeploy/cleaning (wherever instance_info is cleared we almost certainly need to clear the configdrive, too).","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"fda0197a66169fc7a43aecd5d5c472cdfdcc5105","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"536a16d4_f2d6e8e0","updated":"2024-11-14 12:58:25.000000000","message":"Thank you for picking up this work!","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"}],"ironic/conductor/deployments.py":[{"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":"d2f4510268a01853f0f83eed32f7a64ed3117e01","unresolved":true,"context_lines":[{"line_number":516,"context_line":"             with swift are missing."},{"line_number":517,"context_line":"    \"\"\""},{"line_number":518,"context_line":"    # Lazily import configdrive"},{"line_number":519,"context_line":"    from ironic.objects import ConfigDrive"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"    node \u003d task.node"},{"line_number":522,"context_line":"    if CONF.deploy.configdrive_use_object_store:"}],"source_content_type":"text/x-python","patch_set":7,"id":"38a7c397_794f2bf3","line":519,"updated":"2024-11-13 20:15:09.000000000","message":"Let\u0027s figure out how to structure this without lazily loading this.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"fda0197a66169fc7a43aecd5d5c472cdfdcc5105","unresolved":true,"context_lines":[{"line_number":516,"context_line":"             with swift are missing."},{"line_number":517,"context_line":"    \"\"\""},{"line_number":518,"context_line":"    # Lazily import configdrive"},{"line_number":519,"context_line":"    from ironic.objects import ConfigDrive"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"    node \u003d task.node"},{"line_number":522,"context_line":"    if CONF.deploy.configdrive_use_object_store:"}],"source_content_type":"text/x-python","patch_set":7,"id":"2a7b9c60_f6f3de04","line":519,"in_reply_to":"38a7c397_794f2bf3","updated":"2024-11-14 12:58:25.000000000","message":"+1","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"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":"d2f4510268a01853f0f83eed32f7a64ed3117e01","unresolved":true,"context_lines":[{"line_number":547,"context_line":"                                                 timeout)"},{"line_number":548,"context_line":""},{"line_number":549,"context_line":"        i_info \u003d node.instance_info"},{"line_number":550,"context_line":"        i_info[\u0027configdrive\u0027] \u003d configdrive"},{"line_number":551,"context_line":"        node.instance_info \u003d i_info"},{"line_number":552,"context_line":"        node.save()"},{"line_number":553,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":7,"id":"bd539bff_b69294e1","line":550,"updated":"2024-11-13 20:15:09.000000000","message":"I would prefer we use a different field for this now; maybe configdrive_url","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"fda0197a66169fc7a43aecd5d5c472cdfdcc5105","unresolved":true,"context_lines":[{"line_number":547,"context_line":"                                                 timeout)"},{"line_number":548,"context_line":""},{"line_number":549,"context_line":"        i_info \u003d node.instance_info"},{"line_number":550,"context_line":"        i_info[\u0027configdrive\u0027] \u003d configdrive"},{"line_number":551,"context_line":"        node.instance_info \u003d i_info"},{"line_number":552,"context_line":"        node.save()"},{"line_number":553,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":7,"id":"b4de084f_baf5c563","line":550,"in_reply_to":"bd539bff_b69294e1","updated":"2024-11-14 12:58:25.000000000","message":"I don\u0027t quite agree: the change in the behavior may complicate upgrades or be breaking for downstream drivers. That being said, we should treat setting instance_info as a temporary state. This branch should also create a suitable ConfigDrive object.\n\nRemember: the eventual goal is to stop putting the configdrive into instance_info altogether.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"fda0197a66169fc7a43aecd5d5c472cdfdcc5105","unresolved":true,"context_lines":[{"line_number":552,"context_line":"        node.save()"},{"line_number":553,"context_line":"    else:"},{"line_number":554,"context_line":"        ConfigDrive(task.context, values\u003d{\u0027node_id\u0027: node.id,"},{"line_number":555,"context_line":"                                          \u0027data\u0027: configdrive})"},{"line_number":556,"context_line":""},{"line_number":557,"context_line":""},{"line_number":558,"context_line":"def _start_console_in_deploy(task):"}],"source_content_type":"text/x-python","patch_set":7,"id":"8fe7a846_8f6ffad9","line":555,"updated":"2024-11-14 12:58:25.000000000","message":"I don\u0027t think the constructor alone does anything: you probably need to call create() on it.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"d4fdbec8b6ad06ac0ce707e0412fee4c11cd5470","unresolved":false,"context_lines":[{"line_number":552,"context_line":"        node.save()"},{"line_number":553,"context_line":"    else:"},{"line_number":554,"context_line":"        ConfigDrive(task.context, values\u003d{\u0027node_id\u0027: node.id,"},{"line_number":555,"context_line":"                                          \u0027data\u0027: configdrive})"},{"line_number":556,"context_line":""},{"line_number":557,"context_line":""},{"line_number":558,"context_line":"def _start_console_in_deploy(task):"}],"source_content_type":"text/x-python","patch_set":7,"id":"9967a346_e0e60a80","line":555,"in_reply_to":"8fe7a846_8f6ffad9","updated":"2024-11-27 19:45:21.000000000","message":"Acknowledged","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"}],"ironic/conductor/rpcapi.py":[{"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":"f50e68371f4ff30c41822b4ebd7d1515dea24693","unresolved":true,"context_lines":[{"line_number":1554,"context_line":"        i_info \u003d node.instance_info"},{"line_number":1555,"context_line":"        i_info[\u0027configdrive\u0027] \u003d configdrive"},{"line_number":1556,"context_line":"        node.instance_info \u003d i_info"},{"line_number":1557,"context_line":"        node.save()"},{"line_number":1558,"context_line":""},{"line_number":1559,"context_line":"    def get_configdrive(self, task, node_id, topic\u003dNone):"},{"line_number":1560,"context_line":"        \"\"\"Get the configdrive for a node."}],"source_content_type":"text/x-python","patch_set":9,"id":"4278619a_7c2af3e6","line":1557,"updated":"2024-12-11 23:17:32.000000000","message":"Dec 02 18:51:42.666819 np0039235601 ironic-conductor[97286]: DEBUG ironic.conductor.manager [None req-a0f103e7-014a-4451-9899-547f5acad1f3 None None] RPC store_configdrive called for node 1 {{(pid\u003d97286) store_configdrive /opt/stack/ironic/ironic/conductor/manager.py:4005}}\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils [None req-a0f103e7-014a-4451-9899-547f5acad1f3 None None] Unexpected error while preparing the configdrive for node 8c479de0-49c5-4e06-9395-466851b57f22: ironic.common.exception.InvalidConfigDrive: Invalid configdrive: Configdrive must be a valid base64-encoded string  if not a URL or JSON object.\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils Traceback (most recent call last):\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/deployments.py\", line 209, in do_node_deploy\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     _store_configdrive(task, configdrive)\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/deployments.py\", line 551, in _store_configdrive\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     conductor_api.store_configdrive(task, node.id, configdrive, topic\u003dtopic)\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/rpcapi.py\", line 1549, in store_configdrive\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     return cctxt.call(task.context, \u0027store_configdrive\u0027,\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/rpcapi.py\", line 60, in call\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     raise exc_value.with_traceback(exc_tb) from None\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/data/venv/lib/python3.12/site-packages/oslo_messaging/rpc/server.py\", line 262, in inner\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     return func(*args, **kwargs)\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils            ^^^^^^^^^^^^^^^^^^^^^\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/manager.py\", line 4021, in store_configdrive\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     raise exception.InvalidConfigDrive(\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils ironic.common.exception.InvalidConfigDrive: Invalid configdrive: Configdrive must be a valid base64-encoded string  if not a URL or JSON object.","commit_id":"5ad25f075903a2110874f2077be95eb6dec0afa7"}],"ironic/conductor/utils.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"fda0197a66169fc7a43aecd5d5c472cdfdcc5105","unresolved":true,"context_lines":[{"line_number":1117,"context_line":"    :param node: an Ironic node object."},{"line_number":1118,"context_line":"    :returns: A gzipped and base64 encoded configdrive as a string."},{"line_number":1119,"context_line":"    \"\"\""},{"line_number":1120,"context_line":"    # Lazy import"},{"line_number":1121,"context_line":"    from ironic.objects import ConfigDrive"},{"line_number":1122,"context_line":""},{"line_number":1123,"context_line":"    configdrive \u003d ConfigDrive.get_configdrive_data(task.context, task.node.id)"}],"source_content_type":"text/x-python","patch_set":7,"id":"18801c92_c74d5952","line":1120,"updated":"2024-11-14 12:58:25.000000000","message":"Do we have to do it? I see that this module already imports stuff from ironic.objects.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"}],"ironic/db/api.py":[{"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":"d2f4510268a01853f0f83eed32f7a64ed3117e01","unresolved":true,"context_lines":[{"line_number":1617,"context_line":"        :raises: NodeNotFound if the node is not found."},{"line_number":1618,"context_line":"        \"\"\""},{"line_number":1619,"context_line":""},{"line_number":1620,"context_line":"    def create_configdrive(self, node_id, data):"},{"line_number":1621,"context_line":"        \"\"\"Create a ConfigDrive"},{"line_number":1622,"context_line":""},{"line_number":1623,"context_line":"        :param values: A dict describing the configdrive. For example:"}],"source_content_type":"text/x-python","patch_set":7,"id":"d36f45e0_b3e46324","line":1620,"updated":"2024-11-13 20:15:09.000000000","message":"these need to be decorated with @abc.abstractmethod / abstractclassmethod as appropriate","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"d4fdbec8b6ad06ac0ce707e0412fee4c11cd5470","unresolved":false,"context_lines":[{"line_number":1617,"context_line":"        :raises: NodeNotFound if the node is not found."},{"line_number":1618,"context_line":"        \"\"\""},{"line_number":1619,"context_line":""},{"line_number":1620,"context_line":"    def create_configdrive(self, node_id, data):"},{"line_number":1621,"context_line":"        \"\"\"Create a ConfigDrive"},{"line_number":1622,"context_line":""},{"line_number":1623,"context_line":"        :param values: A dict describing the configdrive. For example:"}],"source_content_type":"text/x-python","patch_set":7,"id":"61946b7d_b888ac1b","line":1620,"in_reply_to":"d36f45e0_b3e46324","updated":"2024-11-27 19:45:21.000000000","message":"Acknowledged","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"}],"ironic/db/sqlalchemy/alembic/versions/dfd87e07fc3c_add_configdrive_table.py":[{"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":"95d39ba4957e1018786378c25b50ed438acf670e","unresolved":true,"context_lines":[{"line_number":42,"context_line":"        sa.ForeignKeyConstraint([\u0027node_id\u0027], [\u0027nodes.id\u0027]),"},{"line_number":43,"context_line":"        mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":44,"context_line":"        mysql_charset\u003d\u0027UTF8MB3\u0027"},{"line_number":45,"context_line":"    )"}],"source_content_type":"text/x-python","patch_set":7,"id":"74941046_53f3f263","line":45,"updated":"2024-11-13 20:16:05.000000000","message":"Shouldn\u0027t we have a modification to the nodes table to add a configdrive field that references this one -- a two way relationship where node.configdrive points to the configdrive for that node. This will likely be needed for the suggested API changes.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"}],"ironic/db/sqlalchemy/api.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"fda0197a66169fc7a43aecd5d5c472cdfdcc5105","unresolved":true,"context_lines":[{"line_number":3183,"context_line":"        with _session_for_read() as session:"},{"line_number":3184,"context_line":"            configdrive \u003d session.query(models.ConfigDrive).filter_by("},{"line_number":3185,"context_line":"                node_id\u003dnode_id).one_or_none()"},{"line_number":3186,"context_line":"            return configdrive.data if configdrive else configdrive"},{"line_number":3187,"context_line":""},{"line_number":3188,"context_line":"    def get_configdrive(self, node_id):"},{"line_number":3189,"context_line":"        with _session_for_read() as session:"}],"source_content_type":"text/x-python","patch_set":7,"id":"464bc87c_4c58e47a","line":3186,"updated":"2024-11-14 12:58:25.000000000","message":"This function essentially duplicates get_configdrive (modulo returning None). I\u0027d prefer to drop it and move the logic up the level.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"d4fdbec8b6ad06ac0ce707e0412fee4c11cd5470","unresolved":false,"context_lines":[{"line_number":3183,"context_line":"        with _session_for_read() as session:"},{"line_number":3184,"context_line":"            configdrive \u003d session.query(models.ConfigDrive).filter_by("},{"line_number":3185,"context_line":"                node_id\u003dnode_id).one_or_none()"},{"line_number":3186,"context_line":"            return configdrive.data if configdrive else configdrive"},{"line_number":3187,"context_line":""},{"line_number":3188,"context_line":"    def get_configdrive(self, node_id):"},{"line_number":3189,"context_line":"        with _session_for_read() as session:"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab30643_86d36b4a","line":3186,"in_reply_to":"464bc87c_4c58e47a","updated":"2024-11-27 19:45:21.000000000","message":"Acknowledged","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"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":"f50e68371f4ff30c41822b4ebd7d1515dea24693","unresolved":true,"context_lines":[{"line_number":3159,"context_line":"                self._check_node_exists(session, node_id)"},{"line_number":3160,"context_line":"                node \u003d self.get_node_by_id(node_id)"},{"line_number":3161,"context_line":""},{"line_number":3162,"context_line":"                session.add(configdrive)"},{"line_number":3163,"context_line":"                session.flush()"},{"line_number":3164,"context_line":"            except db_exc.DBDataError as e:"},{"line_number":3165,"context_line":"                msg \u003d _(\u0027Error while storing the configdrive for %(node)s \u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"b6901d67_21426cf1","line":3162,"updated":"2024-12-11 23:17:32.000000000","message":"Dec 02 18:51:42.666819 np0039235601 ironic-conductor[97286]: DEBUG ironic.conductor.manager [None req-a0f103e7-014a-4451-9899-547f5acad1f3 None None] RPC store_configdrive called for node 1 {{(pid\u003d97286) store_configdrive /opt/stack/ironic/ironic/conductor/manager.py:4005}}\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils [None req-a0f103e7-014a-4451-9899-547f5acad1f3 None None] Unexpected error while preparing the configdrive for node 8c479de0-49c5-4e06-9395-466851b57f22: ironic.common.exception.InvalidConfigDrive: Invalid configdrive: Configdrive must be a valid base64-encoded string  if not a URL or JSON object.\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils Traceback (most recent call last):\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/deployments.py\", line 209, in do_node_deploy\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     _store_configdrive(task, configdrive)\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/deployments.py\", line 551, in _store_configdrive\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     conductor_api.store_configdrive(task, node.id, configdrive, topic\u003dtopic)\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/rpcapi.py\", line 1549, in store_configdrive\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     return cctxt.call(task.context, \u0027store_configdrive\u0027,\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/rpcapi.py\", line 60, in call\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     raise exc_value.with_traceback(exc_tb) from None\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/data/venv/lib/python3.12/site-packages/oslo_messaging/rpc/server.py\", line 262, in inner\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     return func(*args, **kwargs)\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils            ^^^^^^^^^^^^^^^^^^^^^\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils   File \"/opt/stack/ironic/ironic/conductor/manager.py\", line 4021, in store_configdrive\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils     raise exception.InvalidConfigDrive(\nDec 02 18:51:42.669078 np0039235601 ironic-conductor[97286]: ERROR ironic.conductor.utils ironic.common.exception.InvalidConfigDrive: Invalid configdrive: Configdrive must be a valid base64-encoded string  if not a URL or JSON object.","commit_id":"5ad25f075903a2110874f2077be95eb6dec0afa7"}],"ironic/db/sqlalchemy/models.py":[{"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":"d2f4510268a01853f0f83eed32f7a64ed3117e01","unresolved":true,"context_lines":[{"line_number":578,"context_line":"    )"},{"line_number":579,"context_line":"    node_id \u003d Column(Integer, ForeignKey(\u0027nodes.id\u0027),"},{"line_number":580,"context_line":"                     primary_key\u003dTrue, nullable\u003dFalse)"},{"line_number":581,"context_line":"    data \u003d Column(db_types.JsonEncodedDict(mysql_as_long\u003dTrue),"},{"line_number":582,"context_line":"                  nullable\u003dTrue)"},{"line_number":583,"context_line":"    node \u003d orm.relationship("},{"line_number":584,"context_line":"        \"Node\","}],"source_content_type":"text/x-python","patch_set":7,"id":"d4fefaa1_bdd32c23","line":581,"updated":"2024-11-13 20:15:09.000000000","message":"So this is the exact same type as instance_info; so we\u0027re gaining some ability to support a larger configdrive, however I wonder if we should explicitly specify a longer length here. I\u0027m unsure what the balance of reasonable to performance is.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"fda0197a66169fc7a43aecd5d5c472cdfdcc5105","unresolved":true,"context_lines":[{"line_number":578,"context_line":"    )"},{"line_number":579,"context_line":"    node_id \u003d Column(Integer, ForeignKey(\u0027nodes.id\u0027),"},{"line_number":580,"context_line":"                     primary_key\u003dTrue, nullable\u003dFalse)"},{"line_number":581,"context_line":"    data \u003d Column(db_types.JsonEncodedDict(mysql_as_long\u003dTrue),"},{"line_number":582,"context_line":"                  nullable\u003dTrue)"},{"line_number":583,"context_line":"    node \u003d orm.relationship("},{"line_number":584,"context_line":"        \"Node\","}],"source_content_type":"text/x-python","patch_set":7,"id":"c0bd3872_bd7087f4","line":581,"in_reply_to":"d4fefaa1_bdd32c23","updated":"2024-11-14 12:58:25.000000000","message":"mysql_as_long should give us enough space IIRC.\n\nI\u0027m somewhat against a generic \"data\" field. There are 3 kinds of config drive data: a URL, a JSON or a base64 blob. I\u0027d prefer these 3 to be separate nullable clearly named fields that are populated depending on what the user provided. This way we\u0027ll be more future-proof than with a \"one-size-fits-all\" field.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"}],"ironic/objects/configdrive.py":[{"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":"d2f4510268a01853f0f83eed32f7a64ed3117e01","unresolved":true,"context_lines":[{"line_number":25,"context_line":"    dbapi \u003d db_api.get_instance()"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027node_id\u0027: object_fields.StringField(),"},{"line_number":29,"context_line":"        \u0027data\u0027: object_fields.FlexibleDictField(nullable\u003dFalse),"},{"line_number":30,"context_line":"    }"},{"line_number":31,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"b40b0047_1e533a0a","line":28,"updated":"2024-11-13 20:15:09.000000000","message":"This needs to be an integer field","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"d4fdbec8b6ad06ac0ce707e0412fee4c11cd5470","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    dbapi \u003d db_api.get_instance()"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    fields \u003d {"},{"line_number":28,"context_line":"        \u0027node_id\u0027: object_fields.StringField(),"},{"line_number":29,"context_line":"        \u0027data\u0027: object_fields.FlexibleDictField(nullable\u003dFalse),"},{"line_number":30,"context_line":"    }"},{"line_number":31,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"46f91dc2_c8e3d9b2","line":28,"in_reply_to":"b40b0047_1e533a0a","updated":"2024-11-27 19:45:21.000000000","message":"Acknowledged","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"fda0197a66169fc7a43aecd5d5c472cdfdcc5105","unresolved":true,"context_lines":[{"line_number":73,"context_line":"        :param node_id: The id of a node."},{"line_number":74,"context_line":"        :returns: a :class:`ConfigDrive` object if exists otherwise None."},{"line_number":75,"context_line":"        \"\"\""},{"line_number":76,"context_line":"        return cls.dbapi.get_configdrive_data(node_id)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    @classmethod"},{"line_number":79,"context_line":"    def get(cls, context, node_id):"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f1d4b3c_1bef70b5","line":76,"updated":"2024-11-14 12:58:25.000000000","message":"How is this different from ConfigDriver.get(node_id).data? Seems redundant.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"},{"author":{"_account_id":36770,"name":"cid","display_name":"cid","email":"cid@gr-oss.io","username":"cidelight","status":"@gr-oss upstream: Doing good IRONIC things..."},"change_message_id":"d4fdbec8b6ad06ac0ce707e0412fee4c11cd5470","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        :param node_id: The id of a node."},{"line_number":74,"context_line":"        :returns: a :class:`ConfigDrive` object if exists otherwise None."},{"line_number":75,"context_line":"        \"\"\""},{"line_number":76,"context_line":"        return cls.dbapi.get_configdrive_data(node_id)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    @classmethod"},{"line_number":79,"context_line":"    def get(cls, context, node_id):"}],"source_content_type":"text/x-python","patch_set":7,"id":"c11ec12e_3c25e8cb","line":76,"in_reply_to":"5f1d4b3c_1bef70b5","updated":"2024-11-27 19:45:21.000000000","message":"Acknowledged","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"}],"releasenotes/notes/move-configdrive-to-a-separate-table-d3ac46b984581824.yaml":[{"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":"d2f4510268a01853f0f83eed32f7a64ed3117e01","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":7,"id":"5cf2b7ee_26114bf5","line":6,"updated":"2024-11-13 20:15:09.000000000","message":"This needs an \"upgrade\" note about the migration.","commit_id":"2ee00ad611f786cbce2bcc8fd9b66c58b43a9d36"}]}
