Skip to content

Commit

Permalink
[Feature] Scheduler CLI (#1624)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajanikow authored Mar 25, 2024
1 parent e5ae994 commit 386efa1
Show file tree
Hide file tree
Showing 7 changed files with 714 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- (Feature) ArangoProfile Selectors
- (Bugfix) Remove ImagePullSecrets Reference from Container
- (Feature) DebugPackage ArangoProfiles
- (Feature) Scheduler CLI

## [1.2.39](https://github.com/arangodb/kube-arangodb/tree/1.2.39) (2024-03-11)
- (Feature) Extract Scheduler API
Expand Down
39 changes: 39 additions & 0 deletions cmd/scheduler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//

package cmd

import (
"github.com/spf13/cobra"

"github.com/arangodb/kube-arangodb/pkg/scheduler"
)

func init() {
cmd := &cobra.Command{
Use: "scheduler",
}

if err := scheduler.InitCommand(cmd); err != nil {
panic(err.Error())
}

cmdMain.AddCommand(cmd)
}
150 changes: 150 additions & 0 deletions pkg/scheduler/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//

package scheduler

import (
"context"
"os"
"strings"

"github.com/spf13/cobra"
"sigs.k8s.io/yaml"

"github.com/arangodb/kube-arangodb/pkg/logging"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
)

func InitCommand(cmd *cobra.Command) error {
var c cli
return c.register(cmd)
}

type cli struct {
Namespace string

Labels []string
Envs []string

Profiles []string

Container string

Image string
}

func (c *cli) asRequest(args ...string) (Request, error) {
var r = Request{
Labels: map[string]string{},
Envs: map[string]string{},
}

for _, l := range c.Labels {
p := strings.SplitN(l, "=", 2)
if len(p) == 1 {
r.Labels[p[0]] = ""
logger.Debug("Label Discovered: %s", p[0])
} else {
r.Labels[p[0]] = p[1]
logger.Debug("Label Discovered: %s=%s", p[0], p[1])
}
}

for _, l := range c.Envs {
p := strings.SplitN(l, "=", 2)
if len(p) == 1 {
return r, errors.Errorf("Missing value for env: %s", p[0])
} else {
r.Envs[p[0]] = p[1]
logger.Debug("Env Discovered: %s=%s", p[0], p[1])
}
}

if len(c.Profiles) > 0 {
r.Profiles = c.Profiles
logger.Debug("Enabling profiles: %s", strings.Join(c.Profiles, ", "))
}

r.Container = util.NewType(c.Container)
if c.Image != "" {
r.Image = util.NewType(c.Image)
}

r.Args = args

return r, nil
}

func (c *cli) register(cmd *cobra.Command) error {
if err := logging.Init(cmd); err != nil {
return err
}

cmd.RunE = c.run

f := cmd.PersistentFlags()

f.StringVarP(&c.Namespace, "namespace", "n", constants.NamespaceWithDefault("default"), "Kubernetes namespace")
f.StringSliceVarP(&c.Labels, "label", "l", nil, "Scheduler Render Labels in format <key>=<value>")
f.StringSliceVarP(&c.Envs, "env", "e", nil, "Scheduler Render Envs in format <key>=<value>")
f.StringSliceVarP(&c.Profiles, "profile", "p", nil, "Scheduler Render Profiles")
f.StringVar(&c.Container, "container", DefaultContainerName, "Container Name")
f.StringVar(&c.Image, "image", "", "Image")

return nil
}

func (c *cli) run(cmd *cobra.Command, args []string) error {
if err := logging.Enable(); err != nil {
return err
}

r, err := c.asRequest()
if err != nil {
return err
}

k, ok := kclient.GetDefaultFactory().Client()
if !ok {
return errors.Errorf("Unable to create Kubernetes Client")
}

s := NewScheduler(k, c.Namespace)

rendered, profiles, err := s.Render(context.Background(), r)
if err != nil {
return err
}
logger.Debug("Enabled profiles: %s", strings.Join(profiles, ", "))

data, err := yaml.Marshal(rendered)
if err != nil {
return err
}

if _, err := util.WriteAll(os.Stdout, data); err != nil {
return err
}

return nil
}
91 changes: 91 additions & 0 deletions pkg/scheduler/input.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//

package scheduler

import (
"math"

core "k8s.io/api/core/v1"

schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1"
schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container"
schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources"
schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod"
schedulerPodResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod/resources"
"github.com/arangodb/kube-arangodb/pkg/util"
)

const DefaultContainerName = "job"

type Request struct {
Labels map[string]string

Profiles []string

Envs map[string]string

Container *string

Image *string

Args []string
}

func (r Request) AsTemplate() *schedulerApi.ProfileTemplate {
var container schedulerContainerApi.Container

if len(r.Envs) > 0 {
container.Environments = &schedulerContainerResourcesApi.Environments{}

for k, v := range r.Envs {
container.Environments.Env = append(container.Environments.Env, core.EnvVar{
Name: k,
Value: v,
})
}
}

if len(r.Args) > 0 {
container.Core = &schedulerContainerResourcesApi.Core{
Args: r.Args,
}
}

if r.Image != nil {
container.Image = &schedulerContainerResourcesApi.Image{
Image: util.NewType(util.TypeOrDefault(r.Image)),
}
}

return &schedulerApi.ProfileTemplate{
Priority: util.NewType(math.MaxInt),
Pod: &schedulerPodApi.Pod{
Metadata: &schedulerPodResourcesApi.Metadata{
Labels: util.MergeMaps(true, r.Labels),
},
},
Container: &schedulerApi.ProfileContainerTemplate{
Containers: map[string]schedulerContainerApi.Container{
util.TypeOrDefault(r.Container, DefaultContainerName): container,
},
},
}
}
25 changes: 25 additions & 0 deletions pkg/scheduler/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//

package scheduler

import "github.com/arangodb/kube-arangodb/pkg/logging"

var logger = logging.Global().RegisterAndGetLogger("scheduler", logging.Info)
Loading

0 comments on commit 386efa1

Please sign in to comment.