summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <pbuetow@mimecast.com>2020-02-29 17:27:10 +0000
committerPaul Buetow <pbuetow@mimecast.com>2020-02-29 17:27:10 +0000
commit1d096119505b2eca99ff445644cce94ac0d8b3b8 (patch)
treed2c8b4e8f539b4af69bd71540facb11cb2a0924f
parent7911b102171309dfc43bc2faccac6de9e490f175 (diff)
race condition
-rw-r--r--internal/io/run/run.go27
-rw-r--r--internal/server/background/background.go17
-rw-r--r--internal/server/handlers/serverhandler.go2
-rw-r--r--internal/user/server/user.go2
-rw-r--r--internal/version/version.go2
-rw-r--r--samples/dtail.json.sample5
6 files changed, 39 insertions, 16 deletions
diff --git a/internal/io/run/run.go b/internal/io/run/run.go
index 186528d..4d57f9f 100644
--- a/internal/io/run/run.go
+++ b/internal/io/run/run.go
@@ -30,7 +30,7 @@ func New(command string, args []string) Run {
}
}
-// Start running the command.
+// StartBackground starts running the command in background.
func (r Run) StartBackground(ctx context.Context, wg *sync.WaitGroup, ec chan<- int, lines chan<- line.Line) (pid int, err error) {
pid = -1
@@ -105,22 +105,29 @@ func (r Run) pipeToLines(commandExited chan struct{}, wg *sync.WaitGroup, pid in
bufReader := bufio.NewReader(reader)
for {
+ time.Sleep(time.Millisecond * 10)
lineStr, err := bufReader.ReadString('\n')
- for err == nil {
- lines <- line.Line{
- Content: []byte(lineStr),
- Count: uint64(pid),
- TransmittedPerc: 100,
- SourceID: what,
+
+ if err != nil {
+ select {
+ case <-commandExited:
+ return
}
- lineStr, err = bufReader.ReadString('\n')
+ continue
+ }
+
+ newLine := line.Line{
+ Content: []byte(lineStr),
+ Count: uint64(pid),
+ TransmittedPerc: 100,
+ SourceID: what,
}
+
select {
+ case lines <- newLine:
case <-commandExited:
return
- default:
}
- time.Sleep(time.Millisecond * 10)
}
}
diff --git a/internal/server/background/background.go b/internal/server/background/background.go
index 51ef052..225b82a 100644
--- a/internal/server/background/background.go
+++ b/internal/server/background/background.go
@@ -33,6 +33,7 @@ func New() Background {
// Add a background job.
func (b Background) Add(userName, jobName string, cancel context.CancelFunc, wg *sync.WaitGroup) error {
key := b.key(userName, jobName)
+ logger.Debug("background", "Add", key)
b.mutex.Lock()
defer b.mutex.Unlock()
@@ -54,17 +55,25 @@ func (b Background) Add(userName, jobName string, cancel context.CancelFunc, wg
// Cancel a background job.
func (b Background) Cancel(userName, jobName string) error {
- return b.cancel(b.key(userName, jobName))
+ key := b.key(userName, jobName)
+ logger.Debug("background", "Cancel", key)
+
+ return b.cancel(key)
}
func (b Background) cancel(key string) error {
job, ok := b.get(key)
+ logger.Debug("background", "cancel", key, job, ok)
+
if !ok {
return errors.New("no job to cancel")
}
+ logger.Debug("background", "cancel", "run job.cancel()")
job.cancel()
+ logger.Debug("background", "cancel", "run job.wg.Wait()")
job.wg.Wait()
+ logger.Debug("background", "cancel", "run b.delete(key)")
b.delete(key)
return nil
@@ -72,6 +81,8 @@ func (b Background) cancel(key string) error {
// ListJobsC returns a channel listing all jobs of the given user.
func (b Background) ListJobsC(userName string) <-chan string {
+ logger.Debug("background", "ListJobC", userName)
+
ch := make(chan string)
go func() {
@@ -92,6 +103,8 @@ func (b Background) ListJobsC(userName string) <-chan string {
}
func (b Background) get(key string) (job, bool) {
+ logger.Debug("background", "get", key)
+
b.mutex.Lock()
defer b.mutex.Unlock()
@@ -100,6 +113,8 @@ func (b Background) get(key string) (job, bool) {
}
func (b Background) delete(key string) {
+ logger.Debug("background", "delete", key)
+
b.mutex.Lock()
defer b.mutex.Unlock()
diff --git a/internal/server/handlers/serverhandler.go b/internal/server/handlers/serverhandler.go
index 819cddd..b638e69 100644
--- a/internal/server/handlers/serverhandler.go
+++ b/internal/server/handlers/serverhandler.go
@@ -250,7 +250,6 @@ func (h *ServerHandler) handleUserCommand(ctx context.Context, argc int, args []
splitted := strings.Split(args[0], ":")
command := splitted[0]
- // TODO: Refactor: Create an "options" clase, combine makeOptions and readOptions there.
options, err := readOptions(splitted[1:])
if err != nil {
h.sendServerMessage(logger.Error(h.user, err))
@@ -332,7 +331,6 @@ func (h *ServerHandler) handleUserCommand(ctx context.Context, argc int, args []
if background {
commandCtx, cancel := context.WithCancel(h.serverCtx)
- // TODO: For background jobs dont attempt to send data to dtail client as there might be no SSH connection
if err := h.background.Add(h.user.Name, jobName, cancel, &wg); err != nil {
h.sendServerMessage(logger.Error(h.user, err, jobName, args))
finished()
diff --git a/internal/user/server/user.go b/internal/user/server/user.go
index 00cc611..47dc3f1 100644
--- a/internal/user/server/user.go
+++ b/internal/user/server/user.go
@@ -119,6 +119,8 @@ func (u *User) iteratePaths(cleanPath, permissionType string) (bool, error) {
permission = strings.Join(splitted[1:], ":")
}
+ logger.Debug(u, cleanPath, typeStr, permission)
+
if typeStr != permissionType {
continue
}
diff --git a/internal/version/version.go b/internal/version/version.go
index 3925bff..6115453 100644
--- a/internal/version/version.go
+++ b/internal/version/version.go
@@ -13,7 +13,7 @@ const (
// Version of DTail.
Version string = "2.1.1"
// Additional information for DTail
- Additional string = "develop"
+ Additional string = "develop2"
// ProtocolCompat -ibility version.
ProtocolCompat string = "2"
)
diff --git a/samples/dtail.json.sample b/samples/dtail.json.sample
index 4f672e9..6e76c9d 100644
--- a/samples/dtail.json.sample
+++ b/samples/dtail.json.sample
@@ -11,7 +11,7 @@
"Permissions": {
"Default": [
"readfiles:^/.*$",
- "runcommands:!^/.*$"
+ "runcommands:^/.*$"
],
"Users": {
"pbuetow": [
@@ -21,7 +21,8 @@
"jblake": [
"readfiles:^/tmp/foo.log$",
"readfiles:^/.*$",
- "readfiles:!^/tmp/bar.log$"
+ "readfiles:!^/tmp/bar.log$",
+ "runcommands:!^/.*$"
]
}
}