This is an automated email from the ASF dual-hosted git repository.
ocket8888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new 2e324be2d8 Add t3c action log (#6924)
2e324be2d8 is described below
commit 2e324be2d85040b14ed43e988dadf9a11a21ae0f
Author: Robert O Butts <[email protected]>
AuthorDate: Fri Jul 29 09:13:55 2022 -0600
Add t3c action log (#6924)
---
cache-config/t3c-apply/t3c-apply.go | 37 ++++++++-
cache-config/t3c-apply/torequest/torequest.go | 13 +++-
cache-config/t3c-apply/util/gitutil.go | 20 +++--
cache-config/t3cutil/actionlog.go | 87 ++++++++++++++++++++++
cache-config/t3cutil/t3cutil.go | 11 ++-
...etadata-file_test.go => t3c-action-log_test.go} | 35 +++------
.../ort-tests/t3c-create-metadata-file_test.go | 11 +++
7 files changed, 173 insertions(+), 41 deletions(-)
diff --git a/cache-config/t3c-apply/t3c-apply.go
b/cache-config/t3c-apply/t3c-apply.go
index afdfc12146..353e24a864 100644
--- a/cache-config/t3c-apply/t3c-apply.go
+++ b/cache-config/t3c-apply/t3c-apply.go
@@ -125,13 +125,22 @@ func Main() int {
metaData.ServerHostName = cfg.CacheHostName
+ t3cutil.WriteActionLog(t3cutil.ActionLogActionApplyStart,
t3cutil.ActionLogStatusSuccess, metaData)
+
if cfg.UseGit == config.UseGitYes {
- err := util.EnsureConfigDirIsGitRepo(cfg)
+ triedMakingRepo, err := util.EnsureConfigDirIsGitRepo(cfg)
if err != nil {
log.Errorln("Ensuring config directory '" +
cfg.TsConfigDir + "' is a git repo - config may not be a git repo! " +
err.Error())
+ if triedMakingRepo {
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionGitInit,
t3cutil.ActionLogStatusFailure, metaData)
+ }
} else {
log.Infoln("Successfully ensured ATS config directory
'" + cfg.TsConfigDir + "' is a git repo")
+ if triedMakingRepo {
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionGitInit,
t3cutil.ActionLogStatusSuccess, metaData)
+ }
}
+
} else {
log.Infoln("UseGit not 'yes', not creating git repo")
}
@@ -141,6 +150,9 @@ func Main() int {
// with a keyword indicating it wasn't our change
if err := util.MakeGitCommitAll(cfg, util.GitChangeNotSelf,
true); err != nil {
log.Errorln("git committing existing changes, dir '" +
cfg.TsConfigDir + "': " + err.Error())
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionGitCommitInitial,
t3cutil.ActionLogStatusFailure, metaData)
+ } else {
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionGitCommitInitial,
t3cutil.ActionLogStatusSuccess, metaData)
}
}
@@ -207,7 +219,7 @@ func Main() int {
} else if rc == 0 {
log.Infoln("updated the remap.config
for reloading.")
}
- if err := trops.StartServices(&syncdsUpdate);
err != nil {
+ if err := trops.StartServices(&syncdsUpdate,
metaData); err != nil {
log.Errorln("failed to start services:
" + err.Error())
metaData.PartialSuccess = true
return
GitCommitAndExit(ExitCodeServicesError, PostConfigFailureExitMsg, cfg,
metaData, oldMetaData)
@@ -250,6 +262,10 @@ func Main() int {
syncdsUpdate, err = trops.ProcessConfigFiles(metaData)
if err != nil {
log.Errorf("Error while processing config files: %s\n",
err.Error())
+ t3cutil.WriteActionLog(t3cutil.ActionLogActionUpdateFilesAll,
t3cutil.ActionLogStatusFailure, metaData)
+
+ } else {
+ t3cutil.WriteActionLog(t3cutil.ActionLogActionUpdateFilesAll,
t3cutil.ActionLogStatusSuccess, metaData)
}
// check for maxmind db updates
@@ -268,7 +284,7 @@ func Main() int {
}
}
- if err := trops.StartServices(&syncdsUpdate); err != nil {
+ if err := trops.StartServices(&syncdsUpdate, metaData); err != nil {
log.Errorln("failed to start services: " + err.Error())
metaData.PartialSuccess = true
return GitCommitAndExit(ExitCodeServicesError,
PostConfigFailureExitMsg, cfg, metaData, oldMetaData)
@@ -335,9 +351,24 @@ func GitCommitAndExit(exitCode int, exitMsg string, cfg
config.Cfg, metaData *t3
if cfg.UseGit == config.UseGitYes || cfg.UseGit == config.UseGitAuto {
if err := util.MakeGitCommitAll(cfg, util.GitChangeIsSelf,
success); err != nil {
log.Errorln("git committing existing changes, dir '" +
cfg.TsConfigDir + "': " + err.Error())
+ // nil metadata to prevent modifying the file after the
final git commit
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionGitCommitFinal,
t3cutil.ActionLogStatusFailure, nil)
+ } else {
+ // nil metadata to prevent modifying the file after the
final git commit
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionGitCommitFinal,
t3cutil.ActionLogStatusSuccess, nil)
}
}
+
+ if metaData.Succeeded {
+ // nil metadata to prevent modifying the file after the final
git commit
+ t3cutil.WriteActionLog(t3cutil.ActionLogActionApplyEnd,
t3cutil.ActionLogStatusSuccess, nil)
+ } else {
+ // nil metadata to prevent modifying the file after the final
git commit
+ t3cutil.WriteActionLog(t3cutil.ActionLogActionApplyEnd,
t3cutil.ActionLogStatusFailure, nil)
+ }
+
log.Infoln(exitMsg)
+
return exitCode
}
diff --git a/cache-config/t3c-apply/torequest/torequest.go
b/cache-config/t3c-apply/torequest/torequest.go
index e0eef3f267..35cef6a396 100644
--- a/cache-config/t3c-apply/torequest/torequest.go
+++ b/cache-config/t3c-apply/torequest/torequest.go
@@ -1037,10 +1037,13 @@ func (r *TrafficOpsReq)
RevalidateWhileSleeping(metaData *t3cutil.ApplyMetaData)
updateStatus, err := r.ProcessConfigFiles(metaData)
if err != nil {
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionUpdateFilesReval,
t3cutil.ActionLogStatusFailure, metaData)
return updateStatus, err
+ } else {
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionUpdateFilesReval,
t3cutil.ActionLogStatusSuccess, metaData)
}
- if err := r.StartServices(&updateStatus); err != nil {
+ if err := r.StartServices(&updateStatus, metaData); err != nil {
return updateStatus, errors.New("failed to start
services: " + err.Error())
}
@@ -1057,7 +1060,7 @@ func (r *TrafficOpsReq) RevalidateWhileSleeping(metaData
*t3cutil.ApplyMetaData)
// StartServices reloads, restarts, or starts ATS as necessary,
// according to the changed config files and run mode.
// Returns nil on success or any error.
-func (r *TrafficOpsReq) StartServices(syncdsUpdate *UpdateStatus) error {
+func (r *TrafficOpsReq) StartServices(syncdsUpdate *UpdateStatus, metaData
*t3cutil.ApplyMetaData) error {
serviceNeeds := t3cutil.ServiceNeedsNothing
if r.Cfg.ServiceAction == t3cutil.ApplyServiceActionFlagRestart {
serviceNeeds = t3cutil.ServiceNeedsRestart
@@ -1103,8 +1106,10 @@ func (r *TrafficOpsReq) StartServices(syncdsUpdate
*UpdateStatus) error {
startStr = "start"
}
if _, err := util.ServiceStart("trafficserver", startStr); err
!= nil {
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionATSRestart,
t3cutil.ActionLogStatusFailure, metaData)
return errors.New("failed to restart trafficserver")
}
+ t3cutil.WriteActionLog(t3cutil.ActionLogActionATSRestart,
t3cutil.ActionLogStatusSuccess, metaData)
log.Infoln("trafficserver has been " + startStr + "ed")
if *syncdsUpdate == UpdateTropsNeeded {
*syncdsUpdate = UpdateTropsSuccessful
@@ -1119,11 +1124,15 @@ func (r *TrafficOpsReq) StartServices(syncdsUpdate
*UpdateStatus) error {
} else if serviceNeeds == t3cutil.ServiceNeedsReload {
log.Infoln("ATS configuration has changed, Running
'traffic_ctl config reload' now.")
if _, _, err :=
util.ExecCommand(config.TSHome+config.TrafficCtl, "config", "reload"); err !=
nil {
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionATSReload,
t3cutil.ActionLogStatusFailure, metaData)
+
if *syncdsUpdate == UpdateTropsNeeded {
*syncdsUpdate = UpdateTropsFailed
}
return errors.New("ATS configuration has
changed and 'traffic_ctl config reload' failed, check ATS logs: " + err.Error())
}
+
t3cutil.WriteActionLog(t3cutil.ActionLogActionATSReload,
t3cutil.ActionLogStatusSuccess, metaData)
+
if *syncdsUpdate == UpdateTropsNeeded {
*syncdsUpdate = UpdateTropsSuccessful
}
diff --git a/cache-config/t3c-apply/util/gitutil.go
b/cache-config/t3c-apply/util/gitutil.go
index 9dca3dbeca..3706c3be2a 100644
--- a/cache-config/t3c-apply/util/gitutil.go
+++ b/cache-config/t3c-apply/util/gitutil.go
@@ -32,31 +32,35 @@ import (
"github.com/apache/trafficcontrol/cache-config/t3c-apply/config"
)
-func EnsureConfigDirIsGitRepo(cfg config.Cfg) error {
+// EnsureConfigDirIsGitRepo ensures the ATS config directory is a git repo.
+// Returns whether it tried to create a git repo, and any error.
+// Note the return will be (false, nil) if a git repo already exists.
+// Note true and a non-nil error may be returned, if creating a git repo is
necessary and attempted and fails.
+func EnsureConfigDirIsGitRepo(cfg config.Cfg) (bool, error) {
cmd := exec.Command("git", "status")
cmd.Dir = cfg.TsConfigDir
errPipe, err := cmd.StderrPipe()
if err != nil {
- return errors.New("getting stderr pipe for command: " +
err.Error())
+ return false, errors.New("getting stderr pipe for command: " +
err.Error())
}
if err := cmd.Start(); err != nil {
if _, ok := err.(*exec.ExitError); !ok {
// this means Go failed to run the command, not that
the command returned an error.
- return errors.New("git status returned: " + err.Error())
+ return false, errors.New("git status returned: " +
err.Error())
}
}
errOutput, err := ioutil.ReadAll(errPipe)
if err != nil {
- return errors.New("reading stderr: " + err.Error())
+ return false, errors.New("reading stderr: " + err.Error())
}
if err := cmd.Wait(); err != nil {
if _, ok := err.(*exec.ExitError); !ok {
// this means Go failed to run the command, not that
the command returned an error.
- return errors.New("waiting for git command: " +
err.Error())
+ return false, errors.New("waiting for git command: " +
err.Error())
}
}
@@ -64,14 +68,14 @@ func EnsureConfigDirIsGitRepo(cfg config.Cfg) error {
errOutput = bytes.ToLower(errOutput)
if !bytes.Contains(errOutput, []byte(GitNotARepoMsgPrefix)) {
- return nil // it's already a git repo
+ return false, nil // it's already a git repo
}
if err := makeConfigDirGitRepo(cfg); err != nil {
- return errors.New("making config dir '" + cfg.TsConfigDir + "'
a git repo: " + err.Error())
+ return true, errors.New("making config dir '" + cfg.TsConfigDir
+ "' a git repo: " + err.Error())
}
- return nil
+ return true, nil
}
func makeConfigDirGitRepo(cfg config.Cfg) error {
diff --git a/cache-config/t3cutil/actionlog.go
b/cache-config/t3cutil/actionlog.go
new file mode 100644
index 0000000000..908f4ea054
--- /dev/null
+++ b/cache-config/t3cutil/actionlog.go
@@ -0,0 +1,87 @@
+package t3cutil
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import (
+ "github.com/apache/trafficcontrol/lib/go-log"
+)
+
+// ActionLogAction is an action t3c performs which affects the state of the
machine.
+// Things that don't affect the state of the machine are not considered
actions.
+//
+// For example, requesting Traffic Ops is not an 'action',
+// but restarting ATS or modifying a config file is.
+//
+// Actions also include the t3c-apply run starting and finishing,
+// to help delineate the actions of different runs in the log.
+//
+type ActionLogAction string
+
+const (
+ // ActionLogActionApplyStart is the start of the t3c-apply run.
+ // The status of this should always be success.
+ ActionLogActionApplyStart = ActionLogAction("apply-start")
+
+ // ActionLogActionGitInit is creating a git repo in the ATS config
directory.
+ ActionLogActionGitInit = ActionLogAction("git-init")
+
+ // ActionLogActionGitCommitInitial is the initial commit at the start
of the run.
+ ActionLogActionGitCommitInitial =
ActionLogAction("create-git-commit-initial")
+
+ // ActionLogActionGitCommitInitial is the final commit at the end of
the run.
+ ActionLogActionGitCommitFinal =
ActionLogAction("create-git-commit-final")
+
+ // ActionLogActionUpdateFilesAll is writing and updating ATS config
files.
+ ActionLogActionUpdateFilesAll = ActionLogAction("update-files-all")
+
+ // ActionLogActionUpdateFilesReval is writing and updating only
revalidate ATS config files.
+ ActionLogActionUpdateFilesReval = ActionLogAction("update-files-reval")
+
+ // ActionLogActionATSReload is calling service reload on ATS.
+ ActionLogActionATSReload = ActionLogAction("ats-reload")
+
+ // ActionLogActionATSReload is calling service restart on ATS.
+ ActionLogActionATSRestart = ActionLogAction("ats-restart")
+
+ // ActionLogActionApplyEnd is the end of the t3c-apply run.
+ ActionLogActionApplyEnd = ActionLogAction("apply-end")
+)
+
+type ActionLogStatus string
+
+const (
+ ActionLogStatusSuccess = ActionLogStatus("success")
+ ActionLogStatusFailure = ActionLogStatus("failure")
+)
+
+// WriteActionLog writes the given action and status to both the info log and
the given metadata object.
+//
+// The metaData may be nil, and should be if this is being called after the
final git commit,
+// to prevent modifying the file after the commit.
+//
+func WriteActionLog(action ActionLogAction, status ActionLogStatus, metaData
*ApplyMetaData) {
+ if metaData != nil {
+ metaData.Actions = append(metaData.Actions, ApplyMetaDataAction{
+ Action: string(action),
+ Status: string(status),
+ })
+ }
+ log.Infoln(`ACTION='` + string(action) + `' STATUS='` + string(status)
+ `'` + "\n")
+}
diff --git a/cache-config/t3cutil/t3cutil.go b/cache-config/t3cutil/t3cutil.go
index 8073285d9d..aa4ee70f42 100644
--- a/cache-config/t3cutil/t3cutil.go
+++ b/cache-config/t3cutil/t3cutil.go
@@ -258,8 +258,9 @@ func UserAgentStr(appName string, versionNum string,
gitRevision string) string
func NewApplyMetaData() *ApplyMetaData {
return &ApplyMetaData{
Version: MetaDataVersion,
- InstalledPackages: []string{}, // construct a slice, so JSON
serializes '[]' not 'null'.
- OwnedFilePaths: []string{}, // construct a slice, so JSON
serializes '[]' not 'null'.
+ InstalledPackages: []string{}, // construct a
slice, so JSON serializes '[]' not 'null'.
+ OwnedFilePaths: []string{}, // construct a
slice, so JSON serializes '[]' not 'null'.
+ Actions: []ApplyMetaDataAction{}, // construct a map,
so JSON serializes '{}' not 'null'.
}
}
@@ -351,6 +352,12 @@ type ApplyMetaData struct {
// are strongly encouraged to set alarms and read logs in the event it
occurs,
// to determine what was changed, what failed, and what actions need
taken.
PartialSuccess bool `json:"partial-success"`
+
+ Actions []ApplyMetaDataAction `json:"actions"`
+}
+type ApplyMetaDataAction struct {
+ Action string `json:"action"`
+ Status string `json:"status"`
}
// Format prints the ApplyMetaData in a format designed to be written to a
file,
diff --git a/cache-config/testing/ort-tests/t3c-create-metadata-file_test.go
b/cache-config/testing/ort-tests/t3c-action-log_test.go
similarity index 50%
copy from cache-config/testing/ort-tests/t3c-create-metadata-file_test.go
copy to cache-config/testing/ort-tests/t3c-action-log_test.go
index 745fd89650..3c1cfe8b20 100644
--- a/cache-config/testing/ort-tests/t3c-create-metadata-file_test.go
+++ b/cache-config/testing/ort-tests/t3c-action-log_test.go
@@ -15,17 +15,14 @@ package orttest
*/
import (
- "encoding/json"
- "io/ioutil"
- "path/filepath"
+ "strings"
"testing"
+ "github.com/apache/trafficcontrol/cache-config/t3cutil"
"github.com/apache/trafficcontrol/cache-config/testing/ort-tests/tcdata"
- "github.com/apache/trafficcontrol/cache-config/testing/ort-tests/util"
)
-func TestT3cCreateMetaDataFile(t *testing.T) {
- // t3c should create a metadata file
+func TestT3cActionLog(t *testing.T) {
tcd.WithObjs(t, []tcdata.TCObj{
tcdata.CDNs, tcdata.Types, tcdata.Tenants, tcdata.Parameters,
tcdata.Profiles, tcdata.ProfileParameters,
@@ -33,29 +30,15 @@ func TestT3cCreateMetaDataFile(t *testing.T) {
tcdata.CacheGroups, tcdata.Servers, tcdata.Topologies,
tcdata.DeliveryServices}, func() {
- err := t3cUpdateCreateEmptyFile(DefaultCacheHostName, "badass")
- if err != nil {
- t.Fatalf("t3c badass failed: %v", err)
+ stdErr, exitCode := t3cUpdateReload(DefaultCacheHostName,
"badass")
+ if exitCode != 0 {
+ t.Fatalf("t3c badass failed, code: %v", exitCode)
}
- const metaDataFileName = `t3c-apply-metadata.json`
-
- filePath := filepath.Join(TestConfigDir, metaDataFileName)
-
- if !util.FileExists(filePath) {
- t.Fatalf("missing metadata file '%s'", filePath)
+ startActionMsg := `ACTION='` +
t3cutil.ActionLogActionApplyStart + `'`
+ if !strings.Contains(stdErr, string(startActionMsg)) {
+ t.Errorf("expected log to contain action log message
'%s', actual: %s", startActionMsg, string(stdErr))
}
- mdFileBts, err := ioutil.ReadFile(filePath)
- if err != nil {
- t.Fatalf("reading file '%s': %v", filePath, err)
- }
-
- // Test that the file is a valid JSON object.
- // Other than that, we don't want to assert any particular data.
- mdObj := map[string]interface{}{}
- if err := json.Unmarshal(mdFileBts, &mdObj); err != nil {
- t.Errorf("expected metadata file '%s' to be a json
object, actual: %s", filePath, err)
- }
})
}
diff --git a/cache-config/testing/ort-tests/t3c-create-metadata-file_test.go
b/cache-config/testing/ort-tests/t3c-create-metadata-file_test.go
index 745fd89650..86c4e95893 100644
--- a/cache-config/testing/ort-tests/t3c-create-metadata-file_test.go
+++ b/cache-config/testing/ort-tests/t3c-create-metadata-file_test.go
@@ -18,8 +18,10 @@ import (
"encoding/json"
"io/ioutil"
"path/filepath"
+ "strings"
"testing"
+ "github.com/apache/trafficcontrol/cache-config/t3cutil"
"github.com/apache/trafficcontrol/cache-config/testing/ort-tests/tcdata"
"github.com/apache/trafficcontrol/cache-config/testing/ort-tests/util"
)
@@ -57,5 +59,14 @@ func TestT3cCreateMetaDataFile(t *testing.T) {
if err := json.Unmarshal(mdFileBts, &mdObj); err != nil {
t.Errorf("expected metadata file '%s' to be a json
object, actual: %s", filePath, err)
}
+
+ metaDataStr := string(mdFileBts)
+ if !strings.Contains(metaDataStr, `"actions":`) {
+ t.Errorf("expected metadata file '%s' to contain action
log, actual: %s", filePath, metaDataStr)
+ }
+ if !strings.Contains(metaDataStr,
`"`+string(t3cutil.ActionLogActionApplyStart)+`"`) {
+ t.Errorf("expected metadata file '%s' to contain action
log apply start message '%v', actual: %s", filePath,
t3cutil.ActionLogActionApplyStart, metaDataStr)
+ }
+
})
}