mirror of
https://github.com/gitpod-io/gitpod.git
synced 2025-12-08 17:36:30 +00:00
135 lines
3.1 KiB
Go
135 lines
3.1 KiB
Go
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
|
|
// Licensed under the GNU Affero General Public License (AGPL).
|
|
// See License-AGPL.txt in the project root for license information.
|
|
|
|
package cgroup
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/gitpod-io/gitpod/common-go/cgroups"
|
|
"github.com/gitpod-io/gitpod/common-go/log"
|
|
"github.com/gitpod-io/gitpod/ws-daemon/pkg/dispatch"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
func NewPluginHost(cgroupBasePath string, plugins ...Plugin) (*PluginHost, error) {
|
|
var version Version
|
|
unified, err := cgroups.IsUnifiedCgroupSetup()
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("could not determine cgroup setup: %w", err)
|
|
}
|
|
if unified {
|
|
version = Version2
|
|
} else {
|
|
version = Version1
|
|
}
|
|
|
|
return &PluginHost{
|
|
CGroupBasePath: cgroupBasePath,
|
|
CGroupVersion: version,
|
|
Plugins: plugins,
|
|
|
|
pluginActivationTotalVec: prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
Name: "cgroup_plugin_activation_total",
|
|
Help: "counts the total activation of cgroup plugins",
|
|
}, []string{"plugin", "success"}),
|
|
}, nil
|
|
}
|
|
|
|
type PluginHost struct {
|
|
CGroupBasePath string
|
|
CGroupVersion Version
|
|
Plugins []Plugin
|
|
|
|
pluginActivationTotalVec *prometheus.CounterVec
|
|
}
|
|
|
|
var _ dispatch.Listener = &PluginHost{}
|
|
var _ prometheus.Collector = &PluginHost{}
|
|
|
|
func (host *PluginHost) Describe(c chan<- *prometheus.Desc) {
|
|
host.pluginActivationTotalVec.Describe(c)
|
|
for _, p := range host.Plugins {
|
|
col, ok := p.(prometheus.Collector)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
col.Describe(c)
|
|
}
|
|
}
|
|
|
|
func (host *PluginHost) Collect(c chan<- prometheus.Metric) {
|
|
host.pluginActivationTotalVec.Collect(c)
|
|
for _, p := range host.Plugins {
|
|
col, ok := p.(prometheus.Collector)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
col.Collect(c)
|
|
}
|
|
}
|
|
|
|
func (host *PluginHost) WorkspaceAdded(ctx context.Context, ws *dispatch.Workspace) (err error) {
|
|
disp := dispatch.GetFromContext(ctx)
|
|
if disp == nil {
|
|
return xerrors.Errorf("no dispatch available")
|
|
}
|
|
|
|
cgroupPath, err := disp.Runtime.ContainerCGroupPath(context.Background(), ws.ContainerID)
|
|
if err != nil {
|
|
return xerrors.Errorf("cannot get cgroup path for container %s: %w", ws.ContainerID, err)
|
|
}
|
|
|
|
opts := &PluginOptions{
|
|
BasePath: host.CGroupBasePath,
|
|
CgroupPath: cgroupPath,
|
|
InstanceId: ws.InstanceID,
|
|
Annotations: ws.Pod.Annotations,
|
|
}
|
|
|
|
for _, plg := range host.Plugins {
|
|
if plg.Type() != host.CGroupVersion {
|
|
continue
|
|
}
|
|
|
|
go func(plg Plugin) {
|
|
err := plg.Apply(ctx, opts)
|
|
if err == context.Canceled || err == context.DeadlineExceeded {
|
|
err = nil
|
|
}
|
|
if err != nil {
|
|
log.WithError(err).WithFields(ws.OWI()).WithField("plugin", plg.Name()).Error("cgroup plugin failure")
|
|
host.pluginActivationTotalVec.WithLabelValues(plg.Name(), "false").Inc()
|
|
} else {
|
|
host.pluginActivationTotalVec.WithLabelValues(plg.Name(), "true").Inc()
|
|
}
|
|
}(plg)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type Plugin interface {
|
|
Name() string
|
|
Type() Version
|
|
Apply(ctx context.Context, options *PluginOptions) error
|
|
}
|
|
|
|
type Version int
|
|
|
|
const (
|
|
Version1 Version = iota
|
|
Version2
|
|
)
|
|
|
|
type PluginOptions struct {
|
|
BasePath string
|
|
CgroupPath string
|
|
InstanceId string
|
|
Annotations map[string]string
|
|
}
|