Libgitops
A Go library for implementing GitOps, used by Ignite
Install / Use
/learn @weaveworks/LibgitopsREADME
Deprecated
This repository is no longer maintained. For a more up-to-date way to manage microVMs, please take a look at Flintlock.
Weave libgitops
A library of tools for manipulation and storage of Kubernetes-style objects with inbuilt GitOps functionality.
Weave libgitops builds on top of the Kubernetes API Machinery.
The library consists of several components, including (but not limited to):
YAML/JSON Serializer - pkg/serializer
The libgitops Serializer is a powerful extension of the Kubernetes API Machinery serialization/manifest manipulation tools.
It operates on Kubernetes runtime.Object compliant objects (types that implement metav1.TypeMeta), and focuses
on streamlining the user experience of dealing with encoding/decoding, versioning (GVKs), conversions and
defaulting.
It also supports API types built with controller-runtime.
Feature highlight:
- Preserving of Comments (even through conversions)
- Strict Decoding
- Multi-Frame Support (multiple documents in one file)
- Works with all Kubernetes-like objects
Example usage:
// Create a serializer instance for Kubernetes types
s := serializer.NewSerializer(scheme.Scheme, nil)
// Read all YAML documents, frame by frame, from STDIN
fr := serializer.NewYAMLFrameReader(os.Stdin)
// Decode all YAML documents from the FrameReader to objects
objs, err := s.Decoder().DecodeAll(fr)
// Write YAML documents, frame by frame, to STDOUT
fw := serializer.NewYAMLFrameWriter(os.Stdout)
// Encode all objects as YAML documents, into the FrameWriter
err = s.Encoder().Encode(fw, objs...)
See the pkg/serializer package for details.
Note: If you need to manipulate unstructured objects (not struct-backed, not runtime.Object compliant), the
kyaml library from kustomize may be a better fit.
The extended runtime - pkg/runtime
The pkg/runtime package provides additional definitions and helpers around the upstream API Machinery
runtime. The most notable definition is the extended runtime.Object (from herein pkg/runtime.Object):
// Object is an union of the Object interfaces that are accessible for a
// type that embeds both metav1.TypeMeta and metav1.ObjectMeta.
type Object interface {
runtime.Object
metav1.ObjectMetaAccessor
metav1.Object
}
Any struct that embeds both metav1.TypeMeta and metav1.ObjectMeta inline, and has the automatically-generated
deep-copy code using the tag // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object will implement
pkg/runtime.Object. See an example in cmd/sample-app/apis/sample.
This extended pkg/runtime.Object is used heavily in the storage subsystem described below.
The storage system - pkg/storage
The storage system is a collection of interfaces and reference implementations for storing Kubernetes-like objects
(that comply to the extended pkg/runtime.Object described above). It can be thought of as a database abstraction layer
for objects based on how the interfaces are laid out.
There are three "layers" of storages:
RawStorage interface
The RawStorage interfaces deal with bytes, this includes RawStorage and MappedRawStorage. It is essentially a
filesystem abstraction.
GenericRawStorageis a generic implementation ofRawStorage, storing all objects as files on disk using the following path pattern:<top-level-dir>/<kind>/<identifier>/metadata.json.GenericMappedRawStorageis a generic implementation ofMappedRawStorage, keeping track of mappings betweenObjectKeys and the real file path on disk. This might be used for e.g. a Git repository where the file structure and contents don't follow a specific format, but mappings need to be registered separately.
Storage interfaces
"Generic" Storage interfaces deal with objects, this includes Storage, TransactionStorage and EventStorage.
- The
Storageinterface is a union of two smaller interfaces,ReadStorageandWriteStorage. It exposes CRUD operations likeGet,List,Create,Update,Delete. TransactionStorageextendsReadStoragewith aTransactionmethod, which temporarily gives access to also theWriteStoragepart when the transaction is active.EventStorageallows the user to subscribe to object events arising from changes by other actors in the system, e.g. a new object was added, or that someone changed or deleted some other object.
Storage implementations
"High-level" Storage implementations bind together multiple Storages, this includes GenericWatchStorage,
GitStorage and ManifestStorage.
GenericStorageis a generic implementation ofStorage, using the givenRawStorageandSerializerto provide object operations to the user.GenericWatchStorageis an implementation ofEventStorage, using inotify to watch a directory on disk. It sends update events to a registered channel. It is a superset of and extends a givenStorage.GitStoragetakes in aGitDirectoryaPullRequestProviderand aSerializer. It watches for new commits automatically pulled by theGitDirectory, and re-syncs the underlyingGenericMappedRawStorage. It implements theTransactionStorageinterface, and when the transaction is active, allows writing which then yields a new branch and commit, pushed to the origin. Lastly, it can, using thePullRequestProvidercreate a Pull Request for the branch. In the future, it should also implementEventStorage.ManifestStoragewatches a directory on disk usingGenericWatchStorage, uses aGenericStoragefor object operations, and aGenericMappedRawStoragefor files. Using it, implementingEventStorage, you can subscribe to file update/create/delete events in a given directory, e.g. a cloned Git repository or "manifest directory".
Example on how the storages interact:


See the pkg/storage package for details.
The filtering framework - pkg/filter
The filtering framework provides interfaces for pkg/runtime.Object filters and provides some basic filter
implementations. These are used in conjunction with storages when running Storage.Find and Storage.List calls.
There are two interfaces:
ListFilterdescribes a filter implementation that filters out objects from a given list, like a UNIX pipe.ObjectFilterdescribes a filter implementation returning a boolean for if a single given object is a match.
There is an ObjectToListFilter helper provided for easily creating ListFilters out of simpler ObjectFilters.
See the pkg/filter package for details.
The GitDirectory - pkg/gitdir
The GitDirectory is an abstraction layer for a temporary Git clone. It pulls and checks out new changes periodically
in the background. It allows high-level access to write operations like creating a new branch, committing, and pushing.
It is currently utilizing some functionality from go-git-providers, but should be refactored to utilize it more thoroughly. See weaveworks/libgitops#38 for more details regarding the integration.
See the pkg/gitdir package for details.
Utilities - pkg/util
This package contains utilities used by the rest of the library. The most interesting thing here is the Patcher
under pkg/util/patch, which can be used to apply patches to pkg/runtime.Object compliant types.
Sample implementations
All sample binaries in this repo are operating on a sample type called Car, that looks something like this:
apiVersion: sample-app.weave.works/v1alpha1
kind: Car
metadata:
creationTimestamp: "2020-08-17T14:33:16Z"
name: foo
namespace: default
spec:
brand: SAAB
engine: The best one
yearModel: "2008"
status:
acceleration: 0
distance: 12176941420362965433
persons: 0
speed: 53.37474583162469
All binaries let you access the data and fake a modification event using a sample webserver running on localhost:8888.
sample-gitops
This is a sample binary that:
a) clones a Git repo of your choice to a temporary directory, and authenticates using given id_rsa and known_hosts files. Create a Git repo with e.g. the sample file above, and set up SSH credentials.
b) exposes all Cars in your Git repository at URL GET localhost:8888/git/
c) lets you fake a "reconciler spec/status write" event at path PUT localhost:8888/git/<name>, where name is the name of the Car in your repo you want to modify
d) re-syncs every 10 seconds, and tries to pull the git repo
e) has an inotify watch on the temporary Git clone, so it will log all objects that have been changed as they happen in Git (e.g. from new commits)
When you modify the "desired state/current status" using e.g. curl -sSL -X PUT localhost:8888/git/foo, the following will happen:
a) a Transaction will be started, which means git pull and git checkout -b <name>-update-<random_sha> will be executed
b) Storage.Get for the Car with the given name will be requested
c) the Car's .status.distance and .status.speed fields are updated to random numbers, and Storage.Update is run
d) the transaction is "committed" by returning a transaction.PullRequestResult
e) when the transaction ends, git commit -A -m <message>, git push and git checkout <main> will be executed. The git pull loop is resumed.
f) as a `transaction.PullRequ
Related Skills
apple-reminders
342.5kManage Apple Reminders via remindctl CLI (list, add, edit, complete, delete). Supports lists, date filters, and JSON/plain output.
gh-issues
342.5kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
healthcheck
342.5kHost security hardening and risk-tolerance configuration for OpenClaw deployments
node-connect
342.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
