Skip to content

Commit

Permalink
(#202) Support macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
dshearer committed Nov 12, 2018
1 parent b46c764 commit 91e088e
Show file tree
Hide file tree
Showing 22 changed files with 352 additions and 122 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ results
.vm-is-created
.vm-is-running
.DS_Store
su_cmd_osx.go
*.pyc
*.pyo
3 changes: 2 additions & 1 deletion common/sources.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ COMMON_SOURCES := \
common/logging.go \
common/path.go \
common/sources.mk \
common/su_cmd_linux.go \
common/su_cmd_darwin.go \
common/su_cmd_freebsd.go \
common/su_cmd_linux.go \
common/user.go \
common/version.go

Expand Down
15 changes: 15 additions & 0 deletions common/su_cmd_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package common

import (
"os/exec"
)

func su_cmd(user string, cmdStr string, shell string) *exec.Cmd {
var cmd *exec.Cmd = exec.Command(
"su",
"-l", // login shell
user,
"-c", cmdStr,
)
return cmd
}
79 changes: 79 additions & 0 deletions jobbermaster/get_users.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package main

import (
"os/user"
"path/filepath"

"github.com/dshearer/jobber/common"
)

func userHasHome(usr *user.User) bool {
// check if user has home dir
if len(usr.HomeDir) == 0 || usr.HomeDir == "/dev/null" {
common.Logger.Printf("Excluding %v: has no home directory",
usr.Username)
return false

}

// check if home dir path is absolute
if !filepath.IsAbs(usr.HomeDir) {
common.Logger.Printf("Excluding %v: home directory path is "+
"not absolute: %v", usr.Username, usr.HomeDir)
return false
}

// check if user owns home dir
ownsHomeDir, err := common.UserOwnsFile(usr, usr.HomeDir)
if err != nil {
common.Logger.Printf("Excluding %v: %v", usr.Username, err)
return false
}
if !ownsHomeDir {
common.Logger.Printf("Excluding %v: doesn't own home dir",
usr.Username)
return false
}

return true
}

func shouldRunForUser(usr *user.User, prefs *Prefs) bool {
// check prefs
if !prefs.ShouldIncludeUser(usr) {
common.Logger.Printf("Excluding %v according to prefs",
usr.Username)
return false
}

if !userHasHome(usr) {
return false
}

if !shouldRunForUser_platform(usr) {
return false
}

return true
}

/*
Get all users for which we should run jobberrunner.
*/
func getAcceptableUsers(prefs *Prefs) ([]*user.User, error) {
acceptableUsers := make([]*user.User, 0)
allUsers, err := getAllUsers()
if err != nil {
return nil, err
}
for _, usr := range allUsers {
// check for reasons to exclude
if !shouldRunForUser(usr, prefs) {
continue
}

acceptableUsers = append(acceptableUsers, usr)
}

return acceptableUsers, nil
}
38 changes: 38 additions & 0 deletions jobbermaster/get_users_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package main

import (
"os/exec"
"os/user"
"strings"

"github.com/dshearer/jobber/common"
)

/*
Get all users.
*/
func getAllUsers() ([]*user.User, error) {
users := make([]*user.User, 0)
out, err := exec.Command("dscl", ".", "list", "/Users").Output()
if err != nil {
return nil, err
}
for _, s := range strings.Split(string(out), "\n") {
// look up user
usr, err := user.Lookup(s)
if err != nil {
continue
}
users = append(users, usr)
}
return users, nil
}

func shouldRunForUser_platform(usr *user.User) bool {
res := !strings.HasPrefix(usr.Username, "_")
if !res {
common.Logger.Printf("Excluding %v: username starts with \"_\"",
usr.Username)
}
return res
}
47 changes: 47 additions & 0 deletions jobbermaster/get_users_nondarwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// +build !darwin

package main

import (
"bufio"
"os"
"os/user"
"strings"

"github.com/dshearer/jobber/common"
)

/*
Get all users.
*/
func getAllUsers() ([]*user.User, error) {
users := make([]*user.User, 0)

// open passwd
f, err := os.Open("/etc/passwd")
if err != nil {
common.ErrLogger.Printf("Failed to open /etc/passwd: %v\n", err)
return users, err
}
defer f.Close()

scanner := bufio.NewScanner(f)
for scanner.Scan() {
// look up user
parts := strings.Split(scanner.Text(), ":")
if len(parts) == 0 {
continue
}
usr, err := user.Lookup(parts[0])
if err != nil {
continue
}

users = append(users, usr)
}
return users, nil
}

func shouldRunForUser_platform(usr *user.User) bool {
return true
}
81 changes: 3 additions & 78 deletions jobbermaster/main.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package main

import (
"bufio"
"context"
"fmt"
"github.com/dshearer/jobber/common"
"os"
"os/exec"
"os/signal"
"os/user"
"path/filepath"
"strings"
"sync"
"syscall"

"github.com/dshearer/jobber/common"
)

/*
Expand Down Expand Up @@ -81,80 +80,6 @@ Loop:
common.Logger.Printf("Exiting thread for %v", usr.Username)
}

func shouldRunForUser(usr *user.User, prefs *Prefs) bool {
// check prefs
if !prefs.ShouldIncludeUser(usr) {
common.Logger.Printf("Excluding %v according to prefs",
usr.Username)
return false
}

// check if user has home dir
if len(usr.HomeDir) == 0 || usr.HomeDir == "/dev/null" {
common.Logger.Printf("Excluding %v: has no home directory",
usr.Username)
return false

}

// check if home dir path is absolute
if !filepath.IsAbs(usr.HomeDir) {
common.Logger.Printf("Excluding %v: home directory path is "+
"not absolute: %v", usr.Username, usr.HomeDir)
return false
}

// check if user owns home dir
ownsHomeDir, err := common.UserOwnsFile(usr, usr.HomeDir)
if err != nil {
common.Logger.Printf("Excluding %v: %v", usr.Username, err)
return false
}
if !ownsHomeDir {
common.Logger.Printf("Excluding %v: doesn't own home dir",
usr.Username)
return false
}

return true
}

/*
Get all users that have home dirs.
*/
func listUsers(prefs *Prefs) ([]*user.User, error) {
users := make([]*user.User, 0)

// open passwd
f, err := os.Open("/etc/passwd")
if err != nil {
common.ErrLogger.Printf("Failed to open /etc/passwd: %v\n", err)
return users, err
}
defer f.Close()

scanner := bufio.NewScanner(f)
for scanner.Scan() {
// look up user
parts := strings.Split(scanner.Text(), ":")
if len(parts) == 0 {
continue
}
usr, err := user.Lookup(parts[0])
if err != nil {
continue
}

// check for reasons to exclude
if !shouldRunForUser(usr, prefs) {
continue
}

users = append(users, usr)
}
return users, nil
}

func mkdirp(path string, perm os.FileMode) error {
if err := os.Mkdir(path, perm); err != nil {
if err.(*os.PathError).Err.(syscall.Errno) != 17 {
Expand Down Expand Up @@ -184,7 +109,7 @@ func doDefault() int {
}

// get all users
users, err := listUsers(prefs)
users, err := getAcceptableUsers(prefs)
if err != nil {
return 1
}
Expand Down
5 changes: 4 additions & 1 deletion jobbermaster/sources.mk
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
MASTER_SOURCES := \
jobbermaster/get_users_darwin.go \
jobbermaster/get_users_nondarwin.go \
jobbermaster/get_users.go \
jobbermaster/main.go \
jobbermaster/prefs_file.go \
jobbermaster/runner_proc.go \
jobbermaster/sources.mk

MASTER_TEST_SOURCES := \
jobbermaster/prefs_file_test.go
jobbermaster/prefs_file_test.go
6 changes: 3 additions & 3 deletions jobberrunner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func main() {
haveInetParam := inetPort_p != nil && *inetPort_p > 0
if (!haveUdsParam && !haveInetParam) || (haveUdsParam && haveInetParam) {
usage("Must specify exactly one of -u and -p")
quit(0)
quit(1)
}

// handle flags
Expand Down Expand Up @@ -187,10 +187,10 @@ func main() {
// make IPC server
if haveUdsParam {
gIpcServer = NewUdsIpcServer(*udsSockPath_p, gJobManager.CmdChan)
common.Logger.Printf("Listing for commands on %v", *udsSockPath_p)
common.Logger.Printf("Listening for commands on %v", *udsSockPath_p)
} else {
gIpcServer = NewInetIpcServer(*inetPort_p, gJobManager.CmdChan)
common.Logger.Printf("Listing for commands on :%v", *inetPort_p)
common.Logger.Printf("Listening for commands on :%v", *inetPort_p)
}
if err := gIpcServer.Launch(); err != nil {
common.ErrLogger.Printf("Error: %v", err)
Expand Down
16 changes: 16 additions & 0 deletions packaging/darwin/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
include ../head.mk

# required by tail.mk:
PKGFILE = nop
PKGFILE_DEPS = nop
PKGFILE_VM_PATH = nop
PACKAGING_SUBDIR = darwin
SRC_TARBALL_DIR = jobber
INSTALL_PKG_CMD = nop
UNINSTALL_PKG_CMD = nop

.PHONY : test-local
test-local : ${WORK_DIR}/${SRC_TARBALL}
./make-and-install.sh ${WORK_DIR}/${SRC_TARBALL} $${PWD}

include ../tail.mk
14 changes: 14 additions & 0 deletions packaging/darwin/launchd.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>info.nekonya.jobber</string>
<key>Program</key>
<string>/usr/local/libexec/jobbermaster</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Loading

0 comments on commit 91e088e

Please sign in to comment.