diff --git a/core/installer/soft/client.go b/core/installer/soft/client.go
index ae1206d..269f3d3 100644
--- a/core/installer/soft/client.go
+++ b/core/installer/soft/client.go
@@ -19,21 +19,36 @@
 	"github.com/go-git/go-git/v5/storage/memory"
 )
 
-type Client struct {
-	Addr     string
-	Signer   ssh.Signer
+type Client interface {
+	Address() string
+	Signer() ssh.Signer
+	GetPublicKeys() ([]string, error)
+	GetRepo(name string) (RepoIO, error)
+	GetRepoAddress(name string) string
+	AddRepository(name string) error
+	AddUser(name, pubKey string) error
+	AddPublicKey(user string, pubKey string) error
+	RemovePublicKey(user string, pubKey string) error
+	MakeUserAdmin(name string) error
+	AddReadWriteCollaborator(repo, user string) error
+	AddReadOnlyCollaborator(repo, user string) error
+}
+
+type realClient struct {
+	addr     string
+	signer   ssh.Signer
 	log      *log.Logger
 	pemBytes []byte
 }
 
-func NewClient(addr string, clientPrivateKey []byte, log *log.Logger) (*Client, error) {
+func NewClient(addr string, clientPrivateKey []byte, log *log.Logger) (Client, error) {
 	signer, err := ssh.ParsePrivateKey(clientPrivateKey)
 	if err != nil {
 		return nil, err
 	}
 	log.SetPrefix("SOFT-SERVE: ")
 	log.Printf("Created signer")
-	return &Client{
+	return &realClient{
 		addr,
 		signer,
 		log,
@@ -41,8 +56,14 @@
 	}, nil
 }
 
-func WaitForClient(addr string, clientPrivateKey []byte, log *log.Logger) (*Client, error) {
-	var client *Client
+type ClientGetter interface {
+	Get(addr string, clientPrivateKey []byte, log *log.Logger) (Client, error)
+}
+
+type RealClientGetter struct{}
+
+func (c RealClientGetter) Get(addr string, clientPrivateKey []byte, log *log.Logger) (Client, error) {
+	var client Client
 	err := backoff.RetryNotify(func() error {
 		var err error
 		client, err = NewClient(addr, clientPrivateKey, log)
@@ -59,7 +80,15 @@
 	return client, err
 }
 
-func (ss *Client) AddUser(name, pubKey string) error {
+func (ss *realClient) Address() string {
+	return ss.addr
+}
+
+func (ss *realClient) Signer() ssh.Signer {
+	return ss.signer
+}
+
+func (ss *realClient) AddUser(name, pubKey string) error {
 	log.Printf("Adding user %s", name)
 	if err := ss.RunCommand("user", "create", name); err != nil {
 		return err
@@ -67,25 +96,25 @@
 	return ss.AddPublicKey(name, pubKey)
 }
 
-func (ss *Client) MakeUserAdmin(name string) error {
+func (ss *realClient) MakeUserAdmin(name string) error {
 	log.Printf("Making user %s admin", name)
 	return ss.RunCommand("user", "set-admin", name, "true")
 }
 
-func (ss *Client) AddPublicKey(user string, pubKey string) error {
+func (ss *realClient) AddPublicKey(user string, pubKey string) error {
 	log.Printf("Adding public key: %s %s\n", user, pubKey)
 	return ss.RunCommand("user", "add-pubkey", user, pubKey)
 }
 
-func (ss *Client) RemovePublicKey(user string, pubKey string) error {
+func (ss *realClient) RemovePublicKey(user string, pubKey string) error {
 	log.Printf("Removing public key: %s %s\n", user, pubKey)
 	return ss.RunCommand("user", "remove-pubkey", user, pubKey)
 }
 
-func (ss *Client) RunCommand(args ...string) error {
+func (ss *realClient) RunCommand(args ...string) error {
 	cmd := strings.Join(args, " ")
 	log.Printf("Running command %s", cmd)
-	client, err := ssh.Dial("tcp", ss.Addr, ss.sshClientConfig())
+	client, err := ssh.Dial("tcp", ss.addr, ss.sshClientConfig())
 	if err != nil {
 		return err
 	}
@@ -100,17 +129,17 @@
 	return session.Run(cmd)
 }
 
-func (ss *Client) AddRepository(name string) error {
+func (ss *realClient) AddRepository(name string) error {
 	log.Printf("Adding repository %s", name)
 	return ss.RunCommand("repo", "create", name)
 }
 
-func (ss *Client) AddReadWriteCollaborator(repo, user string) error {
+func (ss *realClient) AddReadWriteCollaborator(repo, user string) error {
 	log.Printf("Adding read-write collaborator %s %s", repo, user)
 	return ss.RunCommand("repo", "collab", "add", repo, user, "read-write")
 }
 
-func (ss *Client) AddReadOnlyCollaborator(repo, user string) error {
+func (ss *realClient) AddReadOnlyCollaborator(repo, user string) error {
 	log.Printf("Adding read-only collaborator %s %s", repo, user)
 	return ss.RunCommand("repo", "collab", "add", repo, user, "read-only")
 }
@@ -120,8 +149,12 @@
 	Addr RepositoryAddress
 }
 
-func (ss *Client) GetRepo(name string) (*Repository, error) {
-	return CloneRepository(RepositoryAddress{ss.Addr, name}, ss.Signer)
+func (ss *realClient) GetRepo(name string) (RepoIO, error) {
+	r, err := CloneRepository(RepositoryAddress{ss.addr, name}, ss.signer)
+	if err != nil {
+		return nil, err
+	}
+	return NewRepoIO(r, ss.signer)
 }
 
 type RepositoryAddress struct {
@@ -172,7 +205,7 @@
 }
 
 // TODO(giolekva): dead code
-func (ss *Client) authSSH() gitssh.AuthMethod {
+func (ss *realClient) authSSH() gitssh.AuthMethod {
 	a, err := gitssh.NewPublicKeys("git", ss.pemBytes, "")
 	if err != nil {
 		panic(err)
@@ -196,10 +229,10 @@
 	// }
 }
 
-func (ss *Client) authGit() *gitssh.PublicKeys {
+func (ss *realClient) authGit() *gitssh.PublicKeys {
 	return &gitssh.PublicKeys{
 		User:   "git",
-		Signer: ss.Signer,
+		Signer: ss.signer,
 		HostKeyCallbackHelper: gitssh.HostKeyCallbackHelper{
 			HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
 				// TODO(giolekva): verify server public key
@@ -210,18 +243,18 @@
 	}
 }
 
-func (ss *Client) GetPublicKeys() ([]string, error) {
+func (ss *realClient) GetPublicKeys() ([]string, error) {
 	var ret []string
 	config := &ssh.ClientConfig{
 		Auth: []ssh.AuthMethod{
-			ssh.PublicKeys(ss.Signer),
+			ssh.PublicKeys(ss.signer),
 		},
 		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
 			ret = append(ret, string(ssh.MarshalAuthorizedKey(key)))
 			return nil
 		},
 	}
-	client, err := ssh.Dial("tcp", ss.Addr, config)
+	client, err := ssh.Dial("tcp", ss.addr, config)
 	if err != nil {
 		return nil, err
 	}
@@ -229,10 +262,10 @@
 	return ret, nil
 }
 
-func (ss *Client) sshClientConfig() *ssh.ClientConfig {
+func (ss *realClient) sshClientConfig() *ssh.ClientConfig {
 	return &ssh.ClientConfig{
 		Auth: []ssh.AuthMethod{
-			ssh.PublicKeys(ss.Signer),
+			ssh.PublicKeys(ss.signer),
 		},
 		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
 			// TODO(giolekva): verify server public key
@@ -243,10 +276,10 @@
 	}
 }
 
-func (ss *Client) GetRepoAddress(name string) string {
+func (ss *realClient) GetRepoAddress(name string) string {
 	return fmt.Sprintf("%s/%s", ss.addressGit(), name)
 }
 
-func (ss *Client) addressGit() string {
-	return fmt.Sprintf("ssh://%s", ss.Addr)
+func (ss *realClient) addressGit() string {
+	return fmt.Sprintf("ssh://%s", ss.addr)
 }
diff --git a/core/installer/soft/repoio.go b/core/installer/soft/repoio.go
new file mode 100644
index 0000000..6a5097a
--- /dev/null
+++ b/core/installer/soft/repoio.go
@@ -0,0 +1,250 @@
+package soft
+
+import (
+	"encoding/json"
+	"errors"
+	"io"
+	"io/fs"
+	"io/ioutil"
+	"net"
+	"path/filepath"
+	"sync"
+	"time"
+
+	pio "github.com/giolekva/pcloud/core/installer/io"
+
+	"github.com/go-git/go-billy/v5"
+	"github.com/go-git/go-billy/v5/util"
+	"github.com/go-git/go-git/v5"
+	"github.com/go-git/go-git/v5/plumbing/object"
+	gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
+	"golang.org/x/crypto/ssh"
+	"sigs.k8s.io/yaml"
+)
+
+type RepoFS interface {
+	Reader(path string) (io.ReadCloser, error)
+	Writer(path string) (io.WriteCloser, error)
+	CreateDir(path string) error
+	RemoveDir(path string) error
+}
+
+type DoFn func(r RepoFS) (string, error)
+
+type doOptions struct {
+	NoCommit bool
+}
+
+type DoOption func(*doOptions)
+
+func WithNoCommit() DoOption {
+	return func(o *doOptions) {
+		o.NoCommit = true
+	}
+}
+
+type RepoIO interface {
+	RepoFS
+	FullAddress() string
+	Pull() error
+	CommitAndPush(message string) error
+	Do(op DoFn, opts ...DoOption) error
+}
+
+type repoFS struct {
+	fs billy.Filesystem
+}
+
+func NewBillyRepoFS(fs billy.Filesystem) RepoFS {
+	return &repoFS{fs}
+}
+
+func (r *repoFS) Reader(path string) (io.ReadCloser, error) {
+	return r.fs.Open(path)
+}
+
+func (r *repoFS) Writer(path string) (io.WriteCloser, error) {
+	if err := r.fs.MkdirAll(filepath.Dir(path), fs.ModePerm); err != nil {
+		return nil, err
+	}
+	return r.fs.Create(path)
+}
+
+func (r *repoFS) CreateDir(path string) error {
+	return r.fs.MkdirAll(path, fs.ModePerm)
+}
+
+func (r *repoFS) RemoveDir(path string) error {
+	if err := util.RemoveAll(r.fs, path); err != nil {
+		if errors.Is(err, fs.ErrNotExist) {
+			return nil
+		}
+		return err
+	}
+	return nil
+}
+
+type repoIO struct {
+	*repoFS
+	repo   *Repository
+	signer ssh.Signer
+	l      sync.Locker
+}
+
+func NewRepoIO(repo *Repository, signer ssh.Signer) (RepoIO, error) {
+	wt, err := repo.Worktree()
+	if err != nil {
+		return nil, err
+	}
+	return &repoIO{
+		&repoFS{wt.Filesystem},
+		repo,
+		signer,
+		&sync.Mutex{},
+	}, nil
+}
+
+func (r *repoIO) FullAddress() string {
+	return r.repo.Addr.FullAddress()
+}
+
+func (r *repoIO) Pull() error {
+	r.l.Lock()
+	defer r.l.Unlock()
+	return r.pullWithoutLock()
+}
+
+func (r *repoIO) pullWithoutLock() error {
+	wt, err := r.repo.Worktree()
+	if err != nil {
+		return nil
+	}
+	err = wt.Pull(&git.PullOptions{
+		Auth:  auth(r.signer),
+		Force: true,
+	})
+	if err == nil {
+		return nil
+	}
+	if errors.Is(err, git.NoErrAlreadyUpToDate) {
+		return nil
+	}
+	// TODO(gio): check `remote repository is empty`
+	return nil
+}
+
+func (r *repoIO) CommitAndPush(message string) error {
+	wt, err := r.repo.Worktree()
+	if err != nil {
+		return err
+	}
+	if err := wt.AddGlob("*"); err != nil {
+		return err
+	}
+	if _, err := wt.Commit(message, &git.CommitOptions{
+		Author: &object.Signature{
+			Name: "pcloud-installer",
+			When: time.Now(),
+		},
+	}); err != nil {
+		return err
+	}
+	return r.repo.Push(&git.PushOptions{
+		RemoteName: "origin",
+		Auth:       auth(r.signer),
+	})
+}
+
+func (r *repoIO) Do(op DoFn, opts ...DoOption) error {
+	r.l.Lock()
+	defer r.l.Unlock()
+	if err := r.pullWithoutLock(); err != nil {
+		return err
+	}
+	o := &doOptions{}
+	for _, i := range opts {
+		i(o)
+	}
+	if msg, err := op(r); err != nil {
+		return err
+	} else {
+		if !o.NoCommit {
+			return r.CommitAndPush(msg)
+		}
+	}
+	return nil
+}
+
+func auth(signer ssh.Signer) *gitssh.PublicKeys {
+	return &gitssh.PublicKeys{
+		Signer: signer,
+		HostKeyCallbackHelper: gitssh.HostKeyCallbackHelper{
+			HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
+				// TODO(giolekva): verify server public key
+				// fmt.Printf("## %s || %s -- \n", serverPubKey, ssh.MarshalAuthorizedKey(key))
+				return nil
+			},
+		},
+	}
+}
+
+func ReadYaml[T any](repo RepoFS, path string, o *T) error {
+	r, err := repo.Reader(path)
+	if err != nil {
+		return err
+	}
+	defer r.Close()
+	if contents, err := ioutil.ReadAll(r); err != nil {
+		return err
+	} else {
+		return yaml.UnmarshalStrict(contents, o)
+	}
+}
+
+func WriteYaml(repo RepoFS, path string, data any) error {
+	if d, ok := data.(*pio.Kustomization); ok {
+		data = d
+	}
+	out, err := repo.Writer(path)
+	if err != nil {
+		return err
+	}
+	serialized, err := yaml.Marshal(data)
+	if err != nil {
+		return err
+	}
+	if _, err := out.Write(serialized); err != nil {
+		return err
+	}
+	return nil
+}
+
+func ReadJson[T any](repo RepoFS, path string, o *T) error {
+	r, err := repo.Reader(path)
+	if err != nil {
+		return err
+	}
+	defer r.Close()
+	return json.NewDecoder(r).Decode(o)
+}
+
+func WriteJson(repo RepoFS, path string, data any) error {
+	if d, ok := data.(*pio.Kustomization); ok {
+		data = d
+	}
+	w, err := repo.Writer(path)
+	if err != nil {
+		return err
+	}
+	e := json.NewEncoder(w)
+	e.SetIndent("", "\t")
+	return e.Encode(data)
+}
+
+func ReadKustomization(repo RepoFS, path string) (*pio.Kustomization, error) {
+	ret := &pio.Kustomization{}
+	if err := ReadYaml(repo, path, &ret); err != nil {
+		return nil, err
+	}
+	return ret, nil
+}
