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

Move prepare-fs script to scripts configmap #1070

Merged
merged 3 commits into from
Jun 14, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions operators/pkg/controller/elasticsearch/driver/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/cleanup"
esclient "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/client"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/configmap"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/initcontainer"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/license"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/migration"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/mutation"
Expand Down Expand Up @@ -126,8 +127,7 @@ func (d *defaultDriver) Reconcile(
return results.WithError(err)
}

scriptsConfigMap := prepareScriptsConfigMap(es)
if err := configmap.ReconcileConfigMap(d.Client, d.Scheme, es, scriptsConfigMap); err != nil {
if err := reconcileScriptsConfigMap(d.Client, d.Scheme, es); err != nil {
return results.WithError(err)
}

Expand Down Expand Up @@ -535,10 +535,22 @@ func (d *defaultDriver) newElasticsearchClient(service corev1.Service, user user
return esclient.NewElasticsearchClient(d.Dialer, url, user.Auth(), v, caCerts)
}

func prepareScriptsConfigMap(es v1alpha1.Elasticsearch) corev1.ConfigMap {
return configmap.NewConfigMapWithData(
func reconcileScriptsConfigMap(c k8s.Client, scheme *runtime.Scheme, es v1alpha1.Elasticsearch) error {
fsScript, err := initcontainer.RenderPrepareFsScript()
if err != nil {
return err
}

scriptsConfigMap := configmap.NewConfigMapWithData(
types.NamespacedName{Namespace: es.Namespace, Name: name.ScriptsConfigMap(es.Name)},
map[string]string{
pod.ReadinessProbeScriptConfigKey: pod.ReadinessProbeScript,
pod.ReadinessProbeScriptConfigKey: pod.ReadinessProbeScript,
initcontainer.PrepareFsScriptConfigKey: fsScript,
})

if err := configmap.ReconcileConfigMap(c, scheme, es, scriptsConfigMap); err != nil {
return err
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ const (
func NewInitContainers(
elasticsearchImage string,
operatorImage string,
linkedFiles LinkedFilesArray,
setVMMaxMapCount *bool,
transportCertificatesVolume volume.SecretVolume,
clusterName string,
) ([]corev1.Container, error) {
var containers []corev1.Container
// create the privileged init container if not explicitly disabled by the user
Expand All @@ -38,7 +38,7 @@ func NewInitContainers(
}
containers = append(containers, osSettingsContainer)
}
prepareFsContainer, err := NewPrepareFSInitContainer(elasticsearchImage, linkedFiles, transportCertificatesVolume)
prepareFsContainer, err := NewPrepareFSInitContainer(elasticsearchImage, transportCertificatesVolume, clusterName)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ func TestNewInitContainers(t *testing.T) {
type args struct {
elasticsearchImage string
operatorImage string
linkedFiles LinkedFilesArray
SetVMMaxMapCount *bool
}
tests := []struct {
Expand All @@ -30,7 +29,6 @@ func TestNewInitContainers(t *testing.T) {
args: args{
elasticsearchImage: "es-image",
operatorImage: "op-image",
linkedFiles: LinkedFilesArray{},
SetVMMaxMapCount: &varTrue,
},
expectedNumberOfContainers: 3,
Expand All @@ -40,7 +38,6 @@ func TestNewInitContainers(t *testing.T) {
args: args{
elasticsearchImage: "es-image",
operatorImage: "op-image",
linkedFiles: LinkedFilesArray{},
SetVMMaxMapCount: nil,
},
expectedNumberOfContainers: 3,
Expand All @@ -50,7 +47,6 @@ func TestNewInitContainers(t *testing.T) {
args: args{
elasticsearchImage: "es-image",
operatorImage: "op-image",
linkedFiles: LinkedFilesArray{},
SetVMMaxMapCount: &varFalse,
},
expectedNumberOfContainers: 2,
Expand All @@ -61,9 +57,9 @@ func TestNewInitContainers(t *testing.T) {
containers, err := NewInitContainers(
tt.args.elasticsearchImage,
tt.args.operatorImage,
tt.args.linkedFiles,
tt.args.SetVMMaxMapCount,
volume.SecretVolume{},
"clusterName",
)
assert.NoError(t, err)
assert.Equal(t, tt.expectedNumberOfContainers, len(containers))
Expand Down
96 changes: 72 additions & 24 deletions operators/pkg/controller/elasticsearch/initcontainer/prepare_fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,34 @@ package initcontainer

import (
"fmt"

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

"github.com/elastic/cloud-on-k8s/operators/pkg/controller/common/certificates"
volume "github.com/elastic/cloud-on-k8s/operators/pkg/controller/common/volume"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/name"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/settings"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/user"
esvolume "github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume"
"github.com/elastic/cloud-on-k8s/operators/pkg/utils/stringsutil"
corev1 "k8s.io/api/core/v1"
)

const (
transportCertificatesVolumeMountPath = "/mnt/elastic-internal/transport-certificates"
)

// Volumes that are shared between the prepare-fs init container and the ES container
var (
DataSharedVolume = SharedVolume{
Name: esvolume.ElasticsearchDataVolumeName,
InitContainerMountPath: "/usr/share/elasticsearch/data",
EsContainerMountPath: "/usr/share/elasticsearch/data",
InitContainerMountPath: esvolume.ElasticsearchDataMountPath,
EsContainerMountPath: esvolume.ElasticsearchDataMountPath,
}

LogsSharedVolume = SharedVolume{
Name: esvolume.ElasticsearchLogsVolumeName,
InitContainerMountPath: "/usr/share/elasticsearch/logs",
EsContainerMountPath: "/usr/share/elasticsearch/logs",
InitContainerMountPath: esvolume.ElasticsearchLogsMountPath,
EsContainerMountPath: esvolume.ElasticsearchLogsMountPath,
}

// EsBinSharedVolume contains the ES bin/ directory
Expand Down Expand Up @@ -58,6 +66,40 @@ var (
LogsSharedVolume,
},
}

PluginVolumes = SharedVolumeArray{
Array: []SharedVolume{
EsConfigSharedVolume,
EsPluginsSharedVolume,
EsBinSharedVolume,
},
}

// linkedFiles describe how various secrets are mapped into the pod's filesystem.
linkedFiles = LinkedFilesArray{
Array: []LinkedFile{
{
Source: stringsutil.Concat(esvolume.XPackFileRealmVolumeMountPath, "/", user.ElasticUsersFile),
Target: stringsutil.Concat(EsConfigSharedVolume.EsContainerMountPath, "/", user.ElasticUsersFile),
},
{
Source: stringsutil.Concat(esvolume.XPackFileRealmVolumeMountPath, "/", user.ElasticRolesFile),
Target: stringsutil.Concat(EsConfigSharedVolume.EsContainerMountPath, "/", user.ElasticRolesFile),
},
{
Source: stringsutil.Concat(esvolume.XPackFileRealmVolumeMountPath, "/", user.ElasticUsersRolesFile),
Target: stringsutil.Concat(EsConfigSharedVolume.EsContainerMountPath, "/", user.ElasticUsersRolesFile),
},
{
Source: stringsutil.Concat(settings.ConfigVolumeMountPath, "/", settings.ConfigFileName),
Target: stringsutil.Concat(EsConfigSharedVolume.EsContainerMountPath, "/", settings.ConfigFileName),
},
{
Source: stringsutil.Concat(esvolume.UnicastHostsVolumeMountPath, "/", esvolume.UnicastHostsFile),
Target: stringsutil.Concat(EsConfigSharedVolume.EsContainerMountPath, "/", esvolume.UnicastHostsFile),
},
},
}
)

// NewPrepareFSInitContainer creates an init container to handle things such as:
Expand All @@ -66,30 +108,21 @@ var (
// This container does not need to be privileged.
func NewPrepareFSInitContainer(
imageName string,
linkedFiles LinkedFilesArray,
transportCertificatesVolume volume.SecretVolume,
clusterName string,
) (corev1.Container, error) {

// we mount the certificates to a location outside of the default config directory because the prepare-fs script
// will attempt to move all the files under the configuration directory to a different volume, and it should not
// be attempting to move files from this secret volume mount (any attempt to do so will be logged as errors).
certificatesVolumeMount := transportCertificatesVolume.VolumeMount()
certificatesVolumeMount.MountPath = "/mnt/elastic-internal/transport-certificates"
certificatesVolumeMount.MountPath = transportCertificatesVolumeMountPath

script, err := RenderScriptTemplate(TemplateParams{
SharedVolumes: PrepareFsSharedVolumes,
LinkedFiles: linkedFiles,
ChownToElasticsearch: []string{
DataSharedVolume.InitContainerMountPath,
LogsSharedVolume.InitContainerMountPath,
},
TransportCertificatesKeyPath: fmt.Sprintf(
"%s/%s", certificatesVolumeMount.MountPath, certificates.KeyFileName,
),
})
if err != nil {
return corev1.Container{}, err
}
scriptsVolume := volume.NewConfigMapVolumeWithMode(
name.ScriptsConfigMap(clusterName),
esvolume.ScriptsVolumeName,
esvolume.ScriptsVolumeMountPath,
0755)

privileged := false
container := corev1.Container{
Expand All @@ -99,11 +132,26 @@ func NewPrepareFSInitContainer(
SecurityContext: &corev1.SecurityContext{
Privileged: &privileged,
},
Command: []string{"bash", "-c", script},
Command: []string{"bash", "-c", path.Join(esvolume.ScriptsVolumeMountPath, PrepareFsScriptConfigKey)},
VolumeMounts: append(
PrepareFsSharedVolumes.InitContainerVolumeMounts(), certificatesVolumeMount,
PrepareFsSharedVolumes.InitContainerVolumeMounts(), certificatesVolumeMount, scriptsVolume.VolumeMount(),
),
}

return container, nil
}

func RenderPrepareFsScript() (string, error) {
return RenderScriptTemplate(TemplateParams{
PluginVolumes: PluginVolumes,
LinkedFiles: linkedFiles,
ChownToElasticsearch: []string{
DataSharedVolume.InitContainerMountPath,
LogsSharedVolume.InitContainerMountPath,
},
TransportCertificatesKeyPath: fmt.Sprintf(
"%s/%s",
transportCertificatesVolumeMountPath,
certificates.KeyFileName),
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
// TemplateParams are the parameters manipulated in the scriptTemplate
type TemplateParams struct {
// SharedVolumes are directories to persist in shared volumes
SharedVolumes SharedVolumeArray
PluginVolumes SharedVolumeArray
// LinkedFiles are files to link individually
LinkedFiles LinkedFilesArray
// ChownToElasticsearch are paths that need to be chowned to the Elasticsearch user/group.
Expand All @@ -30,11 +30,15 @@ func RenderScriptTemplate(params TemplateParams) (string, error) {
return tplBuffer.String(), nil
}

const PrepareFsScriptConfigKey = "prepare-fs.sh"

// scriptTemplate is the main script to be run
// in the prepare-fs init container before ES starts
var scriptTemplate = template.Must(template.New("").Parse(
`#!/usr/bin/env bash -eu

`#!/usr/bin/env bash

set -eu

# compute time in seconds since the given start time
function duration() {
local start=$1
Expand Down Expand Up @@ -68,10 +72,10 @@ var scriptTemplate = template.Must(template.New("").Parse(
# Files persistence #
######################

# Persist the content of bin/, config/ and plugins/
# to a volume, to be used by the ES container
# Persist the content of bin/, config/ and plugins/ to a volume,
# so installed plugins files can to be used by the ES container
mv_start=$(date +%s)
{{range .SharedVolumes.Array}}
{{range .PluginVolumes.Array}}
if [[ -z "$(ls -A {{.EsContainerMountPath}})" ]]; then
echo "Empty dir {{.EsContainerMountPath}}"
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestRenderScriptTemplate(t *testing.T) {
{
name: "Standard script rendering",
params: TemplateParams{
SharedVolumes: PrepareFsSharedVolumes,
PluginVolumes: PluginVolumes,
LinkedFiles: LinkedFilesArray{
Array: []LinkedFile{
LinkedFile{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/elastic/cloud-on-k8s/operators/pkg/apis/common/v1alpha1"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/common/certificates"
common "github.com/elastic/cloud-on-k8s/operators/pkg/controller/common/settings"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/initcontainer"
"github.com/elastic/cloud-on-k8s/operators/pkg/controller/elasticsearch/volume"
)

Expand Down Expand Up @@ -47,8 +46,8 @@ func baseConfig(clusterName string) *CanonicalConfig {
NetworkPublishHost: "${" + EnvPodIP + "}",
NetworkHost: "0.0.0.0",

PathData: initcontainer.DataSharedVolume.EsContainerMountPath,
PathLogs: initcontainer.LogsSharedVolume.EsContainerMountPath,
PathData: volume.ElasticsearchDataMountPath,
PathLogs: volume.ElasticsearchLogsMountPath,
}
return &CanonicalConfig{common.MustCanonicalConfig(cfg)}
}
Expand Down
12 changes: 9 additions & 3 deletions operators/pkg/controller/elasticsearch/version/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func NewExpectedPodSpecs(

newEnvironmentVarsFn func(p pod.NewPodSpecParams, certs, creds, securecommon volume.SecretVolume) []corev1.EnvVar,
newESConfigFn func(clusterName string, config commonv1alpha1.Config) (settings.CanonicalConfig, error),
newInitContainersFn func(imageName string, operatorImage string, setVMMaxMapCount *bool, transportCerts volume.SecretVolume) ([]corev1.Container, error),
newInitContainersFn func(imageName string, operatorImage string, setVMMaxMapCount *bool, transportCerts volume.SecretVolume, clusterName string) ([]corev1.Container, error),
operatorImage string,
) ([]pod.PodSpecContext, error) {
podSpecs := make([]pod.PodSpecContext, 0, es.Spec.NodeCount())
Expand Down Expand Up @@ -81,7 +81,7 @@ func podSpec(
operatorImage string,
newEnvironmentVarsFn func(p pod.NewPodSpecParams, certs, creds, keystore volume.SecretVolume) []corev1.EnvVar,
newESConfigFn func(clusterName string, config commonv1alpha1.Config) (settings.CanonicalConfig, error),
newInitContainersFn func(elasticsearchImage string, operatorImage string, setVMMaxMapCount *bool, transportCerts volume.SecretVolume) ([]corev1.Container, error),
newInitContainersFn func(elasticsearchImage string, operatorImage string, setVMMaxMapCount *bool, transportCerts volume.SecretVolume, clusterName string) ([]corev1.Container, error),
) (corev1.PodSpec, settings.CanonicalConfig, error) {
// setup volumes
probeSecret := volume.NewSelectiveSecretVolumeWithMountPath(
Expand Down Expand Up @@ -121,7 +121,13 @@ func podSpec(
WithEnv(newEnvironmentVarsFn(p, httpCertificatesVolume, keystoreUserSecret, secureSettingsVolume)...)

// setup init containers
initContainers, err := newInitContainersFn(builder.Container.Image, operatorImage, p.SetVMMaxMapCount, transportCertificatesVolume)
initContainers, err := newInitContainersFn(
builder.Container.Image,
operatorImage,
p.SetVMMaxMapCount,
transportCertificatesVolume,
p.ClusterName)

if err != nil {
return corev1.PodSpec{}, settings.CanonicalConfig{}, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ func Test_podSpec(t *testing.T) {
newESConfigFn := func(clusterName string, config commonv1alpha1.Config) (settings.CanonicalConfig, error) {
return settings.CanonicalConfig{}, nil
}
newInitContainersFn := func(elasticsearchImage string, operatorImage string, setVMMaxMapCount *bool, nodeCertificatesVolume volume.SecretVolume) ([]corev1.Container, error) {
newInitContainersFn := func(elasticsearchImage string, operatorImage string, setVMMaxMapCount *bool, nodeCertificatesVolume volume.SecretVolume, clusterName string) ([]corev1.Container, error) {
return []corev1.Container{
{
Name: "init-container1",
Expand Down
Loading