feat(16-05): replace 6 Docker API queries with Unraid GraphQL
- Migrated Get Container For Action to GraphQL - Migrated Get Container For Cancel to GraphQL - Migrated Get All Containers For Update All to GraphQL (with imageId) - Migrated Fetch Containers For Update All Exec to GraphQL (with imageId) - Migrated Get Container For Callback Update to GraphQL - Migrated Fetch Containers For Bitmap Stop to GraphQL Added 6 GraphQL Response Normalizer nodes and 6 Container ID Registry update nodes. All nodes use $env.UNRAID_HOST and $env.UNRAID_API_KEY for authentication. 15-second timeout for myunraid.net cloud relay. Workflow pushed to n8n successfully (HTTP 200).
This commit is contained in:
+460
-15
@@ -1802,9 +1802,34 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"method": "GET",
|
"method": "POST",
|
||||||
"url": "=http://docker-socket-proxy:2375/containers/json?all=true",
|
"url": "={{ $env.UNRAID_HOST }}/graphql",
|
||||||
"options": {}
|
"authentication": "none",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x-api-key",
|
||||||
|
"value": "={{ $env.UNRAID_API_KEY }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={{ {\"query\": \"query { docker { containers { id names state image } } }\"} }}",
|
||||||
|
"options": {
|
||||||
|
"timeout": 15000,
|
||||||
|
"response": {
|
||||||
|
"response": {
|
||||||
|
"errorRedirection": "continue",
|
||||||
|
"fullResponse": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"id": "http-get-container-for-action",
|
"id": "http-get-container-for-action",
|
||||||
"name": "Get Container For Action",
|
"name": "Get Container For Action",
|
||||||
@@ -1918,9 +1943,34 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"method": "GET",
|
"method": "POST",
|
||||||
"url": "=http://docker-socket-proxy:2375/containers/json?all=true",
|
"url": "={{ $env.UNRAID_HOST }}/graphql",
|
||||||
"options": {}
|
"authentication": "none",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x-api-key",
|
||||||
|
"value": "={{ $env.UNRAID_API_KEY }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={{ {\"query\": \"query { docker { containers { id names state image } } }\"} }}",
|
||||||
|
"options": {
|
||||||
|
"timeout": 15000,
|
||||||
|
"response": {
|
||||||
|
"response": {
|
||||||
|
"errorRedirection": "continue",
|
||||||
|
"fullResponse": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"id": "http-get-container-for-cancel",
|
"id": "http-get-container-for-cancel",
|
||||||
"name": "Get Container For Cancel",
|
"name": "Get Container For Cancel",
|
||||||
@@ -2683,8 +2733,34 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"url": "http://docker-socket-proxy:2375/containers/json?all=false",
|
"method": "POST",
|
||||||
"options": {}
|
"url": "={{ $env.UNRAID_HOST }}/graphql",
|
||||||
|
"authentication": "none",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x-api-key",
|
||||||
|
"value": "={{ $env.UNRAID_API_KEY }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={{ {\"query\": \"query { docker { containers { id names state image imageId } } }\"} }}",
|
||||||
|
"options": {
|
||||||
|
"timeout": 15000,
|
||||||
|
"response": {
|
||||||
|
"response": {
|
||||||
|
"errorRedirection": "continue",
|
||||||
|
"fullResponse": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"id": "http-get-all-containers-update-all",
|
"id": "http-get-all-containers-update-all",
|
||||||
"name": "Get All Containers For Update All",
|
"name": "Get All Containers For Update All",
|
||||||
@@ -2974,8 +3050,34 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"url": "http://docker-socket-proxy:2375/containers/json?all=false",
|
"method": "POST",
|
||||||
"options": {}
|
"url": "={{ $env.UNRAID_HOST }}/graphql",
|
||||||
|
"authentication": "none",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x-api-key",
|
||||||
|
"value": "={{ $env.UNRAID_API_KEY }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={{ {\"query\": \"query { docker { containers { id names state image imageId } } }\"} }}",
|
||||||
|
"options": {
|
||||||
|
"timeout": 15000,
|
||||||
|
"response": {
|
||||||
|
"response": {
|
||||||
|
"errorRedirection": "continue",
|
||||||
|
"fullResponse": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"id": "http-fetch-containers-update-all-exec",
|
"id": "http-fetch-containers-update-all-exec",
|
||||||
"name": "Fetch Containers For Update All Exec",
|
"name": "Fetch Containers For Update All Exec",
|
||||||
@@ -3080,9 +3182,34 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"method": "GET",
|
"method": "POST",
|
||||||
"url": "=http://docker-socket-proxy:2375/containers/json?all=true",
|
"url": "={{ $env.UNRAID_HOST }}/graphql",
|
||||||
"options": {}
|
"authentication": "none",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x-api-key",
|
||||||
|
"value": "={{ $env.UNRAID_API_KEY }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={{ {\"query\": \"query { docker { containers { id names state image } } }\"} }}",
|
||||||
|
"options": {
|
||||||
|
"timeout": 15000,
|
||||||
|
"response": {
|
||||||
|
"response": {
|
||||||
|
"errorRedirection": "continue",
|
||||||
|
"fullResponse": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"id": "http-get-container-callback",
|
"id": "http-get-container-callback",
|
||||||
"name": "Get Container For Callback Update",
|
"name": "Get Container For Callback Update",
|
||||||
@@ -4751,9 +4878,33 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"url": "http://docker-socket-proxy:2375/containers/json?all=true",
|
"method": "POST",
|
||||||
|
"url": "={{ $env.UNRAID_HOST }}/graphql",
|
||||||
|
"authentication": "none",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x-api-key",
|
||||||
|
"value": "={{ $env.UNRAID_API_KEY }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={{ {\"query\": \"query { docker { containers { id names state image } } }\"} }}",
|
||||||
"options": {
|
"options": {
|
||||||
"timeout": 5000
|
"timeout": 15000,
|
||||||
|
"response": {
|
||||||
|
"response": {
|
||||||
|
"errorRedirection": "continue",
|
||||||
|
"fullResponse": false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"id": "http-fetch-containers-bitmap-stop",
|
"id": "http-fetch-containers-bitmap-stop",
|
||||||
@@ -4984,6 +5135,162 @@
|
|||||||
1000,
|
1000,
|
||||||
2400
|
2400
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// GraphQL Response Normalizer - Transform Unraid API to Docker API contract\nconst response = $input.item.json;\n\n// Validate GraphQL response\nif (response.errors) {\n throw new Error(`GraphQL Error: ${response.errors[0].message}`);\n}\n\nif (!response.data?.docker?.containers) {\n throw new Error('Invalid GraphQL response structure');\n}\n\nconst containers = response.data.docker.containers;\n\n// Transform to Docker API format\nconst normalized = containers.map(container => {\n // State mapping: RUNNING\u2192running, STOPPED\u2192exited, PAUSED\u2192paused\n const stateLower = container.state ? container.state.toLowerCase() : 'unknown';\n \n return {\n Id: container.id, // Full 129-char PrefixedID\n Names: container.names || [container.name ? `/${container.name}` : '/unknown'],\n State: stateLower === 'stopped' ? 'exited' : stateLower,\n Status: container.status || stateLower,\n Image: container.image || '',\n ImageId: container.imageId || ''\n };\n});\n\nreturn normalized.map(container => ({ json: container }));\n"
|
||||||
|
},
|
||||||
|
"id": "normalize-graphql-action",
|
||||||
|
"name": "Normalize GraphQL Response (Action)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
2300,
|
||||||
|
1100
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// Update Container ID Registry - Store name\u2192PrefixedID mappings\nconst containers = $input.all();\nconst staticData = $getWorkflowStaticData('global');\n\n// Parse existing registry\nconst registry = JSON.parse(staticData._containerIdRegistry || '{}');\n\n// Update registry with current containers\ncontainers.forEach(item => {\n const container = item.json;\n const name = container.Names?.[0]?.substring(1) || 'unknown'; // Remove leading /\n \n registry[name] = {\n name: name,\n unraidId: container.Id, // Full PrefixedID\n prefixedId: container.Id, // Alias for consistency\n lastSeen: Date.now()\n };\n});\n\n// Write back to static data (top-level assignment for persistence)\nstaticData._containerIdRegistry = JSON.stringify(registry);\nstaticData._containerRegistryLastUpdate = Date.now();\n\n// Pass through all container data\nreturn $input.all();\n"
|
||||||
|
},
|
||||||
|
"id": "registry-update-action",
|
||||||
|
"name": "Update Container Registry (Action)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
2600,
|
||||||
|
1100
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// GraphQL Response Normalizer - Transform Unraid API to Docker API contract\nconst response = $input.item.json;\n\n// Validate GraphQL response\nif (response.errors) {\n throw new Error(`GraphQL Error: ${response.errors[0].message}`);\n}\n\nif (!response.data?.docker?.containers) {\n throw new Error('Invalid GraphQL response structure');\n}\n\nconst containers = response.data.docker.containers;\n\n// Transform to Docker API format\nconst normalized = containers.map(container => {\n // State mapping: RUNNING\u2192running, STOPPED\u2192exited, PAUSED\u2192paused\n const stateLower = container.state ? container.state.toLowerCase() : 'unknown';\n \n return {\n Id: container.id, // Full 129-char PrefixedID\n Names: container.names || [container.name ? `/${container.name}` : '/unknown'],\n State: stateLower === 'stopped' ? 'exited' : stateLower,\n Status: container.status || stateLower,\n Image: container.image || '',\n ImageId: container.imageId || ''\n };\n});\n\nreturn normalized.map(container => ({ json: container }));\n"
|
||||||
|
},
|
||||||
|
"id": "normalize-graphql-cancel",
|
||||||
|
"name": "Normalize GraphQL Response (Cancel)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
2080,
|
||||||
|
1800
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// Update Container ID Registry - Store name\u2192PrefixedID mappings\nconst containers = $input.all();\nconst staticData = $getWorkflowStaticData('global');\n\n// Parse existing registry\nconst registry = JSON.parse(staticData._containerIdRegistry || '{}');\n\n// Update registry with current containers\ncontainers.forEach(item => {\n const container = item.json;\n const name = container.Names?.[0]?.substring(1) || 'unknown'; // Remove leading /\n \n registry[name] = {\n name: name,\n unraidId: container.Id, // Full PrefixedID\n prefixedId: container.Id, // Alias for consistency\n lastSeen: Date.now()\n };\n});\n\n// Write back to static data (top-level assignment for persistence)\nstaticData._containerIdRegistry = JSON.stringify(registry);\nstaticData._containerRegistryLastUpdate = Date.now();\n\n// Pass through all container data\nreturn $input.all();\n"
|
||||||
|
},
|
||||||
|
"id": "registry-update-cancel",
|
||||||
|
"name": "Update Container Registry (Cancel)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
2380,
|
||||||
|
1800
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// GraphQL Response Normalizer - Transform Unraid API to Docker API contract\nconst response = $input.item.json;\n\n// Validate GraphQL response\nif (response.errors) {\n throw new Error(`GraphQL Error: ${response.errors[0].message}`);\n}\n\nif (!response.data?.docker?.containers) {\n throw new Error('Invalid GraphQL response structure');\n}\n\nconst containers = response.data.docker.containers;\n\n// Transform to Docker API format\nconst normalized = containers.map(container => {\n // State mapping: RUNNING\u2192running, STOPPED\u2192exited, PAUSED\u2192paused\n const stateLower = container.state ? container.state.toLowerCase() : 'unknown';\n \n return {\n Id: container.id, // Full 129-char PrefixedID\n Names: container.names || [container.name ? `/${container.name}` : '/unknown'],\n State: stateLower === 'stopped' ? 'exited' : stateLower,\n Status: container.status || stateLower,\n Image: container.image || '',\n ImageId: container.imageId || ''\n };\n});\n\nreturn normalized.map(container => ({ json: container }));\n"
|
||||||
|
},
|
||||||
|
"id": "normalize-graphql-update-all",
|
||||||
|
"name": "Normalize GraphQL Response (Update All)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
1500,
|
||||||
|
2200
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// Update Container ID Registry - Store name\u2192PrefixedID mappings\nconst containers = $input.all();\nconst staticData = $getWorkflowStaticData('global');\n\n// Parse existing registry\nconst registry = JSON.parse(staticData._containerIdRegistry || '{}');\n\n// Update registry with current containers\ncontainers.forEach(item => {\n const container = item.json;\n const name = container.Names?.[0]?.substring(1) || 'unknown'; // Remove leading /\n \n registry[name] = {\n name: name,\n unraidId: container.Id, // Full PrefixedID\n prefixedId: container.Id, // Alias for consistency\n lastSeen: Date.now()\n };\n});\n\n// Write back to static data (top-level assignment for persistence)\nstaticData._containerIdRegistry = JSON.stringify(registry);\nstaticData._containerRegistryLastUpdate = Date.now();\n\n// Pass through all container data\nreturn $input.all();\n"
|
||||||
|
},
|
||||||
|
"id": "registry-update-update-all",
|
||||||
|
"name": "Update Container Registry (Update All)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
1800,
|
||||||
|
2200
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// GraphQL Response Normalizer - Transform Unraid API to Docker API contract\nconst response = $input.item.json;\n\n// Validate GraphQL response\nif (response.errors) {\n throw new Error(`GraphQL Error: ${response.errors[0].message}`);\n}\n\nif (!response.data?.docker?.containers) {\n throw new Error('Invalid GraphQL response structure');\n}\n\nconst containers = response.data.docker.containers;\n\n// Transform to Docker API format\nconst normalized = containers.map(container => {\n // State mapping: RUNNING\u2192running, STOPPED\u2192exited, PAUSED\u2192paused\n const stateLower = container.state ? container.state.toLowerCase() : 'unknown';\n \n return {\n Id: container.id, // Full 129-char PrefixedID\n Names: container.names || [container.name ? `/${container.name}` : '/unknown'],\n State: stateLower === 'stopped' ? 'exited' : stateLower,\n Status: container.status || stateLower,\n Image: container.image || '',\n ImageId: container.imageId || ''\n };\n});\n\nreturn normalized.map(container => ({ json: container }));\n"
|
||||||
|
},
|
||||||
|
"id": "normalize-graphql-update-all-exec",
|
||||||
|
"name": "Normalize GraphQL Response (Update All Exec)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
2500,
|
||||||
|
2600
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// Update Container ID Registry - Store name\u2192PrefixedID mappings\nconst containers = $input.all();\nconst staticData = $getWorkflowStaticData('global');\n\n// Parse existing registry\nconst registry = JSON.parse(staticData._containerIdRegistry || '{}');\n\n// Update registry with current containers\ncontainers.forEach(item => {\n const container = item.json;\n const name = container.Names?.[0]?.substring(1) || 'unknown'; // Remove leading /\n \n registry[name] = {\n name: name,\n unraidId: container.Id, // Full PrefixedID\n prefixedId: container.Id, // Alias for consistency\n lastSeen: Date.now()\n };\n});\n\n// Write back to static data (top-level assignment for persistence)\nstaticData._containerIdRegistry = JSON.stringify(registry);\nstaticData._containerRegistryLastUpdate = Date.now();\n\n// Pass through all container data\nreturn $input.all();\n"
|
||||||
|
},
|
||||||
|
"id": "registry-update-update-all-exec",
|
||||||
|
"name": "Update Container Registry (Update All Exec)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
2800,
|
||||||
|
2600
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// GraphQL Response Normalizer - Transform Unraid API to Docker API contract\nconst response = $input.item.json;\n\n// Validate GraphQL response\nif (response.errors) {\n throw new Error(`GraphQL Error: ${response.errors[0].message}`);\n}\n\nif (!response.data?.docker?.containers) {\n throw new Error('Invalid GraphQL response structure');\n}\n\nconst containers = response.data.docker.containers;\n\n// Transform to Docker API format\nconst normalized = containers.map(container => {\n // State mapping: RUNNING\u2192running, STOPPED\u2192exited, PAUSED\u2192paused\n const stateLower = container.state ? container.state.toLowerCase() : 'unknown';\n \n return {\n Id: container.id, // Full 129-char PrefixedID\n Names: container.names || [container.name ? `/${container.name}` : '/unknown'],\n State: stateLower === 'stopped' ? 'exited' : stateLower,\n Status: container.status || stateLower,\n Image: container.image || '',\n ImageId: container.imageId || ''\n };\n});\n\nreturn normalized.map(container => ({ json: container }));\n"
|
||||||
|
},
|
||||||
|
"id": "normalize-graphql-callback",
|
||||||
|
"name": "Normalize GraphQL Response (Callback)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
2740,
|
||||||
|
1650
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// Update Container ID Registry - Store name\u2192PrefixedID mappings\nconst containers = $input.all();\nconst staticData = $getWorkflowStaticData('global');\n\n// Parse existing registry\nconst registry = JSON.parse(staticData._containerIdRegistry || '{}');\n\n// Update registry with current containers\ncontainers.forEach(item => {\n const container = item.json;\n const name = container.Names?.[0]?.substring(1) || 'unknown'; // Remove leading /\n \n registry[name] = {\n name: name,\n unraidId: container.Id, // Full PrefixedID\n prefixedId: container.Id, // Alias for consistency\n lastSeen: Date.now()\n };\n});\n\n// Write back to static data (top-level assignment for persistence)\nstaticData._containerIdRegistry = JSON.stringify(registry);\nstaticData._containerRegistryLastUpdate = Date.now();\n\n// Pass through all container data\nreturn $input.all();\n"
|
||||||
|
},
|
||||||
|
"id": "registry-update-callback",
|
||||||
|
"name": "Update Container Registry (Callback)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
3040,
|
||||||
|
1650
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// GraphQL Response Normalizer - Transform Unraid API to Docker API contract\nconst response = $input.item.json;\n\n// Validate GraphQL response\nif (response.errors) {\n throw new Error(`GraphQL Error: ${response.errors[0].message}`);\n}\n\nif (!response.data?.docker?.containers) {\n throw new Error('Invalid GraphQL response structure');\n}\n\nconst containers = response.data.docker.containers;\n\n// Transform to Docker API format\nconst normalized = containers.map(container => {\n // State mapping: RUNNING\u2192running, STOPPED\u2192exited, PAUSED\u2192paused\n const stateLower = container.state ? container.state.toLowerCase() : 'unknown';\n \n return {\n Id: container.id, // Full 129-char PrefixedID\n Names: container.names || [container.name ? `/${container.name}` : '/unknown'],\n State: stateLower === 'stopped' ? 'exited' : stateLower,\n Status: container.status || stateLower,\n Image: container.image || '',\n ImageId: container.imageId || ''\n };\n});\n\nreturn normalized.map(container => ({ json: container }));\n"
|
||||||
|
},
|
||||||
|
"id": "normalize-graphql-bitmap-stop",
|
||||||
|
"name": "Normalize GraphQL Response (Bitmap Stop)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
2300,
|
||||||
|
700
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// Update Container ID Registry - Store name\u2192PrefixedID mappings\nconst containers = $input.all();\nconst staticData = $getWorkflowStaticData('global');\n\n// Parse existing registry\nconst registry = JSON.parse(staticData._containerIdRegistry || '{}');\n\n// Update registry with current containers\ncontainers.forEach(item => {\n const container = item.json;\n const name = container.Names?.[0]?.substring(1) || 'unknown'; // Remove leading /\n \n registry[name] = {\n name: name,\n unraidId: container.Id, // Full PrefixedID\n prefixedId: container.Id, // Alias for consistency\n lastSeen: Date.now()\n };\n});\n\n// Write back to static data (top-level assignment for persistence)\nstaticData._containerIdRegistry = JSON.stringify(registry);\nstaticData._containerRegistryLastUpdate = Date.now();\n\n// Pass through all container data\nreturn $input.all();\n"
|
||||||
|
},
|
||||||
|
"id": "registry-update-bitmap-stop",
|
||||||
|
"name": "Update Container Registry (Bitmap Stop)",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
2600,
|
||||||
|
700
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"connections": {
|
"connections": {
|
||||||
@@ -6887,7 +7194,145 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"http-get-container-for-action": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "normalize-graphql-action",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"normalize-graphql-action": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "registry-update-action",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"registry-update-action": {},
|
||||||
|
"http-get-container-for-cancel": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "normalize-graphql-cancel",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"normalize-graphql-cancel": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "registry-update-cancel",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"registry-update-cancel": {},
|
||||||
|
"http-get-all-containers-update-all": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "normalize-graphql-update-all",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"normalize-graphql-update-all": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "registry-update-update-all",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"registry-update-update-all": {},
|
||||||
|
"http-fetch-containers-update-all-exec": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "normalize-graphql-update-all-exec",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"normalize-graphql-update-all-exec": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "registry-update-update-all-exec",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"registry-update-update-all-exec": {},
|
||||||
|
"http-get-container-callback": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "normalize-graphql-callback",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"normalize-graphql-callback": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "registry-update-callback",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"registry-update-callback": {},
|
||||||
|
"http-fetch-containers-bitmap-stop": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "normalize-graphql-bitmap-stop",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"normalize-graphql-bitmap-stop": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "registry-update-bitmap-stop",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"registry-update-bitmap-stop": {}
|
||||||
},
|
},
|
||||||
"pinData": {},
|
"pinData": {},
|
||||||
"settings": {
|
"settings": {
|
||||||
|
|||||||
Reference in New Issue
Block a user