Skip to content

Conversation

@shwstppr
Copy link
Contributor

@shwstppr shwstppr commented Nov 19, 2025

Description

Adds import functionality for extension by giving an YAML manifest URL. Manifest will define extension and its custom actions details.

Based on CCC 2025 Hackathon idea by @msinhore and the contribution by @sudo87

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

image

How Has This Been Tested?

(localcloud) 🐱 > import extension manifesturl=https://raw.githubusercontent.com/msinhore/cloudstack-firecracker-extension/refs/heads/main/manifest.yml
{
  "extension": {
    "created": "2025-11-20T04:45:01+0530",
    "description": "External orchestrator extension that integrates Firecracker microVMs with Apache CloudStack via the Orchestrator Extension Framework.\n",
    "id": "214387be-fabc-4958-8ffa-b12df3c801b4",
    "isuserdefined": true,
    "name": "firecracker",
    "orchestratorrequirespreparevm": false,
    "path": "/home/shwstppr/lab/shapeblue/cloudstack/extensions/firecracker/firecracker.py",
    "pathready": true,
    "state": "Enabled",
    "type": "Orchestrator"
  }
}
(localcloud) 🐱 > list extensions id=214387be-fabc-4958-8ffa-b12df3c801b4 (firecracker)
{
  "count": 1,
  "extension": [
    {
      "created": "2025-11-20T04:45:01+0530",
      "description": "External orchestrator extension that integrates Firecracker microVMs with Apache CloudStack via the Orchestrator Extension Framework.\n",
      "id": "214387be-fabc-4958-8ffa-b12df3c801b4",
      "isuserdefined": true,
      "name": "firecracker",
      "orchestratorrequirespreparevm": false,
      "path": "/home/shwstppr/lab/shapeblue/cloudstack/extensions/firecracker/firecracker.py",
      "pathready": true,
      "state": "Enabled",
      "type": "Orchestrator"
    }
  ]
}
(localcloud) 🐱 > list customactions extensionid=214387be-fabc-4958-8ffa-b12df3c801b4 (firecracker)
{
  "count": 4,
  "extensioncustomaction": [
    {
      "allowedroletypes": [
        "Admin",
        "DomainAdmin",
        "User"
      ],
      "created": "2025-11-20T04:45:01+0530",
      "description": "Delete a snapshot for a virtual machine instance.",
      "details": {},
      "enabled": true,
      "extensionid": "214387be-fabc-4958-8ffa-b12df3c801b4",
      "extensionname": "firecracker",
      "id": "37233ea1-4a5f-47cf-bd15-3e0c9a9d1e7c",
      "name": "DeleteSnapshot",
      "parameters": [
        {
          "name": "snap_name",
          "required": true,
          "type": "STRING",
          "validationformat": "NONE"
        }
      ],
      "resourcetype": "VirtualMachine",
      "timeout": 300
    },
    {
      "allowedroletypes": [
        "Admin",
        "DomainAdmin",
        "User"
      ],
      "created": "2025-11-20T04:45:01+0530",
      "description": "Restore a virtual machine instance from a given snapshot.",
      "details": {},
      "enabled": true,
      "extensionid": "214387be-fabc-4958-8ffa-b12df3c801b4",
      "extensionname": "firecracker",
      "id": "4edf2208-dce5-4ecb-a030-61193adb9825",
      "name": "RestoreSnapshot",
      "parameters": [
        {
          "name": "snap_name",
          "required": true,
          "type": "STRING",
          "validationformat": "NONE"
        }
      ],
      "resourcetype": "VirtualMachine",
      "timeout": 900
    },
    {
      "allowedroletypes": [
        "Admin",
        "DomainAdmin",
        "User"
      ],
      "created": "2025-11-20T04:45:01+0530",
      "description": "List all snapshots for a virtual machine instance.",
      "details": {},
      "enabled": true,
      "extensionid": "214387be-fabc-4958-8ffa-b12df3c801b4",
      "extensionname": "firecracker",
      "id": "de999133-75a5-45da-8893-63622fe02a44",
      "name": "ListSnapshots",
      "parameters": [],
      "resourcetype": "VirtualMachine",
      "timeout": 120
    },
    {
      "allowedroletypes": [
        "Admin",
        "DomainAdmin",
        "User"
      ],
      "created": "2025-11-20T04:45:01+0530",
      "description": "Create a snapshot for a virtual machine instance.",
      "details": {},
      "enabled": true,
      "extensionid": "214387be-fabc-4958-8ffa-b12df3c801b4",
      "extensionname": "firecracker",
      "id": "80b3b994-1ac8-4193-a6b9-9c72146c8815",
      "name": "CreateSnapshot",
      "parameters": [
        {
          "name": "snap_name",
          "required": true,
          "type": "STRING",
          "validationformat": "NONE"
        },
        {
          "name": "snap_description",
          "required": false,
          "type": "STRING",
          "validationformat": "NONE"
        },
        {
          "name": "snap_save_memory",
          "required": false,
          "type": "BOOLEAN",
          "validationformat": "NONE"
        }
      ],
      "resourcetype": "VirtualMachine",
      "timeout": 600
    }
  ]
}

How did you try to break this feature and the system with this change?

Adds import functionality for extension by giving an YAML manifest URL.
Manifest will define extension and its custom actions details.

Co-authored-by: Manoj Kumar <[email protected]>

Signed-off-by: Abhishek Kumar <[email protected]>
@weizhouapache
Copy link
Member

great job !

would it be possible to upload zipped files from local ?

@codecov
Copy link

codecov bot commented Nov 19, 2025

Codecov Report

❌ Patch coverage is 26.40449% with 131 lines in your changes missing coverage. Please review.
✅ Project coverage is 17.56%. Comparing base (6dc259c) to head (22a8e58).

Files with missing lines Patch % Lines
...xtensions/manager/ExtensionsImportManagerImpl.java 0.00% 53 Missing ⚠️
...dstack/framework/extensions/util/ZipExtractor.java 0.00% 31 Missing ⚠️
...ack/framework/extensions/util/ExtensionConfig.java 31.57% 25 Missing and 1 partial ⚠️
...k/framework/extensions/api/ImportExtensionCmd.java 0.00% 17 Missing ⚠️
...oudstack/framework/extensions/util/YamlParser.java 72.72% 2 Missing and 1 partial ⚠️
...work/extensions/manager/ExtensionsManagerImpl.java 96.42% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##               main   #12102    +/-   ##
==========================================
  Coverage     17.55%   17.56%            
- Complexity    15535    15545    +10     
==========================================
  Files          5911     5917     +6     
  Lines        529359   529541   +182     
  Branches      64655    64674    +19     
==========================================
+ Hits          92949    93007    +58     
- Misses       425952   426074   +122     
- Partials      10458    10460     +2     
Flag Coverage Δ
uitests 3.58% <ø> (-0.01%) ⬇️
unittests 18.63% <26.40%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@shwstppr shwstppr changed the title feature: import extension using yaml manifest extension: import using yaml manifest Nov 19, 2025
Signed-off-by: Abhishek Kumar <[email protected]>
@shwstppr
Copy link
Contributor Author

Thanks @weizhouapache. Currently, local upload is not supported. Also, for local upload, do you mean uploading the manifest YAML from local machine or the complete extension source?
Either way, it would first need implementation of allowing upload on the management server (Currently we only upload via SSVM) or we upload to SSVM (secondary store) and then transfer to the management server host
If it is just the YAML then we can follow the same flow - get YAML, parse it, download the extension source and automate the process of adding extension and its actions.
For extension source upload, the operator need to pass extension details like name, description, type, etc.

Signed-off-by: Abhishek Kumar <[email protected]>
Signed-off-by: Abhishek Kumar <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants