Add web server to dev image

This commit is contained in:
Arthur Barr
2018-03-12 11:14:59 +00:00
parent 104098c7b4
commit 10e448056b
19 changed files with 621 additions and 20 deletions

133
cmd/runmqdevserver/main.go Normal file
View File

@@ -0,0 +1,133 @@
/*
© Copyright IBM Corporation 2018
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.
*/
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"syscall"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/logger"
)
var log *logger.Logger
func setPassword(user string, password string) error {
cmd := exec.Command("chpasswd")
stdin, err := cmd.StdinPipe()
if err != nil {
return err
}
fmt.Fprintf(stdin, "%s:%s", user, password)
stdin.Close()
_, _, err = command.RunCmd(cmd)
if err != nil {
return err
}
log.Printf("Set password for \"%v\" user", user)
return nil
}
func getLogFormat() string {
return os.Getenv("LOG_FORMAT")
}
func getDebug() bool {
debug := os.Getenv("DEBUG")
if debug == "true" || debug == "1" {
return true
}
return false
}
func configureLogger() error {
f := getLogFormat()
d := getDebug()
switch f {
case "json":
log = logger.NewLogger(os.Stderr, d, true)
case "basic":
log = logger.NewLogger(os.Stderr, d, false)
default:
log = logger.NewLogger(os.Stdout, d, false)
return fmt.Errorf("invalid value for LOG_FORMAT: %v", f)
}
return nil
}
func logTerminationf(format string, args ...interface{}) {
logTermination(fmt.Sprintf(format, args))
}
// TODO: Duplicated code
func logTermination(args ...interface{}) {
msg := fmt.Sprint(args)
// Write the message to the termination log. This is the default place
// that Kubernetes will look for termination information.
log.Debugf("Writing termination message: %v", msg)
err := ioutil.WriteFile("/dev/termination-log", []byte(msg), 0660)
if err != nil {
log.Debug(err)
}
log.Error(msg)
}
func doMain() error {
err := configureLogger()
if err != nil {
logTermination(err)
return err
}
adminPassword, set := os.LookupEnv("MQ_ADMIN_PASSWORD")
if set {
err = setPassword("admin", adminPassword)
if err != nil {
logTerminationf("Error setting admin password: %v", err)
return err
}
}
appPassword, set := os.LookupEnv("MQ_APP_PASSWORD")
if set {
err = setPassword("app", appPassword)
if err != nil {
logTerminationf("Error setting app password: %v", err)
return err
}
}
err = updateMQSC(set)
if err != nil {
logTerminationf("Error updating MQSC: %v", err)
return err
}
return nil
}
var osExit = os.Exit
func main() {
err := doMain()
if err != nil {
osExit(1)
} else {
// Replace this process with runmqserver
syscall.Exec("/usr/local/bin/runmqserver", []string{"runmqserver"}, os.Environ())
}
}

View File

@@ -0,0 +1,57 @@
/*
© Copyright IBM Corporation 2018
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.
*/
package main
import (
"html/template"
"os"
)
func updateMQSC(appPasswordRequired bool) error {
var checkClient string
if appPasswordRequired {
checkClient = "REQUIRED"
} else {
checkClient = "ASQMGR"
}
const mqsc string = "/etc/mqm/dev.mqsc"
if os.Getenv("MQ_DEV") == "true" {
const mqscTemplate string = mqsc + ".tpl"
// Re-configure channel if app password not set
t, err := template.ParseFiles(mqscTemplate)
if err != nil {
log.Error(err)
return err
}
f, err := os.OpenFile(mqsc, os.O_CREATE|os.O_WRONLY, 0660)
defer f.Close()
err = t.Execute(f, map[string]string{"ChckClnt": checkClient})
if err != nil {
log.Error(err)
return err
}
// TODO: Lookup value for MQM user here?
err = os.Chown(mqsc, 999, 999)
if err != nil {
log.Error(err)
return err
}
// os.Remove(mqscTemplate)
} else {
os.Remove(mqsc)
}
return nil
}

View File

@@ -68,6 +68,12 @@ func doMain() error {
if err != nil {
return err
}
err = postInit(name)
if err != nil {
return err
}
newQM, err := createQueueManager(name)
if err != nil {
logTermination(err)

View File

@@ -61,7 +61,9 @@ func mirrorAvailableMessages(f *os.File, mf mirrorFunc) {
mf(t)
count++
}
log.Debugf("Mirrored %v log entries from %v", count, f.Name())
if count > 0 {
log.Debugf("Mirrored %v log entries from %v", count, f.Name())
}
err := scanner.Err()
if err != nil {
log.Errorf("Error reading file %v: %v", f.Name(), err)

View File

@@ -0,0 +1,36 @@
// +build mqdev
/*
© Copyright IBM Corporation 2018
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.
*/
package main
import "os"
// postInit is run after /var/mqm is set up
// This version of postInit is only included as part of the MQ Advanced for Developers build
func postInit(name string) error {
disable := os.Getenv("MQ_DISABLE_WEB_CONSOLE")
if disable != "true" && disable != "1" {
// Configure and start the web server, in the background (if installed)
// WARNING: No error handling or health checking available for the web server,
// which is why it's limited to use with MQ Advanced for Developers only
go func() {
configureWebServer()
startWebServer()
}()
}
return nil
}

View File

@@ -0,0 +1,22 @@
// +build !mqdev
/*
© Copyright IBM Corporation 2018
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.
*/
package main
func postInit(name string) error {
return nil
}

View File

@@ -0,0 +1,110 @@
// +build mqdev
/*
© Copyright IBM Corporation 2018
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.
*/
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/ibm-messaging/mq-container/internal/command"
)
func startWebServer() error {
_, err := os.Stat("/opt/mqm/bin/strmqweb")
if err != nil && os.IsNotExist(err) {
log.Debug("Skipping web server, because it's not installed")
return nil
}
log.Println("Starting web server")
out, rc, err := command.RunAsMQM("strmqweb")
if err != nil {
log.Printf("Error %v starting web server: %v", rc, string(out))
return err
}
log.Println("Started web server")
return nil
}
func configureWebServer() error {
_, err := os.Stat("/opt/mqm/bin/strmqweb")
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
const webConfigDir string = "/etc/mqm/web"
_, err = os.Stat(webConfigDir)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
uid, gid, err := lookupMQM()
if err != nil {
return err
}
const prefix string = "/etc/mqm/web"
err = filepath.Walk(prefix, func(from string, info os.FileInfo, err error) error {
if err != nil {
return err
}
to := fmt.Sprintf("/var/mqm/web%v", from[len(prefix):])
exists := true
_, err = os.Stat(to)
if err != nil {
if os.IsNotExist(err) {
exists = false
} else {
return err
}
}
if info.IsDir() {
if !exists {
err := os.MkdirAll(to, 0770)
if err != nil {
return err
}
}
log.Printf("Directory: %v --> %v", from, to)
} else {
if exists {
err := os.Remove(to)
if err != nil {
return err
}
}
// TODO: Permissions. Can't rely on them being set in Dockerfile
err := os.Link(from, to)
if err != nil {
log.Debug(err)
return err
}
log.Printf("File: %v", from)
}
err = os.Chown(to, uid, gid)
if err != nil {
return err
}
return nil
})
return err
}