Skip to content

Commit

Permalink
improved windows support
Browse files Browse the repository at this point in the history
Signed-off-by: Kent Rancourt <kent.rancourt@microsoft.com>
  • Loading branch information
krancour committed Nov 5, 2021
1 parent 1f48d4c commit abf035e
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 52 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -433,9 +433,9 @@ hack-deploy:
--set worker.image.repository=$(DOCKER_IMAGE_PREFIX)worker \
--set worker.image.tag=$(IMMUTABLE_DOCKER_TAG) \
--set worker.image.pullPolicy=$(IMAGE_PULL_POLICY) \
--set gitInitializer.image.repository=$(DOCKER_IMAGE_PREFIX)git-initializer \
--set gitInitializer.image.tag=$(IMMUTABLE_DOCKER_TAG) \
--set gitInitializer.image.pullPolicy=$(IMAGE_PULL_POLICY) \
--set gitInitializer.linux.image.repository=$(DOCKER_IMAGE_PREFIX)git-initializer \
--set gitInitializer.linux.image.tag=$(IMMUTABLE_DOCKER_TAG) \
--set gitInitializer.linux.image.pullPolicy=$(IMAGE_PULL_POLICY) \
--set logger.linux.image.repository=$(DOCKER_IMAGE_PREFIX)logger\
--set logger.linux.image.tag=$(IMMUTABLE_DOCKER_TAG) \
--set logger.linux.image.pullPolicy=$(IMAGE_PULL_POLICY)
Expand Down
8 changes: 6 additions & 2 deletions charts/brigade/templates/apiserver/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,13 @@ spec:
name: {{ include "brigade.artemis.fullname" . }}
key: password
- name: GIT_INITIALIZER_IMAGE
value: {{ .Values.gitInitializer.image.repository }}:{{ default .Chart.AppVersion .Values.gitInitializer.image.tag }}
value: {{ .Values.gitInitializer.linux.image.repository }}:{{ default .Chart.AppVersion .Values.gitInitializer.linux.image.tag }}
- name: GIT_INITIALIZER_IMAGE_PULL_POLICY
value: {{ .Values.gitInitializer.image.pullPolicy }}
value: {{ .Values.gitInitializer.linux.image.pullPolicy }}
- name: GIT_INITIALIZER_WINDOWS_IMAGE
value: {{ .Values.gitInitializer.windows.image.repository }}:{{ default .Chart.AppVersion .Values.gitInitializer.windows.image.tag }}
- name: GIT_INITIALIZER_WINDOWS_IMAGE_PULL_POLICY
value: {{ .Values.gitInitializer.windows.image.pullPolicy }}
- name: DEFAULT_WORKER_IMAGE
value: {{ .Values.worker.image.repository }}:{{ default .Chart.AppVersion .Values.worker.image.tag }}
- name: DEFAULT_WORKER_IMAGE_PULL_POLICY
Expand Down
21 changes: 15 additions & 6 deletions charts/brigade/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,21 @@ observer:

gitInitializer:

image:
repository: brigadecore/brigade2-git-initializer
## tag should only be specified if you want to override Chart.appVersion
## The default tag is the value of .Chart.AppVersion
# tag:
pullPolicy: IfNotPresent
linux:
image:
repository: brigadecore/brigade2-git-initializer
## tag should only be specified if you want to override Chart.appVersion
## The default tag is the value of .Chart.AppVersion
# tag:
pullPolicy: IfNotPresent

windows:
image:
repository: brigadecore/brigade2-git-initializer-windows
## tag should only be specified if you want to override Chart.appVersion
## The default tag is the value of .Chart.AppVersion
# tag:
pullPolicy: IfNotPresent

worker:

Expand Down
12 changes: 11 additions & 1 deletion sdk/v2/core/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ import (
// JobKind represents the canonical Job kind string
const JobKind = "Job"

// OSFamily represents a type of operating system.
type OSFamily string

const (
// OSFamilyLinux represents a Linux-based OS.
OSFamilyLinux OSFamily = "linux"
// OSFamilyWindows represents a Windows-based OS.
OSFamilyWindows OSFamily = "windows"
)

// JobPhase represents where a Job is within its lifecycle.
type JobPhase string

Expand Down Expand Up @@ -182,7 +192,7 @@ type JobHost struct {
// OS specifies which "family" of operating system is required on a substrate
// node to host a Job. Valid values are "linux" and "windows". When empty,
// Brigade assumes "linux".
OS string `json:"os,omitempty"`
OS OSFamily `json:"os,omitempty"`
// NodeSelector specifies labels that must be present on the substrate node to
// host a Job. This provides an opaque mechanism for communicating Job needs
// such as specific hardware like an SSD or GPU.
Expand Down
12 changes: 12 additions & 0 deletions v2/apiserver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,18 @@ func substrateConfig() (kubernetes.SubstrateConfig, error) {
}
config.GitInitializerImagePullPolicy =
api.ImagePullPolicy(gitInitializerImagePullPolicyStr)
config.GitInitializerWindowsImage, err =
os.GetRequiredEnvVar("GIT_INITIALIZER_WINDOWS_IMAGE")
if err != nil {
return config, err
}
gitInitializerWindowsImagePullPolicyStr, err :=
os.GetRequiredEnvVar("GIT_INITIALIZER_WINDOWS_IMAGE_PULL_POLICY")
if err != nil {
return config, err
}
config.GitInitializerWindowsImagePullPolicy =
api.ImagePullPolicy(gitInitializerWindowsImagePullPolicyStr)
config.DefaultWorkerImage, err = os.GetRequiredEnvVar("DEFAULT_WORKER_IMAGE")
if err != nil {
return config, err
Expand Down
63 changes: 55 additions & 8 deletions v2/apiserver/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,18 @@ func TestWriterFactoryConfig(t *testing.T) {
}

func TestSubstrateConfig(t *testing.T) {
const testBrigadeID = "4077th"
const testAPIAddress = "http://localhost"
const testGitInitializerImage = "brigadecore/brigade2-git-initializer:2.0.0"
const testGitInitializerImagePullPolicy = api.ImagePullPolicy("IfNotPresent")
const testDefaultWorkerImage = "brigadecore/brigade2-worker:2.0.0"
const testDefaultWorkerImagePullPolicy = api.ImagePullPolicy("IfNotPresent")
const testWorkspaceStorageClass = "nfs"
// nolint: lll
const (
testBrigadeID = "4077th"
testAPIAddress = "http://localhost"
testGitInitializerImage = "brigadecore/brigade2-git-initializer:2.0.0"
testGitInitializerImagePullPolicy = api.ImagePullPolicy("IfNotPresent")
testGitInitializerWindowsImage = "brigadecore/brigade2-git-initializer-windows:2.0.0"
testGitInitializerWindowsImagePullPolicy = api.ImagePullPolicy("IfNotPresent")
testDefaultWorkerImage = "brigadecore/brigade2-worker:2.0.0"
testDefaultWorkerImagePullPolicy = api.ImagePullPolicy("IfNotPresent")
testWorkspaceStorageClass = "nfs"
)
testCases := []struct {
name string
setup func()
Expand Down Expand Up @@ -213,13 +218,45 @@ func TestSubstrateConfig(t *testing.T) {
},
},
{
name: "DEFAULT_WORKER_IMAGE not set",
name: "GIT_INITIALIZER_WINDOWS_IMAGE not set",
setup: func() {
t.Setenv(
"GIT_INITIALIZER_IMAGE_PULL_POLICY",
string(testGitInitializerImagePullPolicy),
)
},
assertions: func(_ kubernetes.SubstrateConfig, err error) {
require.Error(t, err)
require.Contains(t, err.Error(), "value not found for")
require.Contains(t, err.Error(), "GIT_INITIALIZER_WINDOWS_IMAGE")
},
},
{
name: "GIT_INITIALIZER_WINDOWS_IMAGE_PULL_POLICY not set",
setup: func() {
t.Setenv(
"GIT_INITIALIZER_WINDOWS_IMAGE",
testGitInitializerWindowsImage,
)
},
assertions: func(_ kubernetes.SubstrateConfig, err error) {
require.Error(t, err)
require.Contains(t, err.Error(), "value not found for")
require.Contains(
t,
err.Error(),
"GIT_INITIALIZER_WINDOWS_IMAGE_PULL_POLICY",
)
},
},
{
name: "DEFAULT_WORKER_IMAGE not set",
setup: func() {
t.Setenv(
"GIT_INITIALIZER_WINDOWS_IMAGE_PULL_POLICY",
string(testGitInitializerWindowsImagePullPolicy),
)
},
assertions: func(_ kubernetes.SubstrateConfig, err error) {
require.Error(t, err)
require.Contains(t, err.Error(), "value not found for")
Expand Down Expand Up @@ -266,6 +303,16 @@ func TestSubstrateConfig(t *testing.T) {
testGitInitializerImagePullPolicy,
config.GitInitializerImagePullPolicy,
)
require.Equal(
t,
testGitInitializerWindowsImage,
config.GitInitializerWindowsImage,
)
require.Equal(
t,
testGitInitializerWindowsImagePullPolicy,
config.GitInitializerWindowsImagePullPolicy,
)
require.Equal(t, testDefaultWorkerImage, config.DefaultWorkerImage)
require.Equal(
t,
Expand Down
12 changes: 11 additions & 1 deletion v2/apiserver/internal/api/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ import (
// JobKind represents the canonical Job kind string
const JobKind = "Job"

// OSFamily represents a type of operating system.
type OSFamily string

const (
// OSFamilyLinux represents a Linux-based OS.
OSFamilyLinux OSFamily = "linux"
// OSFamilyWindows represents a Windows-based OS.
OSFamilyWindows OSFamily = "windows"
)

// JobPhase represents where a Job is within its lifecycle.
type JobPhase string

Expand Down Expand Up @@ -216,7 +226,7 @@ type JobHost struct {
// OS specifies which "family" of operating system is required on a substrate
// node to host a Job. Valid values are "linux" and "windows". When empty,
// Brigade assumes "linux".
OS string `json:"os,omitempty" bson:"os,omitempty"`
OS OSFamily `json:"os,omitempty" bson:"os,omitempty"`
// NodeSelector specifies labels that must be present on the substrate node to
// host a Job. This provides an opaque mechanism for communicating Job needs
// such as specific hardware like an SSD or GPU.
Expand Down
57 changes: 41 additions & 16 deletions v2/apiserver/internal/api/kubernetes/substrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,20 @@ type SubstrateConfig struct {
// this information whenever it needs to tell another component where to find
// the API server.
APIAddress string
// GitInitializerImage is the name of the OCI image that will be used (when
// applicable) for the git initializer. The expected format is
// GitInitializerImage is the name of the Linux-based OCI image that will be
// used (when applicable) for the git initializer. The expected format is
// [REGISTRY/][ORG/]IMAGE_NAME[:TAG].
GitInitializerImage string
// GitInitializerImagePullPolicy is the ImagePullPolicy that will be used
// (when applicable) for the git initializer.
// (when applicable) for the Linux-based git initializer.
GitInitializerImagePullPolicy api.ImagePullPolicy
// GitInitializerWindowsImage is the name of the Windows-based OCI image that
// will be used (when applicable) for the git initializer. The expected format
// is [REGISTRY/][ORG/]IMAGE_NAME[:TAG].
GitInitializerWindowsImage string
// GitInitializerWindowsImagePullPolicy is the ImagePullPolicy that will be
// used (when applicable) for the Windows-based git initializer.
GitInitializerWindowsImagePullPolicy api.ImagePullPolicy
// DefaultWorkerImage is the name of the OCI image that will be used for the
// Worker pod's container[0] if none is specified in a Project's
// configuration. The expected format is [REGISTRY/][ORG/]IMAGE_NAME[:TAG].
Expand Down Expand Up @@ -1167,13 +1174,18 @@ func (s *substrate) createJobPod(
if useSource &&
event.Worker.Spec.Git != nil &&
event.Worker.Spec.Git.CloneURL != "" {
gitInitializerImage := s.config.GitInitializerImage
gitInitializerImagePullPolicy := s.config.GitInitializerImagePullPolicy
if jobSpec.Host != nil && jobSpec.Host.OS == api.OSFamilyWindows {
gitInitializerImage = s.config.GitInitializerWindowsImage
gitInitializerImagePullPolicy =
s.config.GitInitializerWindowsImagePullPolicy
}
initContainers = []corev1.Container{
{
Name: "vcs",
Image: s.config.GitInitializerImage,
ImagePullPolicy: corev1.PullPolicy(
s.config.GitInitializerImagePullPolicy,
),
Name: "vcs",
Image: gitInitializerImage,
ImagePullPolicy: corev1.PullPolicy(gitInitializerImagePullPolicy),
VolumeMounts: []corev1.VolumeMount{
{
Name: myk8s.LabelKeyEvent,
Expand Down Expand Up @@ -1238,23 +1250,36 @@ func (s *substrate) createJobPod(
},
}

jobPod.Spec.NodeSelector = map[string]string{}
if jobSpec.Host != nil && jobSpec.Host.OS == api.OSFamilyWindows {
jobPod.Spec.NodeSelector[corev1.LabelOSStable] = "windows"
}
if s.config.NodeSelectorKey != "" && s.config.NodeSelectorValue != "" {
jobPod.Spec.NodeSelector = map[string]string{
s.config.NodeSelectorKey: s.config.NodeSelectorValue,
}
jobPod.Spec.NodeSelector[s.config.NodeSelectorKey] =
s.config.NodeSelectorValue
}

if s.config.TolerationKey != "" {
jobPod.Spec.Tolerations = []corev1.Toleration{}
if jobSpec.Host != nil && jobSpec.Host.OS == api.OSFamilyWindows {
jobPod.Spec.Tolerations = []corev1.Toleration{
{
Key: s.config.TolerationKey,
Operator: corev1.TolerationOpExists,
Key: "os",
Operator: corev1.TolerationOpEqual,
Value: "windows",
Effect: corev1.TaintEffectNoSchedule,
},
}
}
if s.config.TolerationKey != "" {
toleration := corev1.Toleration{
Key: s.config.TolerationKey,
Operator: corev1.TolerationOpExists,
}
if s.config.TolerationValue != "" {
jobPod.Spec.Tolerations[0].Value = s.config.TolerationValue
jobPod.Spec.Tolerations[0].Operator = corev1.TolerationOpEqual
toleration.Value = s.config.TolerationValue
toleration.Operator = corev1.TolerationOpEqual
}
jobPod.Spec.Tolerations = append(jobPod.Spec.Tolerations, toleration)
}

podClient := s.kubeClient.CoreV1().Pods(project.Kubernetes.Namespace)
Expand Down
Loading

0 comments on commit abf035e

Please sign in to comment.