Pushing changes for testing harness before my next meeting. Adding working exec library and sample code

Signed-off-by: Kris Nóva <kris@nivenly.com>
main
Kris Nóva 2021-02-03 11:00:11 -08:00
parent 95794522e0
commit b107d98a37
14 changed files with 313 additions and 19 deletions

View File

@ -0,0 +1,20 @@
package main
import (
sampleapp "github.com/kris-nova/client-go/sample-app"
"github.com/kris-nova/logger"
)
func main() {
logger.Level = 4
app := sampleapp.New()
var err error
err = app.Start()
if err != nil {
logger.Critical(err.Error())
}
err = app.Stop()
if err != nil {
logger.Critical(err.Error())
}
}

30
examples/common.go 100644
View File

@ -0,0 +1,30 @@
package main
import (
"fmt"
"os"
photoprism "github.com/kris-nova/client-go"
"github.com/kris-nova/logger"
)
// format string, a ...interface{}
func halt(code int, msg string, a ...interface{}) {
str := fmt.Sprintf(msg, a...)
logger.Critical(str)
os.Exit(code)
}
func auth() photoprism.ClientAuthenticator {
user := os.Getenv("PHOTOPRISM_USER")
if user == "" {
halt(1, "Missing PHOTOPRISM_USER")
}
pass := os.Getenv("PHOTOPRISM_PASS")
if pass == "" {
halt(2, "Missing PHOTOPRISM_PASS")
}
auth := photoprism.NewClientAuthLogin(user, pass)
return auth
}

View File

