Skip to content

Commit

Permalink
inject sidecar share volume
Browse files Browse the repository at this point in the history
  • Loading branch information
niqdev committed Oct 15, 2023
1 parent 0b9a0da commit cb2cb1b
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 22 deletions.
4 changes: 2 additions & 2 deletions pkg/box/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ func (box *DockerBoxClient) createBox(opts *boxModel.CreateOptions) (*boxModel.B
if opts.CommonInfo.NetworkVpn != nil {
// set all network configs on the sidecar to avoid option conflicts
sidecarOpts := &commonModel.SidecarVpnInjectOpts{
MainContainerName: containerName,
VpnInfo: opts.CommonInfo.NetworkVpn,
MainContainerId: containerName,
NetworkVpn: opts.CommonInfo.NetworkVpn,
}
if sidecarContainerId, err := box.dockerCommon.SidecarVpnInject(sidecarOpts, portConfig); err != nil {
return nil, err
Expand Down
19 changes: 17 additions & 2 deletions pkg/box/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,22 @@ func (box *KubeBoxClient) createBox(opts *boxModel.CreateOptions) (*boxModel.Box
box.eventBus.Publish(newServiceCreateIgnoreKubeEvent(namespace, service.Name))
}

// inject sidecar-volume
if opts.CommonInfo.ShareDir != nil {
sidecarOpts := &commonModel.SidecarShareInjectOpts{
MainContainerName: util.ToLowerKebabCase(opts.Template.Image.Repository),
ShareDir: opts.CommonInfo.ShareDir,
}
if err := box.kubeCommon.SidecarShareInject(sidecarOpts, &deployment.Spec.Template.Spec); err != nil {
return nil, err
}
}

// create secret and inject sidecar-vpn
if opts.CommonInfo.NetworkVpn != nil {
sidecarOpts := &commonModel.SidecarVpnInjectOpts{
MainContainerName: boxName,
VpnInfo: opts.CommonInfo.NetworkVpn,
MainContainerId: boxName,
NetworkVpn: opts.CommonInfo.NetworkVpn,
}
if err := box.kubeCommon.SidecarVpnInject(namespace, sidecarOpts, &deployment.Spec.Template.Spec); err != nil {
return nil, err
Expand All @@ -84,6 +95,10 @@ func (box *KubeBoxClient) createBox(opts *boxModel.CreateOptions) (*boxModel.Box
}
box.eventBus.Publish(newDeploymentCreateKubeEvent(namespace, deployment.Name))

// upload shared directory
if opts.CommonInfo.ShareDir != nil {
}

podInfo, err := box.client.PodDescribeFromDeployment(deployment)
if err != nil {
return nil, err
Expand Down
12 changes: 6 additions & 6 deletions pkg/common/docker/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,28 +111,28 @@ func buildSidecarVpnName(containerName string) string {
func (common *DockerCommonClient) SidecarVpnInject(opts *commonModel.SidecarVpnInjectOpts, portConfig *docker.ContainerPortConfigOpts) (string, error) {

// sidecarName
containerName := buildSidecarVpnName(opts.MainContainerName)
containerName := buildSidecarVpnName(opts.MainContainerId)

// constants
imageName := commonModel.SidecarVpnImageName
// base directory "/usr/share" must exist
vpnConfigPath := "/usr/share/client.ovpn"

if err := common.PullImageOffline(imageName, func() {
common.eventBus.Publish(newSidecarVpnConnectDockerEvent(opts.VpnInfo.Name))
common.eventBus.Publish(newSidecarVpnConnectDockerLoaderEvent(opts.VpnInfo.Name))
common.eventBus.Publish(newSidecarVpnConnectDockerEvent(opts.NetworkVpn.Name))
common.eventBus.Publish(newSidecarVpnConnectDockerLoaderEvent(opts.NetworkVpn.Name))
}); err != nil {
return "", err
}

containerConfig, err := docker.BuildContainerConfig(&docker.ContainerConfigOpts{
ImageName: imageName,
Hostname: opts.MainContainerName,
Hostname: opts.MainContainerId,
Env: []docker.ContainerEnv{{Key: "OPENVPN_CONFIG", Value: vpnConfigPath}},
Ports: portConfig.Ports,
Tty: false,
Cmd: []string{},
Labels: commonModel.NewSidecarLabels().AddSidecarMain(opts.MainContainerName),
Labels: commonModel.NewSidecarLabels().AddSidecarMain(opts.MainContainerId),
})
if err != nil {
return "", err
Expand All @@ -151,7 +151,7 @@ func (common *DockerCommonClient) SidecarVpnInject(opts *commonModel.SidecarVpnI
CaptureInterrupt: false, // edge case: killing this while creating will leave an orphan sidecar container
OnContainerCreateCallback: func(containerId string) error {
// upload openvpn config file
return common.client.CopyFileToContainer(containerId, opts.VpnInfo.LocalPath, vpnConfigPath)
return common.client.CopyFileToContainer(containerId, opts.NetworkVpn.LocalPath, vpnConfigPath)
},
OnContainerStatusCallback: func(status string) {
common.eventBus.Publish(newSidecarVpnCreateStatusDockerEvent(status))
Expand Down
6 changes: 3 additions & 3 deletions pkg/common/kubernetes/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ func injectSidecarVpn(podSpec *corev1.PodSpec, mainContainerName string) {
{
Name: fmt.Sprintf("%ssleep", commonModel.SidecarPrefixName),
Image: "busybox",
Stdin: true, // fixes PostStartHookError
Lifecycle: &corev1.Lifecycle{
PostStart: &corev1.LifecycleHandler{
Exec: &corev1.ExecAction{
Expand All @@ -134,7 +135,6 @@ func buildSidecarShareContainer(remoteDir string) corev1.Container {
return corev1.Container{
Name: fmt.Sprintf("%sshare", commonModel.SidecarPrefixName),
Image: "busybox", // only requirement is the "tar" binary
TTY: true,
Stdin: true,
VolumeMounts: []corev1.VolumeMount{
{
Expand All @@ -148,9 +148,9 @@ func buildSidecarShareContainer(remoteDir string) corev1.Container {
func injectSidecarShare(podSpec *corev1.PodSpec, mainContainerName string, remoteDir string) {

// mount read-only shared volume to main container
for _, c := range podSpec.Containers {
for index, c := range podSpec.Containers {
if c.Name == mainContainerName {
c.VolumeMounts = append(
podSpec.Containers[index].VolumeMounts = append(
c.VolumeMounts,
corev1.VolumeMount{
Name: sidecarShareVolume,
Expand Down
62 changes: 62 additions & 0 deletions pkg/common/kubernetes/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ spec:
- 1s
name: sidecar-sleep
resources: {}
stdin: true
- image: my-image
name: my-name
resources: {}
Expand Down Expand Up @@ -174,3 +175,64 @@ status: {}

assert.YAMLEqf(t, expected, kubernetes.ObjectToYaml(actual), "unexpected pod")
}

func TestInjectSidecarShare(t *testing.T) {

expected := `
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
spec:
containers:
- image: my-image
name: my-name
resources: {}
volumeMounts:
- mountPath: /tmp/foo
name: sidecar-share-volume
readOnly: true
- image: busybox
name: sidecar-share
resources: {}
stdin: true
volumeMounts:
- mountPath: /tmp/foo
name: sidecar-share-volume
volumes:
- hostPath:
path: my-path
name: my-volume
- emptyDir: {}
name: sidecar-share-volume
status: {}
`

containerName := "my-name"
shareDir := "/tmp/foo"
actual := &corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: containerName,
Image: "my-image",
},
},
Volumes: []corev1.Volume{
{
Name: "my-volume",
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "my-path",
},
},
},
},
},
}
injectSidecarShare(&actual.Spec, containerName, shareDir)
// fix model
actual.TypeMeta = metav1.TypeMeta{Kind: "Pod", APIVersion: "v1"}

assert.YAMLEqf(t, expected, kubernetes.ObjectToYaml(actual), "unexpected pod")
}
13 changes: 10 additions & 3 deletions pkg/common/kubernetes/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,22 @@ func (common *KubeCommonClient) SidecarVpnDelete(namespace string, mainContainer
func (common *KubeCommonClient) SidecarVpnInject(namespace string, opts *commonModel.SidecarVpnInjectOpts, podSpec *corev1.PodSpec) error {

// create secret
secret := buildSidecarVpnSecret(namespace, opts.MainContainerName, opts.VpnInfo.ConfigValue)
secret := buildSidecarVpnSecret(namespace, opts.MainContainerId, opts.NetworkVpn.ConfigValue)
common.eventBus.Publish(newSecretCreateKubeEvent(namespace, secret.Name))
if err := common.client.SecretCreate(namespace, secret); err != nil {
return err
}

// update pod
injectSidecarVpn(podSpec, opts.MainContainerName)
common.eventBus.Publish(newSidecarVpnConnectKubeEvent(opts.VpnInfo.Name))
injectSidecarVpn(podSpec, opts.MainContainerId)
common.eventBus.Publish(newSidecarVpnConnectKubeEvent(opts.NetworkVpn.Name))

return nil
}

func (common *KubeCommonClient) SidecarShareInject(opts *commonModel.SidecarShareInjectOpts, podSpec *corev1.PodSpec) error {
// update pod
injectSidecarShare(podSpec, opts.MainContainerName, opts.ShareDir.RemotePath)
common.eventBus.Publish(newSidecarShareMountKubeEvent(opts.ShareDir.RemotePath))
return nil
}
4 changes: 4 additions & 0 deletions pkg/common/kubernetes/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ func newSecretDeleteKubeEvent(namespace string, name string) *kubeCommonEvent {
func newSidecarVpnConnectKubeEvent(vpnName string) *kubeCommonEvent {
return &kubeCommonEvent{kind: event.LogInfo, value: fmt.Sprintf("sidecar-vpn connect: vpnName=%s", vpnName)}
}

func newSidecarShareMountKubeEvent(shareDir string) *kubeCommonEvent {
return &kubeCommonEvent{kind: event.LogInfo, value: fmt.Sprintf("sidecar-share mount: shareDir=%s", shareDir)}
}
5 changes: 3 additions & 2 deletions pkg/common/model/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ func NewStdStreamOpts(tty bool) *StreamOptions {
}

type SidecarVpnInjectOpts struct {
MainContainerName string
VpnInfo *NetworkVpnInfo
MainContainerId string
NetworkVpn *NetworkVpnInfo
}

type SidecarShareInjectOpts struct {
MainContainerName string
ShareDir *ShareDirInfo
}
4 changes: 2 additions & 2 deletions pkg/task/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ func (task *DockerTaskClient) runTask(opts *taskModel.RunOptions) error {
var networkMode string
if opts.CommonInfo.NetworkVpn != nil {
sidecarOpts := &commonModel.SidecarVpnInjectOpts{
MainContainerName: containerName,
VpnInfo: opts.CommonInfo.NetworkVpn,
MainContainerId: containerName,
NetworkVpn: opts.CommonInfo.NetworkVpn,
}
if sidecarContainerId, err := task.dockerCommon.SidecarVpnInject(sidecarOpts, &docker.ContainerPortConfigOpts{}); err != nil {
return err
Expand Down
19 changes: 17 additions & 2 deletions pkg/task/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,22 @@ func (task *KubeTaskClient) runTask(opts *taskModel.RunOptions) error {
},
})

// inject sidecar-volume
if opts.CommonInfo.ShareDir != nil {
sidecarOpts := &commonModel.SidecarShareInjectOpts{
MainContainerName: util.ToLowerKebabCase(opts.Template.Image.Repository),
ShareDir: opts.CommonInfo.ShareDir,
}
if err := task.kubeCommon.SidecarShareInject(sidecarOpts, &jobSpec.Spec.Template.Spec); err != nil {
return err
}
}

// create secret and inject sidecar-vpn
if opts.CommonInfo.NetworkVpn != nil {
sidecarOpts := &commonModel.SidecarVpnInjectOpts{
MainContainerName: jobName,
VpnInfo: opts.CommonInfo.NetworkVpn,
MainContainerId: jobName,
NetworkVpn: opts.CommonInfo.NetworkVpn,
}
if err := task.kubeCommon.SidecarVpnInject(namespace, sidecarOpts, &jobSpec.Spec.Template.Spec); err != nil {
return err
Expand All @@ -93,6 +104,10 @@ func (task *KubeTaskClient) runTask(opts *taskModel.RunOptions) error {
}
task.eventBus.Publish(newJobCreateKubeEvent(namespace, jobName))

// upload shared directory
if opts.CommonInfo.ShareDir != nil {
}

podInfo, err := task.client.JobDescribe(namespace, jobName)
if err != nil {
return err
Expand Down

0 comments on commit cb2cb1b

Please sign in to comment.