UNCLASSIFIED

Commit 211ac6fe authored by jonathan.janos@mongodb.com's avatar jonathan.janos@mongodb.com
Browse files

Initial commit for the MongoDB Enterprise Ops Manager Init container

parent 1b5c9947
Pipeline #25581 failed with stage
# Dockerfile for Ops Manager init container.
ARG BASE_REGISTRY=nexus-docker-secure.levelup-nexus.svc.cluster.local:18082
ARG BASE_IMAGE=redhat/ubi/ubi7
ARG BASE_TAG=7.8
FROM golang:1.13 as builder
USER root
RUN mkdir /build
ADD . /build/
WORKDIR /build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -a -i -o ./output/mmsconfiguration ./mmsconfiguration
#####
FROM ${BASE_REGISTRY}/${BASE_IMAGE}:${BASE_TAG}
ARG VERSION
LABEL name="MongoDB Enterprise Ops Manager Init" \
maintainer="support@mongodb.com" \
vendor="MongoDB" \
version="mongodb-enterprise-init-ops-manager-${VERSION}" \
release="1" \
summary="MongoDB Enterprise Ops Manager Init Image" \
description="Startup Scripts for MongoDB Enterprise Ops Manager"
RUN mkdir /scripts
COPY --from=builder /build/output/mmsconfiguration /scripts/
COPY scripts/docker-entry-point.sh /scripts/
RUN mkdir -p /licenses
COPY LICENSE /licenses/mongodb-enterprise-ops-manager
USER 2000
ENTRYPOINT [ "/bin/cp", "-f", "/scripts/docker-entry-point.sh", "/scripts/mmsconfiguration", "/opt/scripts/" ]
HEALTHCHECK --timeout=30s CMD ls /scripts/docker-entry-point.sh || exit 1
@Library('DCCSCR@master') _
dccscrPipeline(version: "1.5.3")
Usage of the MongoDB Enterprise Operator for Kubernetes indicates
agreement with the MongoDB Development, Test, and Evaluation Agreement
* https://www.mongodb.com/legal/evaluation-agreement
# MongoDB Ops Manager Init
# MongoDB Enterprise Ops Manager - Init Container #
Init container for MongoDB Enterprise Ops Manager. This container image is used exclusively by the MongoDB Enterprise Kubernetes Operator to deploy MongoDB Ops Manager to Kubernetes or OpenShift clusters.
For more information about MongoDB Ops Manager, please visit <https://www.mongodb.com/products/ops-manager>.
Information about MongoDB can be found at <https://www.mongodb.com>.
## Documentation ##
Documentation for MongoDB Ops Manager is available at <https://docs.opsmanager.mongodb.com/current/>.
Documentation for the MongoDB Enterprise Kubernetes Operator is available at <https://docs.mongodb.com/kubernetes-operator>.
package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
)
const (
mmsJvmParamsVar = "JAVA_MMS_UI_OPTS"
backupDaemonJvmParamsVar = "JAVA_DAEMON_OPTS"
omPropertyPrefix = "OM_PROP_"
lineBreak = "\n"
commentPrefix = "#"
propOverwriteFmt = "%s=\"${%s} %s\""
backupDaemon = "BACKUP_DAEMON"
)
func updateConfFile(confFile string) error {
confFilePropertyName := mmsJvmParamsVar
if _, isBackupDaemon := os.LookupEnv(backupDaemon); isBackupDaemon {
confFilePropertyName = backupDaemonJvmParamsVar
}
customJvmParamsVar := "CUSTOM_" + confFilePropertyName
jvmParams, jvmParamsEnvVarExists := os.LookupEnv(customJvmParamsVar)
if !jvmParamsEnvVarExists || jvmParams == "" {
fmt.Printf("%s not specified, not modifying %s\n", customJvmParamsVar, confFile)
return nil
}
newMmsJvmParams := fmt.Sprintf(propOverwriteFmt, confFilePropertyName, confFilePropertyName, jvmParams)
fmt.Printf("Appending %s to %s\n", newMmsJvmParams, confFile)
err := appendLinesToFile(confFile, getJvmParamDocString()+newMmsJvmParams+lineBreak)
return err
}
func updatePropertiesFile(propertiesFile string) error {
newProperties := getOmPropertiesFromEnvVars()
// If there are no exported mms properties, we can stop here
if len(newProperties) == 0 {
return nil
}
lines, err := readLinesFromFile(propertiesFile)
if err != nil {
return err
}
lines = updateMmsProperties(lines, newProperties)
fmt.Printf("Updating configuration properties file %s\n", propertiesFile)
err = writeLinesToFile(propertiesFile, lines)
return err
}
func readLinesFromFile(name string) ([]string, error) {
input, err := ioutil.ReadFile(name)
if err != nil {
return nil, fmt.Errorf("error reading file %s: %v", name, err)
}
return strings.Split(string(input), lineBreak), nil
}
func writeLinesToFile(name string, lines []string) error {
output := strings.Join(lines, lineBreak)
err := ioutil.WriteFile(name, []byte(output), 0775)
if err != nil {
return fmt.Errorf("error writing to file %s: %v", name, err)
}
return nil
}
func appendLinesToFile(name string, lines string) error {
f, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("error opening file %s: %v", name, err)
}
if _, err = f.WriteString(lines); err != nil {
return fmt.Errorf("error writing to file %s: %v", name, err)
}
err = f.Close()
return err
}
func getOmPropertiesFromEnvVars() map[string]string {
props := map[string]string{}
for _, pair := range os.Environ() {
if !strings.HasPrefix(pair, omPropertyPrefix) {
continue
}
p := strings.SplitN(pair, "=", 2)
key := strings.Replace(p[0], omPropertyPrefix, "", 1)
key = strings.ReplaceAll(key, "_", ".")
props[key] = p[1]
}
return props
}
func updateMmsProperties(lines []string, newProperties map[string]string) []string {
seenProperties := map[string]bool{}
// Overwrite existing properties
for i, line := range lines {
if strings.HasPrefix(line, commentPrefix) || !strings.Contains(line, "=") {
continue
}
key := strings.Split(line, "=")[0]
if newVal, ok := newProperties[key]; ok {
lines[i] = fmt.Sprintf("%s=%s", key, newVal)
fmt.Printf("Setting %s=%s\n", key, newVal)
seenProperties[key] = true
}
}
// Add new properties
for key, val := range newProperties {
if _, ok := seenProperties[key]; !ok {
lines = append(lines, fmt.Sprintf("%s=%s", key, val))
fmt.Printf("Added %s=%s\n", key, val)
}
}
return lines
}
func getJvmParamDocString() string {
commentMarker := strings.Repeat("#", 55)
return fmt.Sprintf("%s\n## This is the custom JVM configuration set by the Operator\n%s\n\n", commentMarker, commentMarker)
}
func main() {
if len(os.Args) < 3 {
fmt.Printf("Incorrect arguments %s, must specify path to conf file and path to properties file"+lineBreak, os.Args[1:])
os.Exit(1)
}
confFile := os.Args[1]
propertiesFile := os.Args[2]
if err := updateConfFile(confFile); err != nil {
fmt.Println(err)
os.Exit(1)
}
if err := updatePropertiesFile(propertiesFile); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
package main
import (
"fmt"
"io/ioutil"
"math/rand"
"os"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestEditMmsConfiguration_UpdateConfFile_Mms(t *testing.T) {
confFile := _createTestConfFile()
_ = os.Setenv("CUSTOM_JAVA_MMS_UI_OPTS", "-Xmx4000m -Xms4000m")
err := updateConfFile(confFile)
assert.NoError(t, err)
updatedContent := _readLinesFromFile(confFile)
assert.Equal(t, updatedContent[7], "JAVA_MMS_UI_OPTS=\"${JAVA_MMS_UI_OPTS} -Xmx4000m -Xms4000m\"")
}
func TestEditMmsConfiguration_UpdateConfFile_BackupDaemon(t *testing.T) {
confFile := _createTestConfFile()
_ = os.Setenv("BACKUP_DAEMON", "something")
_ = os.Setenv("CUSTOM_JAVA_DAEMON_OPTS", "-Xmx4000m -Xms4000m")
err := updateConfFile(confFile)
assert.NoError(t, err)
updatedContent := _readLinesFromFile(confFile)
assert.Equal(t, updatedContent[7], "JAVA_DAEMON_OPTS=\"${JAVA_DAEMON_OPTS} -Xmx4000m -Xms4000m\"")
}
func TestEditMmsConfiguration_UpdatePropertiesFile(t *testing.T) {
val := fmt.Sprintf("test%d", rand.Intn(1000))
key := "OM_PROP_test_edit_mms_configuration_get_om_props"
_ = os.Setenv(key, val)
props := getOmPropertiesFromEnvVars()
assert.Equal(t, props["test.edit.mms.configuration.get.om.props"], val)
_ = os.Unsetenv(key)
}
func TestEditMmsConfiguration_GetOmPropertiesFromEnvVars(t *testing.T) {
_ = os.Setenv("OM_PROP_mms_test_prop", "somethingNew")
_ = os.Setenv("OM_PROP_mms_test_prop_new", "400")
propFile := _createTestPropertiesFile()
err := updatePropertiesFile(propFile)
assert.NoError(t, err)
updatedContent := _readLinesFromFile(propFile)
assert.Equal(t, updatedContent[0], "mms.prop=1234")
assert.Equal(t, updatedContent[1], "mms.test.prop5=")
assert.Equal(t, updatedContent[2], "mms.test.prop=somethingNew")
assert.Equal(t, updatedContent[3], "mms.test.prop.new=400")
}
func _createTestConfFile() string {
contents := "JAVA_MMS_UI_OPTS=\"${JAVA_MMS_UI_OPTS} -Xmx4352m -Xss328k -Xms4352m -XX:NewSize=600m -Xmn1500m -XX:ReservedCodeCacheSize=128m -XX:-OmitStackTraceInFastThrow\"\n"
contents += "JAVA_DAEMON_OPTS= \"${JAVA_DAEMON_OPTS} -DMONGO.BIN.PREFIX=\"\n\n"
return _writeTempFileWithContent(contents, "conf")
}
func _createTestPropertiesFile() string {
contents := "mms.prop=1234\nmms.test.prop5=\nmms.test.prop=something"
return _writeTempFileWithContent(contents, "prop")
}
func _readLinesFromFile(name string) []string {
content, _ := ioutil.ReadFile(name)
return strings.Split(string(content), "\n")
}
func _writeTempFileWithContent(content string, prefix string) string {
tmpfile, _ := ioutil.TempFile("", prefix)
_, _ = tmpfile.WriteString(content)
_ = tmpfile.Close()
return tmpfile.Name()
}
#!/usr/bin/env bash
set -euo pipefail
# the function reacting on SIGTERM command sent by the container on its shutdown. Redirects the signal
# to the child process ("tail" in this case)
cleanup () {
echo "Caught SIGTERM signal."
kill -TERM "$child"
}
# we need to change the Home directory for current bash so that the gen key was found correctly
# (the key is searched in "${HOME}/.mongodb-mms/gen.key")
HOME=${MMS_HOME}
# Execute script that updates properties and conf file used to start ops manager
echo "Updating configuration properties file ${MMS_PROP_FILE} and conf file ${MMS_CONF_FILE}"
/opt/scripts/mmsconfiguration ${MMS_CONF_FILE} ${MMS_PROP_FILE}
if [[ -z ${BACKUP_DAEMON+x} ]]; then
echo "Starting Ops Manager"
${MMS_HOME}/bin/mongodb-mms start_mms || {
echo "Startup of Ops Manager failed with code $?"
if [[ -f ${MMS_LOG_DIR}/mms0-startup.log ]]; then
echo
echo "mms0-startup.log:"
echo
cat "${MMS_LOG_DIR}/mms0-startup.log"
fi
if [[ -f ${MMS_LOG_DIR}/mms0.log ]]; then
echo
echo "mms0.log:"
echo
cat "${MMS_LOG_DIR}/mms0.log"
fi
if [[ -f ${MMS_LOG_DIR}/mms-migration.log ]]; then
echo
echo "mms-migration.log"
echo
cat "${MMS_LOG_DIR}/mms-migration.log"
fi
exit 1
}
trap cleanup SIGTERM
tail -F -n 1000 "${MMS_LOG_DIR}/mms0.log" "${MMS_LOG_DIR}/mms0-startup.log" "${MMS_LOG_DIR}/mms-migration.log" &
else
echo "Starting Ops Manager Backup Daemon"
${MMS_HOME}/bin/mongodb-mms start_backup_daemon
trap cleanup SIGTERM
tail -F "${MMS_LOG_DIR}/daemon.log" &
fi
child=$!
wait "$child"
  • Pipeline Status: FAILURE
    FAILURE Stage: Build
    Branch: mdb-initial-153

    graph LR
      0([setup]):::INTERNAL_SUCCESS --> 1([Import Artifacts]):::NOT_BUILT --> 2((/)):::INTERNAL_SUCCESS --> 3([Stage Artifacts]):::NOT_BUILT --> 4((/)):::INTERNAL_SUCCESS --> 5([Build]):::FAILURE --> 6([Publish, Scan & Report]):::INTERNAL_FAILURE
    
    classDef SUCCESS font-size:10px
    classDef FAILURE fill:#f44, font-size:10px
    classDef SKIPPED font-size:10px
    classDef ABORTED fill:#889, font-size:10px
    classDef INTERNAL_SUCCESS font-size:10px, stroke-dasharray: 2, 1
    classDef INTERNAL_FAILURE fill:#f44, font-size:10px, stroke-dasharray: 2, 1
    classDef INTERNAL_SKIPPED font-size:10px, stroke-dasharray: 2, 1
    classDef INTERNAL_ABORTED fill:#889, font-size:10px, stroke-dasharray: 2, 1
    

    Error Log:

    
    ---
    + buildah bud --tls-verify=false --format=docker --loglevel=3 --storage-driver=vfs --build-arg BASE_REGISTRY=**** --build-arg BASE_IMAGE=redhat/ubi/ubi8 --build-arg BASE_TAG=8.1 -t ****/mongodb/mongodb-enterprise/mongodb-ops-manager-init:1.5.3-testing --label dccscr.git.commit.id=211ac6fe23d33fe4bd38fb27a85add83d7a2738d --label dccscr.git.commit.url=https://dccscr.dsop.io/dsop/mongodb/mongodb-enterprise/mongodb-ops-manager-init/tree/211ac6fe23d33fe4bd38fb27a85add83d7a2738d --label dccscr.git.url=https://repo1.dsop.io/dsop/mongodb/mongodb-enterprise/mongodb-ops-manager-init.git --label dccscr.git.branch=mdb-initial-153 --label dccscr.image.version=1.5.3 --label 'dccscr.image.build.date=Mon Jun 29 17:34:18 UTC 2020
    ' --label dccscr.image.build.id=1 --label dccscr.image.name=mongodb-ops-manager-init --label dccscr.ironbank.approval.status=pendingapproval --label dccscr.ironbank.approval.url=TBD --label dccscr.ironbank.url=TBD --label dcar_status=pendingapproval .
    STEP 1: FROM golang:1.13 AS builder
    error creating build container: The following failures happened while trying to pull image specified by "golang:1.13" based on search registries in /etc/containers/registries.conf:
    * "localhost/golang:1.13": Error initializing source docker://localhost/golang:1.13: error pinging docker registry localhost: Get http://localhost/v2/: dial tcp [::1]:80: connect: connection refused
    * "registry.access.redhat.com/golang:1.13": Error initializing source docker://registry.access.redhat.com/golang:1.13: error pinging docker registry registry.access.redhat.com: Get http://registry.access.redhat.com/v2/: dial tcp 23.36.241.155:80: i/o timeout
    * "registry.fedoraproject.org/golang:1.13": Error initializing source docker://registry.fedoraproject.org/golang:1.13: error pinging docker registry registry.fedoraproject.org: Get http://registry.fedoraproject.org/v2/: dial tcp 38.145.60.21:80: i/o timeout
    * "registry.centos.org/golang:1.13": Error initializing source docker://registry.centos.org/golang:1.13: error pinging docker registry registry.centos.org: Get http://registry.centos.org/v2/: dial tcp 8.43.84.200:80: i/o timeout
    * "docker.io/library/golang:1.13": Error initializing source docker://golang:1.13: error pinging docker registry registry-1.docker.io: Get http://registry-1.docker.io/v2/: dial tcp 34.195.246.183:80: i/o timeout
    script returned exit code 1
  • Pipeline Status: FAILURE
    FAILURE Stage: Build
    Branch: mdb-initial-153

    graph LR
      0([setup]):::INTERNAL_SUCCESS --> 1([Import Artifacts]):::NOT_BUILT --> 2((/)):::INTERNAL_SUCCESS --> 3([Stage Artifacts]):::NOT_BUILT --> 4((/)):::INTERNAL_SUCCESS --> 5([Build]):::FAILURE --> 6([Publish, Scan & Report]):::INTERNAL_FAILURE
    
    classDef SUCCESS font-size:10px
    classDef FAILURE fill:#f44, font-size:10px
    classDef SKIPPED font-size:10px
    classDef ABORTED fill:#889, font-size:10px
    classDef INTERNAL_SUCCESS font-size:10px, stroke-dasharray: 2, 1
    classDef INTERNAL_FAILURE fill:#f44, font-size:10px, stroke-dasharray: 2, 1
    classDef INTERNAL_SKIPPED font-size:10px, stroke-dasharray: 2, 1
    classDef INTERNAL_ABORTED fill:#889, font-size:10px, stroke-dasharray: 2, 1
    

    Error Log:

    
    ---
    + buildah bud --tls-verify=false --format=docker --loglevel=3 --storage-driver=vfs --build-arg BASE_REGISTRY=**** --build-arg BASE_IMAGE=redhat/ubi/ubi8 --build-arg BASE_TAG=8.1 -t ****/mongodb/mongodb-enterprise/mongodb-ops-manager-init:1.5.3-testing --label dccscr.git.commit.id=211ac6fe23d33fe4bd38fb27a85add83d7a2738d --label dccscr.git.commit.url=https://dccscr.dsop.io/dsop/mongodb/mongodb-enterprise/mongodb-ops-manager-init/tree/211ac6fe23d33fe4bd38fb27a85add83d7a2738d --label dccscr.git.url=https://repo1.dsop.io/dsop/mongodb/mongodb-enterprise/mongodb-ops-manager-init.git --label dccscr.git.branch=mdb-initial-153 --label dccscr.image.version=1.5.3 --label 'dccscr.image.build.date=Mon Jun 29 18:58:08 UTC 2020
    ' --label dccscr.image.build.id=2 --label dccscr.image.name=mongodb-ops-manager-init --label dccscr.ironbank.approval.status=pendingapproval --label dccscr.ironbank.approval.url=TBD --label dccscr.ironbank.url=TBD --label dcar_status=pendingapproval .
    STEP 1: FROM golang:1.13 AS builder
    error creating build container: The following failures happened while trying to pull image specified by "golang:1.13" based on search registries in /etc/containers/registries.conf:
    * "localhost/golang:1.13": Error initializing source docker://localhost/golang:1.13: error pinging docker registry localhost: Get http://localhost/v2/: dial tcp [::1]:80: connect: connection refused
    * "registry.access.redhat.com/golang:1.13": Error initializing source docker://registry.access.redhat.com/golang:1.13: error pinging docker registry registry.access.redhat.com: Get http://registry.access.redhat.com/v2/: dial tcp 23.36.241.161:80: i/o timeout
    * "registry.fedoraproject.org/golang:1.13": Error initializing source docker://registry.fedoraproject.org/golang:1.13: error pinging docker registry registry.fedoraproject.org: Get http://registry.fedoraproject.org/v2/: dial tcp 38.145.60.20:80: i/o timeout
    * "registry.centos.org/golang:1.13": Error initializing source docker://registry.centos.org/golang:1.13: error pinging docker registry registry.centos.org: Get http://registry.centos.org/v2/: dial tcp 8.43.84.200:80: i/o timeout
    * "docker.io/library/golang:1.13": Error initializing source docker://golang:1.13: error pinging docker registry registry-1.docker.io: Get http://registry-1.docker.io/v2/: dial tcp 54.236.131.166:80: i/o timeout
    script returned exit code 1
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment