Add support for Git LFS enabled repositories (fixes #1853) (#1941)

* Add support for LFS enabled repositories
This commit is contained in:
jannfis 2019-07-18 21:49:49 +02:00 committed by Alexander Matyushentsev
parent 6049a49114
commit 8f3a6047b2
23 changed files with 581 additions and 391 deletions

View file

@ -151,6 +151,15 @@ commands:
sudo chmod +x /usr/local/bin/protoc
sudo unzip /tmp/dl/protoc.zip include/* -d /usr/local/
protoc --version
- run:
name: Install Git LFS plugin
command: |
set -x
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sleep 5
sudo killall -9 apt-get || true
sudo apt-get update
sudo apt-get install -y git-lfs openssh-client
- save_cache:
key: dl-v4
paths:

View file

@ -6,11 +6,14 @@ ARG BASE_IMAGE=debian:9.5-slim
####################################################################################################
FROM golang:1.12.6 as builder
RUN echo 'deb http://deb.debian.org/debian stretch-backports main' >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y \
openssh-server \
nginx \
fcgiwrap \
git \
git-lfs \
make \
wget \
gcc \
@ -101,12 +104,14 @@ FROM $BASE_IMAGE as argocd-base
USER root
RUN echo 'deb http://deb.debian.org/debian stretch-backports main' >> /etc/apt/sources.list
RUN groupadd -g 999 argocd && \
useradd -r -u 999 -g argocd argocd && \
mkdir -p /home/argocd && \
chown argocd:argocd /home/argocd && \
apt-get update && \
apt-get install -y git && \
apt-get install -y git git-lfs && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

1
Gopkg.lock generated
View file

@ -1606,7 +1606,6 @@
"github.com/gogo/protobuf/proto",
"github.com/gogo/protobuf/protoc-gen-gofast",
"github.com/gogo/protobuf/protoc-gen-gogofast",
"github.com/gogo/protobuf/sortkeys",
"github.com/golang/protobuf/proto",
"github.com/golang/protobuf/protoc-gen-go",
"github.com/golang/protobuf/ptypes/empty",

View file

@ -49,7 +49,7 @@
"ApplicationService"
],
"summary": "List returns list of applications",
"operationId": "ListMixin6",
"operationId": "ListMixin1",
"parameters": [
{
"type": "string",
@ -89,7 +89,7 @@
"ApplicationService"
],
"summary": "Create creates an application",
"operationId": "CreateMixin6",
"operationId": "CreateMixin1",
"parameters": [
{
"name": "body",
@ -116,7 +116,7 @@
"ApplicationService"
],
"summary": "Update updates an application",
"operationId": "UpdateMixin6",
"operationId": "UpdateMixin1",
"parameters": [
{
"type": "string",
@ -197,7 +197,7 @@
"ApplicationService"
],
"summary": "Get returns an application by name",
"operationId": "GetMixin6",
"operationId": "Get",
"parameters": [
{
"type": "string",
@ -238,7 +238,7 @@
"ApplicationService"
],
"summary": "Delete deletes an application",
"operationId": "DeleteMixin6",
"operationId": "DeleteMixin1",
"parameters": [
{
"type": "string",
@ -852,7 +852,7 @@
"ClusterService"
],
"summary": "List returns list of clusters",
"operationId": "List",
"operationId": "ListMixin3",
"parameters": [
{
"type": "string",
@ -874,7 +874,7 @@
"ClusterService"
],
"summary": "Create creates a cluster",
"operationId": "Create",
"operationId": "CreateMixin3",
"parameters": [
{
"name": "body",
@ -901,7 +901,7 @@
"ClusterService"
],
"summary": "Update updates a cluster",
"operationId": "Update",
"operationId": "UpdateMixin3",
"parameters": [
{
"type": "string",
@ -934,7 +934,7 @@
"ClusterService"
],
"summary": "Get returns a cluster by server address",
"operationId": "GetMixin1",
"operationId": "GetMixin3",
"parameters": [
{
"type": "string",
@ -957,7 +957,7 @@
"ClusterService"
],
"summary": "Delete deletes a cluster",
"operationId": "Delete",
"operationId": "DeleteMixin3",
"parameters": [
{
"type": "string",
@ -1239,7 +1239,7 @@
"RepositoryService"
],
"summary": "List returns list of repos",
"operationId": "ListMixin2",
"operationId": "List",
"parameters": [
{
"type": "string",
@ -1261,7 +1261,7 @@
"RepositoryService"
],
"summary": "Create creates a repo",
"operationId": "CreateMixin2",
"operationId": "Create",
"parameters": [
{
"name": "body",
@ -1288,7 +1288,7 @@
"RepositoryService"
],
"summary": "Update updates a repo",
"operationId": "UpdateMixin2",
"operationId": "Update",
"parameters": [
{
"type": "string",
@ -1321,7 +1321,7 @@
"RepositoryService"
],
"summary": "Delete deletes a repo",
"operationId": "DeleteMixin2",
"operationId": "Delete",
"parameters": [
{
"type": "string",
@ -1500,7 +1500,7 @@
"SettingsService"
],
"summary": "Get returns Argo CD settings",
"operationId": "Get",
"operationId": "GetMixin5",
"responses": {
"200": {
"description": "(empty)",
@ -3255,6 +3255,11 @@
"connectionState": {
"$ref": "#/definitions/v1alpha1ConnectionState"
},
"enableLfs": {
"type": "boolean",
"format": "boolean",
"title": "Whether git-lfs support should be enabled for this repo"
},
"insecure": {
"type": "boolean",
"format": "boolean",

View file

@ -43,6 +43,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
sshPrivateKeyPath string
insecureIgnoreHostKey bool
insecureSkipServerVerification bool
enableLfs bool
)
var command = &cobra.Command{
Use: "add REPO",
@ -63,6 +64,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
// InsecureIgnoreHostKey is deprecated and only here for backwards compat
repo.InsecureIgnoreHostKey = insecureIgnoreHostKey
repo.Insecure = insecureSkipServerVerification
repo.EnableLFS = enableLfs
conn, repoIf := argocdclient.NewClientOrDie(clientOpts).NewRepoClientOrDie()
defer util.Close(conn)
@ -100,6 +102,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
command.Flags().StringVar(&sshPrivateKeyPath, "ssh-private-key-path", "", "path to the private ssh key (e.g. ~/.ssh/id_rsa)")
command.Flags().BoolVar(&insecureIgnoreHostKey, "insecure-ignore-host-key", false, "disables SSH strict host key checking (deprecated, use --insecure-skip-server-validation instead)")
command.Flags().BoolVar(&insecureSkipServerVerification, "insecure-skip-server-verification", false, "disables server certificate and host key checks")
command.Flags().BoolVar(&enableLfs, "enable-lfs", false, "enable git-lfs (Large File Support) on this repository")
command.Flags().BoolVar(&upsert, "upsert", false, "Override an existing repository with the same name even if the spec differs")
return command
}
@ -128,7 +131,7 @@ func NewRepoRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
// Print table of repo info
func printRepoTable(repos []appsv1.Repository) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "REPO\tINSECURE\tUSER\tSTATUS\tMESSAGE\n")
fmt.Fprintf(w, "REPO\tINSECURE\tLFS\tUSER\tSTATUS\tMESSAGE\n")
for _, r := range repos {
var username string
if r.Username == "" {
@ -136,7 +139,7 @@ func printRepoTable(repos []appsv1.Repository) {
} else {
username = r.Username
}
fmt.Fprintf(w, "%s\t%v\t%s\t%s\t%s\n", r.Repo, r.Insecure, username, r.ConnectionState.Status, r.ConnectionState.Message)
fmt.Fprintf(w, "%s\t%v\t%v\t%s\t%s\t%s\n", r.Repo, r.IsInsecure(), r.EnableLFS, username, r.ConnectionState.Status, r.ConnectionState.Message)
}
_ = w.Flush()
}

View file

@ -2,6 +2,7 @@ API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,ConnectionState,ModifiedAt
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,JWTToken,ExpiresAt
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,JWTToken,IssuedAt
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,Repository,EnableLFS
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,RepositoryCertificate,CertData
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,RepositoryCertificate,CertFingerprint
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,RepositoryCertificate,CertSubType

File diff suppressed because it is too large Load diff

View file

@ -503,6 +503,9 @@ message Repository {
// Whether the repo is insecure
optional bool insecure = 7;
// Whether git-lfs support should be enabled for this repo
optional bool enableLfs = 8;
}
// A RepositoryCertificate is either SSH known hosts entry or TLS certificate

View file

@ -1796,6 +1796,13 @@ func schema_pkg_apis_application_v1alpha1_Repository(ref common.ReferenceCallbac
Format: "",
},
},
"enableLfs": {
SchemaProps: spec.SchemaProps{
Description: "Whether git-lfs support should be enabled for this repo",
Type: []string{"boolean"},
Format: "",
},
},
},
Required: []string{"repo"},
},

View file

@ -895,12 +895,18 @@ type Repository struct {
InsecureIgnoreHostKey bool `json:"insecureIgnoreHostKey,omitempty" protobuf:"bytes,6,opt,name=insecureIgnoreHostKey"`
// Whether the repo is insecure
Insecure bool `json:"insecure,omitempty" protobuf:"bytes,7,opt,name=insecure"`
// Whether git-lfs support should be enabled for this repo
EnableLFS bool `json:"enableLfs,omitempty" protobuf:"bytes,8,opt,name=enableLfs"`
}
func (repo *Repository) IsInsecure() bool {
return repo.InsecureIgnoreHostKey || repo.Insecure
}
func (repo *Repository) IsLFSEnabled() bool {
return repo.EnableLFS
}
func (m *Repository) HasCredentials() bool {
return m.Username != "" || m.Password != "" || m.SSHPrivateKey != "" || m.InsecureIgnoreHostKey
}
@ -912,6 +918,7 @@ func (m *Repository) CopyCredentialsFrom(source *Repository) {
m.SSHPrivateKey = source.SSHPrivateKey
m.InsecureIgnoreHostKey = source.InsecureIgnoreHostKey
m.Insecure = source.Insecure
m.EnableLFS = source.EnableLFS
}
}

View file

@ -30,6 +30,10 @@ func (w *gitClientWrapper) LsFiles(path string) ([]string, error) {
return w.client.LsFiles(path)
}
func (w *gitClientWrapper) LsLargeFiles() ([]string, error) {
return w.client.LsLargeFiles()
}
func (w *gitClientWrapper) Checkout(revision string) error {
return w.client.Checkout(revision)
}

View file

@ -53,8 +53,8 @@ func (m *MetricsServer) IncGitRequest(repo string, requestType GitRequestType) {
m.gitRequestCounter.WithLabelValues(repo, string(requestType)).Inc()
}
func (m *MetricsServer) NewClient(repoURL string, path string, creds git.Creds, insecureIgnoreHostKey bool) (git.Client, error) {
client, err := m.gitClientFactory.NewClient(repoURL, path, creds, insecureIgnoreHostKey)
func (m *MetricsServer) NewClient(repoURL string, path string, creds git.Creds, insecureIgnoreHostKey bool, lfsEnabled bool) (git.Client, error) {
client, err := m.gitClientFactory.NewClient(repoURL, path, creds, insecureIgnoreHostKey, lfsEnabled)
if err != nil {
return nil, err
}

View file

@ -526,7 +526,7 @@ func (s *Service) newClientResolveRevision(repo *v1alpha1.Repository, revision s
func (s *Service) newClient(repo *v1alpha1.Repository) (git.Client, error) {
appPath := tempRepoPath(git.NormalizeGitURL(repo.Repo))
return s.gitFactory.NewClient(repo.Repo, appPath, argo.GetRepoCreds(repo), repo.IsInsecure())
return s.gitFactory.NewClient(repo.Repo, appPath, argo.GetRepoCreds(repo), repo.IsInsecure(), repo.EnableLFS)
}
func runCommand(command v1alpha1.Command, path string, env []string) (string, error) {

View file

@ -46,7 +46,7 @@ type fakeGitClientFactory struct {
revisionMetadata *git.RevisionMetadata
}
func (f *fakeGitClientFactory) NewClient(repoURL string, path string, creds git.Creds, insecureIgnoreHostKey bool) (git.Client, error) {
func (f *fakeGitClientFactory) NewClient(repoURL string, path string, creds git.Creds, insecureIgnoreHostKey bool, enableLfs bool) (git.Client, error) {
mockClient := gitmocks.Client{}
root := "./testdata"
if f.root != "" {

View file

@ -962,7 +962,7 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy
if err != nil {
return "", "", err
}
gitClient, err := s.gitFactory.NewClient(repo.Repo, "", argoutil.GetRepoCreds(repo), repo.IsInsecure())
gitClient, err := s.gitFactory.NewClient(repo.Repo, "", argoutil.GetRepoCreds(repo), repo.IsInsecure(), repo.IsLFSEnabled())
if err != nil {
return "", "", err
}

View file

@ -60,7 +60,7 @@ func (s *Server) getConnectionState(ctx context.Context, url string) appsv1.Conn
}
repo, err := s.db.GetRepository(ctx, url)
if err == nil {
err = git.TestRepo(repo.Repo, argo.GetRepoCreds(repo), repo.IsInsecure())
err = git.TestRepo(repo.Repo, argo.GetRepoCreds(repo), repo.IsInsecure(), repo.EnableLFS)
}
if err != nil {
connectionState.Status = appsv1.ConnectionStatusFailed
@ -86,7 +86,12 @@ func (s *Server) List(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.
if err != nil {
return nil, err
}
items = append(items, appsv1.Repository{Repo: url, Insecure: repo.IsInsecure(), Username: repo.Username})
items = append(items, appsv1.Repository{
Repo: url,
Username: repo.Username,
Insecure: repo.IsInsecure(),
EnableLFS: repo.EnableLFS,
})
}
}
err = util.RunAllAsync(len(items), func(i int) error {
@ -228,7 +233,7 @@ func (s *Server) Create(ctx context.Context, q *repositorypkg.RepoCreateRequest)
return nil, err
}
r := q.Repo
err := git.TestRepo(r.Repo, argo.GetRepoCreds(r), r.IsInsecure())
err := git.TestRepo(r.Repo, argo.GetRepoCreds(r), r.IsInsecure(), r.EnableLFS)
if err != nil {
return nil, err
}
@ -287,7 +292,7 @@ func (s *Server) ValidateAccess(ctx context.Context, q *repositorypkg.RepoAccess
}
repo := &appsv1.Repository{Username: q.Username, Password: q.Password, SSHPrivateKey: q.SshPrivateKey, Insecure: q.Insecure}
err := git.TestRepo(q.Repo, argo.GetRepoCreds(repo), q.Insecure)
err := git.TestRepo(q.Repo, argo.GetRepoCreds(repo), q.Insecure, false)
if err != nil {
return nil, err
}

View file

@ -179,7 +179,7 @@ func ValidateRepo(ctx context.Context, spec *argoappv1.ApplicationSpec, repoClie
return nil, "", err
}
err = git.TestRepo(repoRes.Repo, GetRepoCreds(repoRes), repoRes.IsInsecure())
err = git.TestRepo(repoRes.Repo, GetRepoCreds(repoRes), repoRes.IsInsecure(), repoRes.EnableLFS)
if err != nil {
conditions = append(conditions, argoappv1.ApplicationCondition{
Type: argoappv1.ApplicationConditionInvalidSpecError,

View file

@ -64,8 +64,9 @@ func (db *db) CreateRepository(ctx context.Context, r *appsv1.Repository) (*apps
repoInfo := settings.RepoCredentials{
URL: r.Repo,
InsecureIgnoreHostKey: (r.InsecureIgnoreHostKey || r.Insecure),
Insecure: (r.InsecureIgnoreHostKey || r.Insecure),
InsecureIgnoreHostKey: r.IsInsecure(),
Insecure: r.IsInsecure(),
EnableLFS: r.EnableLFS,
}
err = db.updateSecrets(&repoInfo, r)
if err != nil {
@ -123,6 +124,7 @@ func (db *db) credentialsToRepository(repoInfo settings.RepoCredentials) (*appsv
Repo: repoInfo.URL,
InsecureIgnoreHostKey: repoInfo.InsecureIgnoreHostKey,
Insecure: repoInfo.Insecure,
EnableLFS: repoInfo.EnableLFS,
}
err := db.unmarshalFromSecretsStr(map[*string]*apiv1.SecretKeySelector{
&repo.Username: repoInfo.UsernameSecret,
@ -150,6 +152,12 @@ func (db *db) UpdateRepository(ctx context.Context, r *appsv1.Repository) (*apps
if err != nil {
return nil, err
}
// Update boolean settings
repoInfo.InsecureIgnoreHostKey = r.IsInsecure()
repoInfo.Insecure = r.IsInsecure()
repoInfo.EnableLFS = r.EnableLFS
repos[index] = repoInfo
err = db.settingsMgr.SaveRepositories(repos)
if err != nil {

View file

@ -41,6 +41,7 @@ type Client interface {
Checkout(revision string) error
LsRemote(revision string) (string, error)
LsFiles(path string) ([]string, error)
LsLargeFiles() ([]string, error)
CommitSHA() (string, error)
RevisionMetadata(revision string) (*RevisionMetadata, error)
}
@ -48,7 +49,7 @@ type Client interface {
// ClientFactory is a factory of Git Clients
// Primarily used to support creation of mock git clients during unit testing
type ClientFactory interface {
NewClient(rawRepoURL string, path string, creds Creds, insecure bool) (Client, error)
NewClient(rawRepoURL string, path string, creds Creds, insecure bool, enableLfs bool) (Client, error)
}
// nativeGitClient implements Client interface using git CLI
@ -61,6 +62,8 @@ type nativeGitClient struct {
creds Creds
// Whether to connect insecurely to repository, e.g. don't verify certificate
insecure bool
// Whether the repository is LFS enabled
enableLfs bool
}
type factory struct{}
@ -69,20 +72,13 @@ func NewFactory() ClientFactory {
return &factory{}
}
func (f *factory) NewClient(rawRepoURL string, path string, creds Creds, insecure bool) (Client, error) {
// We need a custom HTTP client for go-git when we want to skip validation
// of the server's TLS certificate (--insecure-ignore-server-cert). Since
// this change is permanent to go-git Client during runtime, we need to
// explicitly replace it with default client for repositories without the
// insecure flag set.
//if IsHTTPSURL(rawRepoURL) {
// gitclient.InstallProtocol("https", githttp.NewClient(getRepoHTTPClient(rawRepoURL, insecure)))
//}
func (f *factory) NewClient(rawRepoURL string, path string, creds Creds, insecure bool, enableLfs bool) (Client, error) {
client := nativeGitClient{
repoURL: rawRepoURL,
root: path,
creds: creds,
insecure: insecure,
repoURL: rawRepoURL,
root: path,
creds: creds,
insecure: insecure,
enableLfs: enableLfs,
}
return &client, nil
}
@ -200,9 +196,24 @@ func (m *nativeGitClient) Init() error {
return err
}
// Returns true if the repository is LFS enabled
func (m *nativeGitClient) IsLFSEnabled() bool {
return m.enableLfs
}
// Fetch fetches latest updates from origin
func (m *nativeGitClient) Fetch() error {
_, err := m.runCredentialedCmd("git", "fetch", "origin", "--tags", "--force")
// When we have LFS support enabled, check for large files and fetch them too.
if err == nil && m.IsLFSEnabled() {
largeFiles, err := m.LsLargeFiles()
if err == nil && len(largeFiles) > 0 {
_, err = m.runCredentialedCmd("git", "lfs", "fetch", "--all")
if err != nil {
return err
}
}
}
return err
}
@ -217,6 +228,16 @@ func (m *nativeGitClient) LsFiles(path string) ([]string, error) {
return ss[:len(ss)-1], nil
}
// LsLargeFiles lists all files that have references to LFS storage
func (m *nativeGitClient) LsLargeFiles() ([]string, error) {
out, err := m.runCmd("lfs", "ls-files", "-n")
if err != nil {
return nil, err
}
ss := strings.Split(out, "\n")
return ss, nil
}
// Checkout checkout specified git sha
func (m *nativeGitClient) Checkout(revision string) error {
if revision == "" || revision == "HEAD" {
@ -225,6 +246,19 @@ func (m *nativeGitClient) Checkout(revision string) error {
if _, err := m.runCmd("checkout", "--force", revision); err != nil {
return err
}
// We must populate LFS content by using lfs checkout, if we have at least
// one LFS reference in the current revision.
if m.IsLFSEnabled() {
if largeFiles, err := m.LsLargeFiles(); err == nil {
if len(largeFiles) > 0 {
if _, err := m.runCmd("lfs", "checkout"); err != nil {
return err
}
}
} else {
return err
}
}
if _, err := m.runCmd("clean", "-fdx"); err != nil {
return err
}
@ -361,9 +395,12 @@ func (m *nativeGitClient) runCredentialedCmd(command string, args ...string) (st
func (m *nativeGitClient) runCmdOutput(cmd *exec.Cmd) (string, error) {
cmd.Dir = m.root
cmd.Env = append(cmd.Env, os.Environ()...)
// Set $HOME to nowhere, so we can be execute Git regardless of any external
// authentication keys (e.g. in ~/.ssh) -- this is especially important for
// running tests on local machines and/or CircleCI.
cmd.Env = append(cmd.Env, "HOME=/dev/null")
cmd.Env = append(cmd.Env, "GIT_CONFIG_NOSYSTEM=true")
cmd.Env = append(cmd.Env, "GIT_CONFIG_NOGLOBAL=true")
// Skip LFS for most Git operations except when explicitly requested
cmd.Env = append(cmd.Env, "GIT_LFS_SKIP_SMUDGE=1")
log.Debug(strings.Join(cmd.Args, " "))
return argoexec.RunCommandExt(cmd, argoconfig.CmdOpts())
}

View file

@ -78,8 +78,8 @@ func IsHTTPSURL(url string) bool {
}
// TestRepo tests if a repo exists and is accessible with the given credentials
func TestRepo(repo string, creds Creds, insecure bool) error {
clnt, err := NewFactory().NewClient(repo, "", creds, insecure)
func TestRepo(repo string, creds Creds, insecure bool, enableLfs bool) error {
clnt, err := NewFactory().NewClient(repo, "", creds, insecure, enableLfs)
if err != nil {
return err
}

View file

@ -1,6 +1,7 @@
package git
import (
"fmt"
"io/ioutil"
"os"
"testing"
@ -107,7 +108,7 @@ func TestSameURL(t *testing.T) {
}
func TestLsRemote(t *testing.T) {
clnt, err := NewFactory().NewClient("https://github.com/argoproj/argo-cd.git", "/tmp", NopCreds{}, false)
clnt, err := NewFactory().NewClient("https://github.com/argoproj/argo-cd.git", "/tmp", NopCreds{}, false, false)
assert.NoError(t, err)
xpass := []string{
"HEAD",
@ -139,6 +140,46 @@ func TestLsRemote(t *testing.T) {
}
}
// Running this test requires git-lfs to be installed on your machine.
func TestLFSClient(t *testing.T) {
tempDir, err := ioutil.TempDir("", "git-client-lfs-test-")
assert.NoError(t, err)
if err == nil {
defer func() { _ = os.RemoveAll(tempDir) }()
}
client, err := NewFactory().NewClient("https://github.com/argoproj-labs/argocd-testrepo-lfs", tempDir, NopCreds{}, false, true)
assert.NoError(t, err)
commitSHA, err := client.LsRemote("HEAD")
assert.NoError(t, err)
assert.NotEqual(t, "", commitSHA)
err = client.Init()
assert.NoError(t, err)
err = client.Fetch()
assert.NoError(t, err)
err = client.Checkout(commitSHA)
assert.NoError(t, err)
largeFiles, err := client.LsLargeFiles()
assert.NoError(t, err)
assert.Equal(t, 3, len(largeFiles))
fileHandle, err := os.Open(fmt.Sprintf("%s/test3.yaml", tempDir))
assert.NoError(t, err)
if err == nil {
defer fileHandle.Close()
text, err := ioutil.ReadAll(fileHandle)
assert.NoError(t, err)
if err == nil {
assert.Equal(t, "This is not a YAML, sorry.\n", string(text))
}
}
}
func TestNewFactory(t *testing.T) {
addBinDirToPath := path.NewBinDirToPath()
defer addBinDirToPath.Close()
@ -166,7 +207,7 @@ func TestNewFactory(t *testing.T) {
assert.NoError(t, err)
defer func() { _ = os.RemoveAll(dirName) }()
client, err := NewFactory().NewClient(tt.args.url, dirName, NopCreds{}, tt.args.insecureIgnoreHostKey)
client, err := NewFactory().NewClient(tt.args.url, dirName, NopCreds{}, tt.args.insecureIgnoreHostKey, false)
assert.NoError(t, err)
commitSHA, err := client.LsRemote("HEAD")
assert.NoError(t, err)

View file

@ -96,6 +96,29 @@ func (_m *Client) LsFiles(path string) ([]string, error) {
return r0, r1
}
// LsLargeFiles provides a mock function with given fields:
func (_m *Client) LsLargeFiles() ([]string, error) {
ret := _m.Called()
var r0 []string
if rf, ok := ret.Get(0).(func() []string); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// LsRemote provides a mock function with given fields: revision
func (_m *Client) LsRemote(revision string) (string, error) {
ret := _m.Called(revision)

View file

@ -94,6 +94,8 @@ type RepoCredentials struct {
InsecureIgnoreHostKey bool `json:"insecureIgnoreHostKey,omitempty"`
// Whether to connect the repository in an insecure way
Insecure bool `json:"insecure,omitempty"`
// Whether the repo is git-lfs enabled
EnableLFS bool `json:"enableLfs,omitempty"`
}
type HelmRepoCredentials struct {