diff --git a/pkg/ansibleserver/models/ansibleplaybooks.go b/pkg/ansibleserver/models/ansibleplaybooks.go index 912e4a385e..797953eed1 100644 --- a/pkg/ansibleserver/models/ansibleplaybooks.go +++ b/pkg/ansibleserver/models/ansibleplaybooks.go @@ -59,6 +59,10 @@ type SAnsiblePlaybook struct { EndTime time.Time `list:"user"` } +const ( + OutputMaxBytes = 64*1024*1024 - 1 +) + type SAnsiblePlaybookManager struct { db.SVirtualResourceBaseManager @@ -218,6 +222,7 @@ func (apb *SAnsiblePlaybook) runPlaybook(ctx context.Context, userCred mcclient. } else { pb.PrivateKey = []byte(k) } + pb.OutputWriter(&ansiblePlaybookOutputRecorder{apb}) man.sessions.Add(apb.Id, pb) @@ -251,13 +256,6 @@ func (apb *SAnsiblePlaybook) runPlaybook(ctx context.Context, userCred mcclient. apb.Status = AnsiblePlaybookStatusSucceeded } apb.EndTime = time.Now() - // truncate to preserve the tail - output := pb.Output() - textMax := 64*1024*1024 - 1 - if len(output) > textMax { - output = output[len(output)-textMax:] - } - apb.Output = string(output) return nil }) if err != nil { @@ -278,3 +276,27 @@ func (apb *SAnsiblePlaybook) stopPlaybook(ctx context.Context, userCred mcclient man.sessions.Stop(apb.Id) return nil } + +type ansiblePlaybookOutputRecorder struct { + apb *SAnsiblePlaybook +} + +func (w *ansiblePlaybookOutputRecorder) Write(p []byte) (n int, err error) { + apb := w.apb + _, err = db.Update(apb, func() error { + cur := apb.Output + i := len(p) + len(cur) - OutputMaxBytes + if i > 0 { + // truncate to preserve the tail + apb.Output = cur[:len(cur)-i] + string(p) + } else { + apb.Output += string(p) + } + return nil + }) + if err != nil { + log.Errorf("ansibleplaybook %s(%s): record output: %v", apb.Name, apb.Id, err) + return 0, err + } + return len(p), nil +}