@ -5,29 +5,15 @@ import (
"os"
photoprism "github.com/kris-nova/client-go"
"github.com/kris-nova/logger"
)
// format string, a ...interface{}
func halt(code int, msg string, a ...interface{}) {
str := fmt.Sprintf(msg, a...)
logger.Critical(str)
os.Exit(code)
}
func main() {
user := os.Getenv("PHOTOPRISM_USER")
if user == "" {
halt(1, "Missing PHOTOPRISM_USER")
uuid := os.Getenv("PHOTOPRISM_ID")
if uuid == "" {
halt(2, "Missing PHOTOPRISM_UUID")
}
pass := os.Getenv("PHOTOPRISM_PASS")
if pass == "" {
halt(2, "Missing PHOTOPRISM_PASS")
}
login := photoprism.NewClientAuthLogin("username", "password")
photoclient := photoprism.New(login)
photo, err := photoclient.V1().GetPhoto("123")
client := photoprism.New(auth())
photo, err := client.V1().GetPhoto(uuid)
if err != nil {
halt(3, "Error fetching photo: %v", err)
}

41
sample-app/app.go 100644
View File

@ -0,0 +1,41 @@
package sampleapp
import (
"github.com/kris-nova/logger"
photoprism "github.com/kris-nova/client-go"
)
type SampleApplication struct {
}
func New() *SampleApplication {
app := &SampleApplication{}
return app
}
// These are the bash scripts that can be used
// to start/stop the Photoprism test application
var (
CreateCommand = `./pcreate`
DestroyCommand = `./pdestroy`
LogsCommand = `./plogs`
StartCommand = `./pstart`
StopCommand = `./pstop`
)
func (a *SampleApplication) Start() error {
logger.Info("Starting Application...")
script := NewScript(StartCommand)
return script.Interpret()
}
func (a *SampleApplication) Stop() error {
logger.Info("Stopping Application...")
script := NewScript(StopCommand)
return script.Interpret()
}
func (a *SampleApplication) GetAuth() photoprism.ClientAuthenticator {
return nil
}

135
sample-app/exec.go 100644
View File

@ -0,0 +1,135 @@
package sampleapp
import (
"bytes"
"fmt"
"os/exec"
"strings"
"github.com/kris-nova/logger"
)
type Script struct {
commands []string
}
func NewScript(str string) *Script {
script := &Script{}
spl := strings.Split(str, "\n")
//logger.Info("Script lines: %d", len(spl))
for _, line := range spl {
script.commands = append(script.commands, line)
}
return script
}
func (s *Script) Interpret() error {
//logger.Info("Running script...")
chResult := make(chan *ExecResult)
chError := make(chan error)
chBreak := make(chan bool)
defer close(chResult)
defer close(chError)
defer close(chBreak)
for i, cmdStr := range s.commands {
// Exec will hang for output
// Ignore newlines
// Ignore comments starting with #
// Ignore comments starting with //
if cmdStr == "\n" || strings.HasPrefix(cmdStr, "#") || strings.HasPrefix(cmdStr, "//") {
continue
}
//logger.Info("Executing: [%s]", cmdStr)
result, err := Exec(cmdStr)
if err != nil {
return fmt.Errorf("error executing running command [%s] on line [%d]\n%v\n", cmdStr, i+1, err)
} else if result.exitCode != 0 {
return fmt.Errorf("non zero exit code running command [%s] on line [%d]\n%s\n%s\n", cmdStr, i+1, result.Stdout(), result.stderr)
}
// Here is where we log STDOUT from a "script"
// Right now it is set to DEBUG which can be enabled by
// setting logger.Level = 4
logger.Debug(result.Stdout())
}
return nil
}
type ExecResult struct {
stderr string
stdout string
exitCode int
execErr exec.ExitError
}
func (e *ExecResult) Stdout() string {
return e.stdout
}
func (e *ExecResult) Stderr() string {
return e.stderr
}
func (e *ExecResult) ExitCode() int {
if e == nil {
return 0
}
return e.exitCode
}
func (e *ExecResult) ExecError() exec.ExitError {
return e.execErr
}
// Exec will take an arbitrary executable string
// and hang until the command exits
func Exec(str string) (*ExecResult, error) {
//logger.Info("Exec [%s]", str)
var cmdstr string
var args []string
var l int
spl := strings.Split(str, " ")
l = len(spl)
if l == 1 {
// <cmd>
cmdstr = spl[0]
} else if l > 1 {
// <cmd> <arg>...
cmdstr = spl[0]
for i := 1; i < l; i++ {
args = append(args, spl[i])
}
} else if l < 1 {
return nil, fmt.Errorf("invalid Exec() string %s", str)
}
fqpcmd, err := exec.LookPath(cmdstr)
if err != nil {
return nil, fmt.Errorf("unable to find fully qualified path for executable %s: %v", cmdstr, err)
}
//logger.Info("Command: %s", fqpcmd)
//logger.Info("Args: %v", args)
stdoutBuffer := bytes.Buffer{}
stderrBuffer := bytes.Buffer{}
e := []string{fqpcmd, fmt.Sprint(args)}
cmd := exec.Command(e[0], e[1:]...)
cmd.Stdout = &stdoutBuffer
cmd.Stderr = &stderrBuffer
result := &ExecResult{}
err = cmd.Run()
if err != nil {
if eerr, ok := err.(*exec.ExitError); ok {
result.stderr = stderrBuffer.String()
result.stdout = stdoutBuffer.String()
result.exitCode = eerr.ExitCode()
result.execErr = *eerr
return result, nil
}
return nil, fmt.Errorf("major error running command [%s]: %v", str, err)
}
result.stderr = stderrBuffer.String()
result.stdout = stdoutBuffer.String()
result.exitCode = 0
return result, nil
}

21
sample-app/pcreate 100755
View File

@ -0,0 +1,21 @@
#!/bin/bash
####################################
#####
###
##
#
#
# Startup Script for the Application
####################################
set -e
echo "Starting [SampleApp]"
docker run -d \
--name photoprism \
-p 8080:2342 \
-e PHOTOPRISM_UPLOAD_NSFW="true" \
-e PHOTOPRISM_ADMIN_PASSWORD="missy" \
-v photoprism:/photoprism \
photoprism/photoprism:latest

View File

@ -0,0 +1,16 @@
#!/bin/bash
####################################
#####
###
##
#
#
# Startup Script for the Application
####################################
set -e
echo "Stopping [SampleApp]"
docker stop photoprism
docker rm photoprism

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

15
sample-app/plogs 100755
View File

@ -0,0 +1,15 @@
#!/bin/bash
####################################
#####
###
##
#
#
# Startup Script for the Application
####################################
set -e
echo "Starting [SampleApp]"
docker logs -f --tail 100 photoprism

14
sample-app/pstart 100755
View File

@ -0,0 +1,14 @@
#!/bin/bash
####################################
#####
###
##
#
#
# Startup Script for the Application
####################################
set -e
echo "Stopping [SampleApp]"
docker start photoprism

16
sample-app/pstop 100755
View File

@ -0,0 +1,16 @@
#!/bin/bash
####################################
#####
###
##
#
#
# Startup Script for the Application
####################################
set -e
echo "Stopping [SampleApp]"
docker stop photoprism
#docker rm photoprism