Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More debug output #190

Merged
merged 3 commits into from
Jun 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ endif

TEST_CRDS:=controllers/testdata/crds

# Log level for `make run`
LOG_LEVEL?=info

all: manager

# Running the tests requires the source.toolkit.fluxcd.io CRDs
Expand Down Expand Up @@ -49,7 +52,7 @@ manager: generate fmt vet

# Run against the configured Kubernetes cluster in ~/.kube/config
run: generate fmt vet manifests
go run ./main.go
go run ./main.go --log-level=${LOG_LEVEL} --log-encoding=console

# Install CRDs into a cluster
install: manifests
Expand Down
3 changes: 2 additions & 1 deletion controllers/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/storage/memory"
"github.com/go-logr/logr"
)

func populateRepoFromFixture(repo *git.Repository, fixture string) error {
Expand Down Expand Up @@ -100,7 +101,7 @@ func TestIgnoreBrokenSymlink(t *testing.T) {
t.Fatal(err)
}

_, err = commitChangedManifests(repo, tmp, nil, nil, "unused")
_, err = commitChangedManifests(logr.Discard(), repo, tmp, nil, nil, "unused")
if err != errNoChanges {
t.Fatalf("expected no changes but got: %v", err)
}
Expand Down
50 changes: 37 additions & 13 deletions controllers/imageupdateautomation_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,16 @@ import (
"github.com/fluxcd/image-automation-controller/pkg/update"
)

// log level for debug info
// log level for debug output
const debug = 1

// log level for trace output; the logging system
squaremo marked this conversation as resolved.
Show resolved Hide resolved
// (fluxcd/pkg/runtime/logging) doesn't presently account for levels
// more verbose than debug, so lump tracing into
// --log-level=debug. However, it's useful as self-documentation to
// keep tracing distinct.
const trace = 1

const originRemote = "origin"

const defaultMessageTemplate = `Update from image update automation`
Expand Down Expand Up @@ -97,6 +105,8 @@ type ImageUpdateAutomationReconciler struct {

func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := logr.FromContext(ctx)
debuglog := log.V(debug)
tracelog := log.V(trace)
now := time.Now()
var templateValues TemplateData

Expand Down Expand Up @@ -164,6 +174,8 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
Name: auto.Spec.SourceRef.Name,
Namespace: auto.GetNamespace(),
}
debuglog.Info("fetching git repository", "gitrepository", originName)

if err := r.Get(ctx, originName, &origin); err != nil {
if client.IgnoreNotFound(err) == nil {
imagev1.SetImageUpdateAutomationReadiness(&auto, metav1.ConditionFalse, imagev1.GitNotAvailableReason, "referenced git repository is missing")
Expand All @@ -176,19 +188,20 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, err
}

log.V(debug).Info("found git repository", "gitrepository", originName)

// validate the git spec and default any values needed later, before proceeding
var ref *sourcev1.GitRepositoryRef
if gitSpec.Checkout != nil {
ref = &gitSpec.Checkout.Reference
tracelog.Info("using git repository ref from .spec.git.checkout", "ref", ref)
} else if r := origin.Spec.Reference; r != nil {
ref = r
tracelog.Info("using git repository ref from GitRepository spec", "ref", ref)
} // else remain as `nil`, which is an acceptable value for cloneInto, later.

var pushBranch string
if gitSpec.Push != nil {
pushBranch = gitSpec.Push.Branch
tracelog.Info("using push branch from .spec.push.branch", "branch", pushBranch)
} else {
// Here's where it gets constrained. If there's no push branch
// given, then the checkout ref must include a branch, and
Expand All @@ -197,6 +210,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
failWithError(fmt.Errorf("Push branch not given explicitly, and cannot be inferred from .spec.git.checkout.ref or GitRepository .spec.ref"))
}
pushBranch = ref.Branch
tracelog.Info("using push branch from $ref.branch", "branch", pushBranch)
}

tmp, err := ioutil.TempDir("", fmt.Sprintf("%s-%s", originName.Namespace, originName.Name))
Expand All @@ -207,6 +221,8 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr

// FIXME use context with deadline for at least the following ops

debuglog.Info("attempting to clone git repository", "gitrepository", originName, "ref", ref, "working", tmp)

access, err := r.getRepoAccess(ctx, &origin)
if err != nil {
return failWithError(err)
Expand All @@ -229,10 +245,9 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
}
}

