Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(api): list docker volume performance [EE-6896] #11754

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion api/cmd/portainer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {

kubeClusterAccessService := kubernetes.NewKubeClusterAccessService(*flags.BaseURL, *flags.AddrHTTPS, sslSettings.CertPath)

proxyManager := proxy.NewManager(dataStore, digitalSignatureService, reverseTunnelService, dockerClientFactory, kubernetesClientFactory, kubernetesTokenCacheManager, gitService)
proxyManager := proxy.NewManager(kubernetesClientFactory)

reverseTunnelService.ProxyManager = proxyManager

Expand Down Expand Up @@ -490,6 +490,8 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
}
snapshotService.Start()

proxyManager.NewProxyFactory(dataStore, digitalSignatureService, reverseTunnelService, dockerClientFactory, kubernetesClientFactory, kubernetesTokenCacheManager, gitService, snapshotService)

helmPackageManager, err := initHelmPackageManager(*flags.Assets)
if err != nil {
log.Fatal().Err(err).Msg("failed initializing helm package manager")
Expand Down
3 changes: 2 additions & 1 deletion api/http/handler/endpoints/endpoint_delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ func TestEndpointDeleteEdgeGroupsConcurrently(t *testing.T) {

handler := NewHandler(testhelpers.NewTestRequestBouncer(), demo.NewService())
handler.DataStore = store
handler.ProxyManager = proxy.NewManager(nil, nil, nil, nil, nil, nil, nil)
handler.ProxyManager = proxy.NewManager(nil)
handler.ProxyManager.NewProxyFactory(nil, nil, nil, nil, nil, nil, nil, nil)

// Create all the environments and add them to the same edge group

Expand Down
2 changes: 1 addition & 1 deletion api/http/proxy/factory/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (factory *ProxyFactory) newDockerHTTPProxy(endpoint *portainer.Endpoint) (h
DockerClientFactory: factory.dockerClientFactory,
}

dockerTransport, err := docker.NewTransport(transportParameters, httpTransport, factory.gitService)
dockerTransport, err := docker.NewTransport(transportParameters, httpTransport, factory.gitService, factory.snapshotService)
if err != nil {
return nil, err
}
Expand Down
4 changes: 3 additions & 1 deletion api/http/proxy/factory/docker/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type (
reverseTunnelService portainer.ReverseTunnelService
dockerClientFactory *dockerclient.ClientFactory
gitService portainer.GitService
snapshotService portainer.SnapshotService
}

// TransportParameters is used to create a new Transport
Expand Down Expand Up @@ -63,7 +64,7 @@ type (
)

// NewTransport returns a pointer to a new Transport instance.
func NewTransport(parameters *TransportParameters, httpTransport *http.Transport, gitService portainer.GitService) (*Transport, error) {
func NewTransport(parameters *TransportParameters, httpTransport *http.Transport, gitService portainer.GitService, snapshotService portainer.SnapshotService) (*Transport, error) {
transport := &Transport{
endpoint: parameters.Endpoint,
dataStore: parameters.DataStore,
Expand All @@ -72,6 +73,7 @@ func NewTransport(parameters *TransportParameters, httpTransport *http.Transport
dockerClientFactory: parameters.DockerClientFactory,
HTTPTransport: httpTransport,
gitService: gitService,
snapshotService: snapshotService,
}

return transport, nil
Expand Down
9 changes: 9 additions & 0 deletions api/http/proxy/factory/docker/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path"

"github.com/docker/docker/client"
"github.com/rs/zerolog/log"

portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/http/proxy/factory/utils"
Expand Down Expand Up @@ -48,6 +49,14 @@ func (transport *Transport) volumeListOperation(response *http.Response, executo
if responseObject["Volumes"] != nil {
volumeData := responseObject["Volumes"].([]interface{})

if transport.snapshotService != nil {
// Filling snapshot data can improve the performance of getVolumeResourceID
if err = transport.snapshotService.FillSnapshotData(transport.endpoint); err != nil {
log.Info().Err(err).
Int("endpoint id", int(transport.endpoint.ID)).
Msg("snapshot is not filled into the endpoint.")
}
}
for _, volumeObject := range volumeData {
volume := volumeObject.(map[string]interface{})

Expand Down
2 changes: 1 addition & 1 deletion api/http/proxy/factory/docker_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (factory ProxyFactory) newOSBasedLocalProxy(path string, endpoint *portaine

proxy := &dockerLocalProxy{}

dockerTransport, err := docker.NewTransport(transportParameters, newSocketTransport(path), factory.gitService)
dockerTransport, err := docker.NewTransport(transportParameters, newSocketTransport(path), factory.gitService, factory.snapshotService)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion api/http/proxy/factory/docker_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (factory ProxyFactory) newOSBasedLocalProxy(path string, endpoint *portaine

proxy := &dockerLocalProxy{}

dockerTransport, err := docker.NewTransport(transportParameters, newNamedPipeTransport(path), factory.gitService)
dockerTransport, err := docker.NewTransport(transportParameters, newNamedPipeTransport(path), factory.gitService, factory.snapshotService)
if err != nil {
return nil, err
}
Expand Down
4 changes: 3 additions & 1 deletion api/http/proxy/factory/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ type (
kubernetesClientFactory *cli.ClientFactory
kubernetesTokenCacheManager *kubernetes.TokenCacheManager
gitService portainer.GitService
snapshotService portainer.SnapshotService
}
)

// NewProxyFactory returns a pointer to a new instance of a ProxyFactory
func NewProxyFactory(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *dockerclient.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService) *ProxyFactory {
func NewProxyFactory(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *dockerclient.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService, snapshotService portainer.SnapshotService) *ProxyFactory {
return &ProxyFactory{
dataStore: dataStore,
signatureService: signatureService,
Expand All @@ -36,6 +37,7 @@ func NewProxyFactory(dataStore dataservices.DataStore, signatureService portaine
kubernetesClientFactory: kubernetesClientFactory,
kubernetesTokenCacheManager: kubernetesTokenCacheManager,
gitService: gitService,
snapshotService: snapshotService,
}
}

Expand Down
17 changes: 15 additions & 2 deletions api/http/proxy/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,24 @@ type (
)

// NewManager initializes a new proxy Service
func NewManager(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *dockerclient.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService) *Manager {
func NewManager(kubernetesClientFactory *cli.ClientFactory) *Manager {
return &Manager{
endpointProxies: cmap.New(),
k8sClientFactory: kubernetesClientFactory,
proxyFactory: factory.NewProxyFactory(dataStore, signatureService, tunnelService, clientFactory, kubernetesClientFactory, kubernetesTokenCacheManager, gitService),
}
}

func (manager *Manager) NewProxyFactory(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *dockerclient.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService, snapshotService portainer.SnapshotService) {
manager.proxyFactory = factory.NewProxyFactory(dataStore, signatureService, tunnelService, clientFactory, kubernetesClientFactory, kubernetesTokenCacheManager, gitService, snapshotService)
}

// CreateAndRegisterEndpointProxy creates a new HTTP reverse proxy based on environment(endpoint) properties and and adds it to the registered proxies.
// It can also be used to create a new HTTP reverse proxy and replace an already registered proxy.
func (manager *Manager) CreateAndRegisterEndpointProxy(endpoint *portainer.Endpoint) (http.Handler, error) {
if manager.proxyFactory == nil {
return nil, fmt.Errorf("proxy factory not init")
}

proxy, err := manager.proxyFactory.NewEndpointProxy(endpoint)
if err != nil {
return nil, err
Expand All @@ -48,6 +55,9 @@ func (manager *Manager) CreateAndRegisterEndpointProxy(endpoint *portainer.Endpo
// CreateAgentProxyServer creates a new HTTP reverse proxy based on environment(endpoint) properties and and adds it to the registered proxies.
// It can also be used to create a new HTTP reverse proxy and replace an already registered proxy.
func (manager *Manager) CreateAgentProxyServer(endpoint *portainer.Endpoint) (*factory.ProxyServer, error) {
if manager.proxyFactory == nil {
return nil, fmt.Errorf("proxy factory not init")
}
return manager.proxyFactory.NewAgentProxy(endpoint)
}

Expand All @@ -74,5 +84,8 @@ func (manager *Manager) DeleteEndpointProxy(endpointID portainer.EndpointID) {

// CreateGitlabProxy creates a new HTTP reverse proxy that can be used to send requests to the Gitlab API
func (manager *Manager) CreateGitlabProxy(url string) (http.Handler, error) {
if manager.proxyFactory == nil {
return nil, fmt.Errorf("proxy factory not init")
}
return manager.proxyFactory.NewGitlabProxy(url)
}