mirror of
https://github.com/portainer/portainer.git
synced 2025-07-23 07:19:41 +02:00
feat(extensions): add the ability to upload and enable an extension (#3345)
* feat(extensions): offline mode mockup * feat(extensions): offline mode mockup * feat(api): add support for extensionUpload API operation * feat(extensions): offline extension upload * feat(api): better support for extensions in offline mode * feat(extension): update offline description * feat(api): introduce local extension manifest * fix(api): fix LocalExtensionManifestFile value * feat(api): use a 5second timeout for online extension infos * feat(extensions): add download archive link * feat(extensions): add support for offline update * fix(api): fix issues with offline install and online updates of extensions * fix(extensions): fix extensions link URL * fix(extension): hide screenshot in offline mode
This commit is contained in:
parent
8b0eb71d69
commit
a85f0058ee
17 changed files with 440 additions and 132 deletions
|
@ -3,54 +3,28 @@ package extensions
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/coreos/go-semver/semver"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
"github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
// GET request on /api/extensions?store=<store>
|
||||
func (handler *Handler) extensionList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
storeDetails, _ := request.RetrieveBooleanQueryParameter(r, "store", true)
|
||||
fetchManifestInformation, _ := request.RetrieveBooleanQueryParameter(r, "store", true)
|
||||
|
||||
extensions, err := handler.ExtensionService.Extensions()
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve extensions from the database", err}
|
||||
}
|
||||
|
||||
if storeDetails {
|
||||
if fetchManifestInformation {
|
||||
definitions, err := handler.ExtensionManager.FetchExtensionDefinitions()
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve extensions", err}
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve extensions informations", err}
|
||||
}
|
||||
|
||||
for idx := range definitions {
|
||||
associateExtensionData(&definitions[idx], extensions)
|
||||
}
|
||||
|
||||
extensions = definitions
|
||||
extensions = mergeExtensionsAndDefinitions(extensions, definitions)
|
||||
}
|
||||
|
||||
return response.JSON(w, extensions)
|
||||
}
|
||||
|
||||
func associateExtensionData(definition *portainer.Extension, extensions []portainer.Extension) {
|
||||
for _, extension := range extensions {
|
||||
if extension.ID == definition.ID {
|
||||
|
||||
definition.Enabled = extension.Enabled
|
||||
definition.License.Company = extension.License.Company
|
||||
definition.License.Expiration = extension.License.Expiration
|
||||
definition.License.Valid = extension.License.Valid
|
||||
|
||||
definitionVersion := semver.New(definition.Version)
|
||||
extensionVersion := semver.New(extension.Version)
|
||||
if extensionVersion.LessThan(*definitionVersion) {
|
||||
definition.UpdateAvailable = true
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue