Browse Source

Add --git-readonly flag and plumb through to repo

This does the minimum to enable a read-only mode for git, that is:

 - add the flag to fluxd
 - pass the flag value along to the repo, so it knows when the repo is
   read-only (the main effect of this is that it won't try to test
   that it can write to the upstream after cloning)
 - do some checks for interaction between the sync state and read-only
   -- basically, you can't use a git tag for sync state if the repo is
   read-only.
Michael Bridgen 4 months ago
parent
commit
07c8b30f6a
4 changed files with 43 additions and 9 deletions
  1. 35
    2
      cmd/fluxd/main.go
  2. 2
    1
      git/errors.go
  3. 6
    2
      git/repo.go
  4. 0
    4
      git/working.go

+ 35
- 2
cmd/fluxd/main.go View File

@@ -112,13 +112,14 @@ func main() {
112 112
 		gitURL       = fs.String("git-url", "", "URL of git repo with Kubernetes manifests; e.g., git@github.com:weaveworks/flux-get-started")
113 113
 		gitBranch    = fs.String("git-branch", "master", "branch of git repo to use for Kubernetes manifests")
114 114
 		gitPath      = fs.StringSlice("git-path", []string{}, "relative paths within the git repo to locate Kubernetes manifests")
115
+		gitReadonly  = fs.Bool("git-readonly", false, fmt.Sprintf("use to prevent Flux from pushing changes to git; implies --sync-state=%s", fluxsync.NativeStateMode))
115 116
 		gitUser      = fs.String("git-user", "Weave Flux", "username to use as git committer")
116 117
 		gitEmail     = fs.String("git-email", "support@weave.works", "email to use as git committer")
117 118
 		gitSetAuthor = fs.Bool("git-set-author", false, "if set, the author of git commits will reflect the user who initiated the commit and will differ from the git committer.")
118 119
 		gitLabel     = fs.String("git-label", "", "label to keep track of sync progress; overrides both --git-sync-tag and --git-notes-ref")
119 120
 		gitSecret    = fs.Bool("git-secret", false, `if set, git-secret will be run on every git checkout. A gpg key must be imported using  --git-gpg-key-import or by mounting a keyring containing it directly`)
120 121
 		// Old git config; still used if --git-label is not supplied, but --git-label is preferred.
121
-		gitSyncTag     = fs.String("git-sync-tag", defaultGitSyncTag, "tag to use to mark sync progress for this cluster")
122
+		gitSyncTag     = fs.String("git-sync-tag", defaultGitSyncTag, fmt.Sprintf("tag to use to mark sync progress for this cluster (only relevant when --sync-state=%s)", fluxsync.GitTagStateMode))
122 123
 		gitNotesRef    = fs.String("git-notes-ref", defaultGitNotesRef, "ref to use for keeping commit annotations in git notes")
123 124
 		gitSkip        = fs.Bool("git-ci-skip", false, `append "[ci skip]" to commit messages so that CI will skip builds`)
124 125
 		gitSkipMessage = fs.String("git-ci-skip-message", "", "additional text for commit messages, useful for skipping builds in CI. Use this to supply specific text, or set --git-ci-skip")
@@ -248,8 +249,34 @@ func main() {
248 249
 		k8slog.Log("err", err)
249 250
 	}
250 251
 	k8sruntime.ErrorHandlers = []func(error){logErrorUnlessAccessRelated}
252
+
251 253
 	// Argument validation
252 254
 
255
+	if *gitReadonly {
256
+		if *syncState == fluxsync.GitTagStateMode {
257
+			logger.Log("warning", fmt.Sprintf("--git-readonly prevents use of --sync-state=%s. Forcing to --sync-state=%s", fluxsync.GitTagStateMode, fluxsync.NativeStateMode))
258
+			*syncState = fluxsync.NativeStateMode
259
+		}
260
+
261
+		gitRelatedFlags := []string{
262
+			"git-user",
263
+			"git-email",
264
+			"git-sync-tag",
265
+			"git-set-author",
266
+			"git-ci-skip",
267
+			"git-ci-skip-message",
268
+		}
269
+		var changedGitRelatedFlags []string
270
+		for _, gitRelatedFlag := range gitRelatedFlags {
271
+			if fs.Changed(gitRelatedFlag) {
272
+				changedGitRelatedFlags = append(changedGitRelatedFlags, gitRelatedFlag)
273
+			}
274
+		}
275
+		if len(changedGitRelatedFlags) > 0 {
276
+			logger.Log("warning", fmt.Sprintf("configuring any of {%s} has no effect when --git-readonly is set", strings.Join(changedGitRelatedFlags, ", ")))
277
+		}
278
+	}
279
+
253 280
 	// Maintain backwards compatibility with the --registry-poll-interval
254 281
 	// flag, but only if the --automation-interval is not set to a custom
255 282
 	// (non default) value.
@@ -571,7 +598,7 @@ func main() {
571 598
 		GitSecret:   *gitSecret,
572 599
 	}
573 600
 
574
-	repo := git.NewRepo(gitRemote, git.PollInterval(*gitPollInterval), git.Timeout(*gitTimeout), git.Branch(*gitBranch))
601
+	repo := git.NewRepo(gitRemote, git.PollInterval(*gitPollInterval), git.Timeout(*gitTimeout), git.Branch(*gitBranch), git.IsReadOnly(*gitReadonly))
575 602
 	{
576 603
 		shutdownWg.Add(1)
577 604
 		go func() {
@@ -589,6 +616,8 @@ func main() {
589 616
 		"signing-key", *gitSigningKey,
590 617
 		"verify-signatures", *gitVerifySignatures,
591 618
 		"sync-tag", *gitSyncTag,
619
+		"state", *syncState,
620
+		"readonly", *gitReadonly,
592 621
 		"notes-ref", *gitNotesRef,
593 622
 		"set-author", *gitSetAuthor,
594 623
 		"git-secret", *gitSecret,
@@ -629,6 +658,10 @@ func main() {
629 658
 			logger.Log("err", err)
630 659
 			os.Exit(1)
631 660
 		}
661
+
662
+	default:
663
+		logger.Log("error", "unknown sync state mode", "mode", *syncState)
664
+		os.Exit(1)
632 665
 	}
633 666
 
634 667
 	daemon := &daemon.Daemon{

+ 2
- 1
git/errors.go View File

@@ -114,7 +114,8 @@ create a new deploy key. To create a new one, use
114 114
     fluxctl identity --regenerate
115 115
 
116 116
 The public key this outputs can then be given to GitHub; make sure you
117
-check the box to allow write access.
117
+check the box to allow write access unless you're using the
118
+--git-readonly=true option.
118 119
 
119 120
 `,
120 121
 	}

+ 6
- 2
git/repo.go View File

@@ -91,10 +91,14 @@ func (b Branch) apply(r *Repo) {
91 91
 	r.branch = string(b)
92 92
 }
93 93
 
94
-var ReadOnly optionFunc = func(r *Repo) {
95
-	r.readonly = true
94
+type IsReadOnly bool
95
+
96
+func (ro IsReadOnly) apply(r *Repo) {
97
+	r.readonly = bool(ro)
96 98
 }
97 99
 
100
+var ReadOnly IsReadOnly = true
101
+
98 102
 // NewRepo constructs a repo mirror which will sync itself.
99 103
 func NewRepo(origin Remote, opts ...Option) *Repo {
100 104
 	status := RepoNew

+ 0
- 4
git/working.go View File

@@ -59,10 +59,6 @@ type TagAction struct {
59 59
 // Clone returns a local working clone of the sync'ed `*Repo`, using
60 60
 // the config given.
61 61
 func (r *Repo) Clone(ctx context.Context, conf Config) (*Checkout, error) {
62
-	if r.readonly {
63
-		return nil, ErrReadOnly
64
-	}
65
-
66 62
 	upstream := r.Origin()
67 63
 	repoDir, err := r.workingClone(ctx, conf.Branch)
68 64
 	if err != nil {

Loading…
Cancel
Save