log.V(debug).Info("cloned git repository", "gitrepository", originName, "ref", ref, "working", tmp)

manifestsPath := tmp
if auto.Spec.Update.Path != "" {
tracelog.Info("adjusting update path according to .spec.update.path", "base", tmp, "spec-path", auto.Spec.Update.Path)
if p, err := securejoin.SecureJoin(tmp, auto.Spec.Update.Path); err != nil {
return failWithError(err)
} else {
Expand All @@ -250,7 +265,14 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
return failWithError(err)
}

if result, err := updateAccordingToSetters(ctx, manifestsPath, policies.Items); err != nil {
debuglog.Info("updating with setters according to image policies", "count", len(policies.Items), "manifests-path", manifestsPath)
if tracelog.Enabled() {
for _, item := range policies.Items {
tracelog.Info("found policy", "namespace", item.Namespace, "name", item.Name, "latest-image", item.Status.LatestImage)
}
}

if result, err := updateAccordingToSetters(ctx, tracelog, manifestsPath, policies.Items); err != nil {
return failWithError(err)
} else {
templateValues.Updated = result
Expand All @@ -263,7 +285,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, r.patchStatus(ctx, req, auto.Status)
}

log.V(debug).Info("ran updates to working dir", "working", tmp)
debuglog.Info("ran updates to working dir", "working", tmp)

var statusMessage string

Expand Down Expand Up @@ -294,10 +316,11 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
Email: gitSpec.Commit.Author.Email,
When: time.Now(),
}
if rev, err := commitChangedManifests(repo, tmp, signingEntity, author, messageBuf.String()); err != nil {

if rev, err := commitChangedManifests(tracelog, repo, tmp, signingEntity, author, messageBuf.String()); err != nil {
if err == errNoChanges {
r.event(ctx, auto, events.EventSeverityInfo, "no updates made")
log.V(debug).Info("no changes made in working directory; no commit")
debuglog.Info("no changes made in working directory; no commit")
statusMessage = "no updates made"
if lastCommit, lastTime := auto.Status.LastPushCommit, auto.Status.LastPushTime; lastCommit != "" {
statusMessage = fmt.Sprintf("%s; last commit %s at %s", statusMessage, lastCommit[:7], lastTime.Format(time.RFC3339))
Expand Down Expand Up @@ -520,11 +543,10 @@ func switchBranch(repo *gogit.Repository, pushBranch string) error {

var errNoChanges error = errors.New("no changes made to working directory")

func commitChangedManifests(repo *gogit.Repository, absRepoPath string, ent *openpgp.Entity, author *object.Signature, message string) (string, error) {
func commitChangedManifests(tracelog logr.Logger, repo *gogit.Repository, absRepoPath string, ent *openpgp.Entity, author *object.Signature, message string) (string, error) {
working, err := repo.Worktree()
if err != nil {
return "", err

}
status, err := working.Status()
if err != nil {
Expand All @@ -547,9 +569,11 @@ func commitChangedManifests(repo *gogit.Repository, absRepoPath string, ent *ope
// of the bug mentioned above, but not of interest in any
// case.
if _, err := os.Stat(abspath); os.IsNotExist(err) {
tracelog.Info("apparently broken symlink found; ignoring", "path", abspath)
continue
}
}
tracelog.Info("adding file", "file", file)
working.Add(file)
changed = true
}
Expand Down Expand Up @@ -724,8 +748,8 @@ func (r *ImageUpdateAutomationReconciler) recordReadinessMetric(ctx context.Cont

// updateAccordingToSetters updates files under the root by treating
// the given image policies as kyaml setters.
func updateAccordingToSetters(ctx context.Context, path string, policies []imagev1_reflect.ImagePolicy) (update.Result, error) {
return update.UpdateWithSetters(path, path, policies)
func updateAccordingToSetters(ctx context.Context, tracelog logr.Logger, path string, policies []imagev1_reflect.ImagePolicy) (update.Result, error) {
return update.UpdateWithSetters(tracelog, path, path, policies)
}

func (r *ImageUpdateAutomationReconciler) recordSuspension(ctx context.Context, auto imagev1.ImageUpdateAutomation) {
Expand Down
12 changes: 12 additions & 0 deletions pkg/update/filereader.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"os"
"path/filepath"

"github.com/go-logr/logr"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/kustomize/kyaml/yaml"
Expand All @@ -38,6 +39,8 @@ type ScreeningLocalReader struct {
Token string
Path string

Trace logr.Logger

// This records the relative path of each file that passed
// screening (i.e., contained the token), but couldn't be parsed.
ProblemFiles []string
Expand All @@ -51,6 +54,13 @@ type ScreeningLocalReader struct {
// [LocalPackageReader.Read](https://godoc.org/sigs.k8s.io/kustomize/kyaml/kio#LocalPackageReader.Read),
// adapting lightly (mainly to leave features out).
func (r *ScreeningLocalReader) Read() ([]*yaml.RNode, error) {
tracelog := r.Trace
if tracelog == nil {
tracelog = logr.Discard()
}

tracelog.Info("scanning files", "path", r.Path, "token", r.Token)

if r.Path == "" {
return nil, fmt.Errorf("must supply path to scan for files")
}
Expand Down Expand Up @@ -108,6 +118,7 @@ func (r *ScreeningLocalReader) Read() ([]*yaml.RNode, error) {
kioutil.PathAnnotation: path,
}

tracelog.Info("reading file", "path", path)
rdr := &kio.ByteReader{
Reader: bytes.NewBuffer(filebytes),
SetAnnotations: annotations,
Expand All @@ -119,6 +130,7 @@ func (r *ScreeningLocalReader) Read() ([]*yaml.RNode, error) {
// doesn't need to be the end of the matter; we can record
// this file as problematic, and continue.
if err != nil {
tracelog.Info("problem file", "path", path)
r.ProblemFiles = append(r.ProblemFiles, path)
return nil
}
Expand Down
11 changes: 11 additions & 0 deletions pkg/update/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package update

import (
"github.com/go-logr/logr"
"k8s.io/kube-openapi/pkg/validation/spec"
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/openapi"
Expand Down Expand Up @@ -48,6 +49,14 @@ import (
type SetAllCallback struct {
SettersSchema *spec.Schema
Callback func(setter, oldValue, newValue string)
Trace logr.Logger
}

func (s *SetAllCallback) TraceOrDiscard() logr.Logger {
if s.Trace == nil {
return logr.Discard()
}
return s.Trace
}

func (s *SetAllCallback) Filter(object *yaml.RNode) (*yaml.RNode, error) {
Expand Down Expand Up @@ -113,6 +122,7 @@ func (s *SetAllCallback) set(field *yaml.RNode, ext *setters2.CliExtension, sch
// this has a full setter, set its value
old := field.YNode().Value
field.YNode().Value = ext.Setter.Value
s.TraceOrDiscard().Info("applying setter", "setter", ext.Setter.Name, "old", old, "new", ext.Setter.Value)
s.Callback(ext.Setter.Name, old, ext.Setter.Value)

// format the node so it is quoted if it is a string. If there is
Expand All @@ -137,6 +147,7 @@ func (s *SetAllCallback) visitScalar(object *yaml.RNode, p string, fieldSchema *
return nil
}

s.TraceOrDiscard().Info("found schema extension", "path", p)
// perform a direct set of the field if it matches
_, err = s.set(object, ext, fieldSchema.Schema)
return err
Expand Down
18 changes: 12 additions & 6 deletions pkg/update/setters.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package update
import (
"fmt"

"github.com/go-logr/logr"
"github.com/google/go-containerregistry/pkg/name"
"k8s.io/apimachinery/pkg/types"
"k8s.io/kube-openapi/pkg/validation/spec"
Expand Down Expand Up @@ -51,7 +52,7 @@ func init() {
// UpdateWithSetters takes all YAML files from `inpath`, updates any
// that contain an "in scope" image policy marker, and writes files it
// updated (and only those files) back to `outpath`.
func UpdateWithSetters(inpath, outpath string, policies []imagev1alpha1_reflect.ImagePolicy) (Result, error) {
func UpdateWithSetters(tracelog logr.Logger, inpath, outpath string, policies []imagev1alpha1_reflect.ImagePolicy) (Result, error) {
// the OpenAPI schema is a package variable in kyaml/openapi. In
// lieu of being able to isolate invocations (per
// https://github.com/kubernetes-sigs/kustomize/issues/3058), I
Expand Down Expand Up @@ -161,28 +162,29 @@ func UpdateWithSetters(inpath, outpath string, policies []imagev1alpha1_reflect.
name := image[:len(image)-len(tag)-1]

imageSetter := fmt.Sprintf("%s:%s", policy.GetNamespace(), policy.GetName())
tracelog.Info("adding setter", "name", imageSetter)
defs[fieldmeta.SetterDefinitionPrefix+imageSetter] = setterSchema(imageSetter, policy.Status.LatestImage)
imageRefs[imageSetter] = ref

tagSetter := imageSetter + ":tag"
tracelog.Info("adding setter", "name", tagSetter)
defs[fieldmeta.SetterDefinitionPrefix+tagSetter] = setterSchema(tagSetter, tag)
imageRefs[tagSetter] = ref

// Context().Name() gives the image repository _as supplied_
nameSetter := imageSetter + ":name"
tracelog.Info("adding setter", "name", nameSetter)
defs[fieldmeta.SetterDefinitionPrefix+nameSetter] = setterSchema(nameSetter, name)
imageRefs[nameSetter] = ref
}

settersSchema.Definitions = defs
set := &SetAllCallback{
SettersSchema: &settersSchema,
}

// get ready with the reader and writer
reader := &ScreeningLocalReader{
Path: inpath,
Token: fmt.Sprintf("%q", SetterShortHand),
Trace: tracelog,
}
writer := &kio.LocalPackageWriter{
PackagePath: outpath,
Expand All @@ -192,7 +194,7 @@ func UpdateWithSetters(inpath, outpath string, policies []imagev1alpha1_reflect.
Inputs: []kio.Reader{reader},
Outputs: []kio.Writer{writer},
Filters: []kio.Filter{
setAll(set, setAllCallback),
setAll(&settersSchema, tracelog, setAllCallback),
},
}

Expand All @@ -210,7 +212,11 @@ func UpdateWithSetters(inpath, outpath string, policies []imagev1alpha1_reflect.
// files with changed nodes. This is based on
// [`SetAll`](https://github.com/kubernetes-sigs/kustomize/blob/kyaml/v0.10.16/kyaml/setters2/set.go#L503
// from kyaml/kio.
func setAll(filter *SetAllCallback, callback func(file, setterName string, node *yaml.RNode)) kio.Filter {
func setAll(schema *spec.Schema, tracelog logr.Logger, callback func(file, setterName string, node *yaml.RNode)) kio.Filter {
filter := &SetAllCallback{
SettersSchema: schema,
Trace: tracelog,
}
return kio.FilterFunc(
func(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
filesToUpdate := sets.String{}
Expand Down
5 changes: 3 additions & 2 deletions pkg/update/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"os"
"testing"

"github.com/go-logr/logr"
"github.com/google/go-containerregistry/pkg/name"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -88,7 +89,7 @@ var _ = Describe("Update image via kyaml setters2", func() {
},
}

_, err = UpdateWithSetters("testdata/setters/original", tmp, policies)
_, err = UpdateWithSetters(logr.Discard(), "testdata/setters/original", tmp, policies)
Expect(err).ToNot(HaveOccurred())
test.ExpectMatchingDirectories(tmp, "testdata/setters/expected")
})
Expand All @@ -98,7 +99,7 @@ var _ = Describe("Update image via kyaml setters2", func() {
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(tmp)

result, err := UpdateWithSetters("testdata/setters/original", tmp, policies)
result, err := UpdateWithSetters(logr.Discard(), "testdata/setters/original", tmp, policies)
Expect(err).ToNot(HaveOccurred())

kustomizeResourceID := ObjectIdentifier{yaml.ResourceIdentifier{
Expand Down