Test SSH as well as HTTP access to git
This commit rearranges update tests so that those that check that updates are made can be run against a git server using SSH as well as HTTP. The local clone, used to provoke automated updates and to check results, still uses HTTP. Those operations are not under test. libgit2 wants to be asked for authentication when using SSH, and will balk if it's not requested by the server. To avoid that, auth must be switched on for the git test server. This also switches auth on for HTTP, so it's necessary to use a git URL that includes credentials for setting things up with a local clone. I have also used that URL for the git-over-HTTP tests -- it's arguable whether it's necessary to test that works, here. Signed-off-by: Michael Bridgen <michael@weave.works>
This commit is contained in:
parent
5d9f0f9958
commit
172dec486c
|
|
@ -53,8 +53,8 @@ import (
|
|||
"github.com/fluxcd/pkg/runtime/metrics"
|
||||
"github.com/fluxcd/pkg/runtime/predicates"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
gitstrat "github.com/fluxcd/source-controller/pkg/git"
|
||||
git "github.com/fluxcd/source-controller/pkg/git/common"
|
||||
git "github.com/fluxcd/source-controller/pkg/git"
|
||||
gitstrat "github.com/fluxcd/source-controller/pkg/git/strategy"
|
||||
|
||||
imagev1 "github.com/fluxcd/image-automation-controller/api/v1alpha1"
|
||||
"github.com/fluxcd/image-automation-controller/pkg/update"
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-git/go-billy/v5/memfs"
|
||||
|
|
@ -46,6 +48,7 @@ import (
|
|||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1alpha1"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
"github.com/fluxcd/pkg/gittestserver"
|
||||
"github.com/fluxcd/pkg/ssh"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
|
||||
imagev1 "github.com/fluxcd/image-automation-controller/api/v1alpha1"
|
||||
|
|
@ -69,12 +72,11 @@ func randStringRunes(n int) string {
|
|||
|
||||
var _ = Describe("ImageUpdateAutomation", func() {
|
||||
var (
|
||||
impl string
|
||||
branch string
|
||||
repositoryPath string
|
||||
repoURL string
|
||||
namespace *corev1.Namespace
|
||||
gitServer *gittestserver.GitServer
|
||||
branch string
|
||||
repositoryPath string
|
||||
namespace *corev1.Namespace
|
||||
username, password string
|
||||
gitServer *gittestserver.GitServer
|
||||
)
|
||||
|
||||
// Start the git server
|
||||
|
|
@ -89,10 +91,15 @@ var _ = Describe("ImageUpdateAutomation", func() {
|
|||
var err error
|
||||
gitServer, err = gittestserver.NewTempGitServer()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
username = randStringRunes(5)
|
||||
password = randStringRunes(5)
|
||||
// using authentication makes using the server more fiddly in
|
||||
// general, but is required for testing SSH.
|
||||
gitServer.Auth(username, password)
|
||||
gitServer.AutoCreate()
|
||||
Expect(gitServer.StartHTTP()).To(Succeed())
|
||||
|
||||
repoURL = gitServer.HTTPAddress() + repositoryPath
|
||||
gitServer.KeyDir(filepath.Join(gitServer.Root(), "keys"))
|
||||
Expect(gitServer.ListenSSH()).To(Succeed())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
|
|
@ -104,8 +111,20 @@ var _ = Describe("ImageUpdateAutomation", func() {
|
|||
Expect(initGitRepo(gitServer, "testdata/appconfig", branch, repositoryPath)).To(Succeed())
|
||||
})
|
||||
|
||||
// These are used for end-to-end tests; withImagePolicy is
|
||||
// effectively parameterised on these two values.
|
||||
var (
|
||||
// set the proto and impl in BeforeEach
|
||||
proto string
|
||||
impl string
|
||||
)
|
||||
|
||||
withImagePolicy := func() {
|
||||
var (
|
||||
// for cloning locally
|
||||
cloneLocalRepoURL string
|
||||
// for the controller
|
||||
repoURL string
|
||||
localRepo *git.Repository
|
||||
policy *imagev1_reflect.ImagePolicy
|
||||
policyKey types.NamespacedName
|
||||
|
|
@ -117,13 +136,31 @@ var _ = Describe("ImageUpdateAutomation", func() {
|
|||
const evenLatestImage = "helloworld:1.2.0"
|
||||
|
||||
BeforeEach(func() {
|
||||
cloneLocalRepoURL = gitServer.HTTPAddressWithCredentials() + repositoryPath
|
||||
if proto == "http" {
|
||||
repoURL = cloneLocalRepoURL // NB not testing auth for git over HTTP
|
||||
} else if proto == "ssh" {
|
||||
sshURL := gitServer.SSHAddress()
|
||||
// this is expected to use 127.0.0.1, but host key
|
||||
// checking usually wants a hostname, so use
|
||||
// "localhost".
|
||||
sshURL = strings.Replace(sshURL, "127.0.0.1", "localhost", 1)
|
||||
repoURL = sshURL + repositoryPath
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
gitServer.StartSSH()
|
||||
}()
|
||||
} else {
|
||||
Fail("proto not set to http or ssh")
|
||||
}
|
||||
|
||||
commitMessage = "Commit a difference " + randStringRunes(5)
|
||||
|
||||
Expect(initGitRepo(gitServer, "testdata/appconfig", branch, repositoryPath)).To(Succeed())
|
||||
|
||||
var err error
|
||||
localRepo, err = git.Clone(memory.NewStorage(), memfs.New(), &git.CloneOptions{
|
||||
URL: repoURL,
|
||||
URL: cloneLocalRepoURL,
|
||||
RemoteName: "origin",
|
||||
ReferenceName: plumbing.NewBranchReferenceName(branch),
|
||||
})
|
||||
|
|
@ -145,6 +182,31 @@ var _ = Describe("ImageUpdateAutomation", func() {
|
|||
GitImplementation: impl,
|
||||
},
|
||||
}
|
||||
|
||||
// If using SSH, we need to provide an identity (private
|
||||
// key) and known_hosts file in a secret.
|
||||
if proto == "ssh" {
|
||||
url, err := url.Parse(repoURL)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
knownhosts, err := ssh.ScanHostKey(url.Host, 5*time.Second)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
keygen := ssh.NewRSAGenerator(2048)
|
||||
pair, err := keygen.Generate()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
sec := &corev1.Secret{
|
||||
StringData: map[string]string{
|
||||
"known_hosts": string(knownhosts),
|
||||
"identity": string(pair.PrivateKey),
|
||||
"identity.pub": string(pair.PublicKey),
|
||||
},
|
||||
}
|
||||
sec.Name = "git-secret-" + randStringRunes(5)
|
||||
sec.Namespace = namespace.Name
|
||||
Expect(k8sClient.Create(context.Background(), sec)).To(Succeed())
|
||||
gitRepo.Spec.SecretRef = &meta.LocalObjectReference{Name: sec.Name}
|
||||
}
|
||||
|
||||
Expect(k8sClient.Create(context.Background(), gitRepo)).To(Succeed())
|
||||
|
||||
policyKey = types.NamespacedName{
|
||||
|
|
@ -180,6 +242,7 @@ var _ = Describe("ImageUpdateAutomation", func() {
|
|||
AfterEach(func() {
|
||||
Expect(k8sClient.Delete(context.Background(), namespace)).To(Succeed())
|
||||
Expect(k8sClient.Delete(context.Background(), policy)).To(Succeed())
|
||||
Expect(gitServer.StopSSH()).To(Succeed())
|
||||
})
|
||||
|
||||
Context("defaulting", func() {
|
||||
|
|
@ -234,7 +297,7 @@ var _ = Describe("ImageUpdateAutomation", func() {
|
|||
BeforeEach(func() {
|
||||
// Insert a setter reference into the deployment file,
|
||||
// before creating the automation object itself.
|
||||
commitInRepo(repoURL, branch, "Install setter marker", func(tmp string) {
|
||||
commitInRepo(cloneLocalRepoURL, branch, "Install setter marker", func(tmp string) {
|
||||
replaceMarker(tmp, policyKey)
|
||||
})
|
||||
|
||||
|
|
@ -291,7 +354,7 @@ var _ = Describe("ImageUpdateAutomation", func() {
|
|||
Expect(newObj.Status.LastPushCommit).To(Equal(head.Hash().String()))
|
||||
Expect(newObj.Status.LastPushTime).ToNot(BeNil())
|
||||
|
||||
compareRepoWithExpected(repoURL, branch, "testdata/appconfig-setters-expected", func(tmp string) {
|
||||
compareRepoWithExpected(cloneLocalRepoURL, branch, "testdata/appconfig-setters-expected", func(tmp string) {
|
||||
replaceMarker(tmp, policyKey)
|
||||
})
|
||||
})
|
||||
|
|
@ -338,21 +401,35 @@ var _ = Describe("ImageUpdateAutomation", func() {
|
|||
}
|
||||
|
||||
Context("Using go-git", func() {
|
||||
BeforeEach(func() {
|
||||
impl = sourcev1.GoGitImplementation
|
||||
BeforeEach(func() { impl = sourcev1.GoGitImplementation })
|
||||
|
||||
Context("with HTTP", func() {
|
||||
BeforeEach(func() { proto = "http" })
|
||||
Describe("with image policy", withImagePolicy)
|
||||
})
|
||||
|
||||
Context("with image policy", withImagePolicy)
|
||||
Context("with SSH", func() {
|
||||
BeforeEach(func() { proto = "ssh" })
|
||||
Describe("with image policy", withImagePolicy)
|
||||
})
|
||||
})
|
||||
|
||||
Context("Using libgit2", func() {
|
||||
BeforeEach(func() {
|
||||
impl = sourcev1.LibGit2Implementation
|
||||
BeforeEach(func() { impl = sourcev1.LibGit2Implementation })
|
||||
|
||||
Context("with HTTP", func() {
|
||||
BeforeEach(func() { proto = "http" })
|
||||
Describe("with image policy", withImagePolicy)
|
||||
})
|
||||
|
||||
Context("with image policy", withImagePolicy)
|
||||
// Marked "Pending" because the libgit2 SSH implementation
|
||||
// won't work with the gittestserver yet -- see
|
||||
// https://github.com/fluxcd/source-controller/issues/287
|
||||
Context("with SSH", func() {
|
||||
BeforeEach(func() { proto = "ssh" })
|
||||
Describe("with image policy", withImagePolicy)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
func expectCommittedAndPushed(conditions []metav1.Condition) {
|
||||
|
|
@ -498,7 +575,7 @@ func initGitRepo(gitServer *gittestserver.GitServer, fixture, branch, repository
|
|||
|
||||
remote, err := repo.CreateRemote(&config.RemoteConfig{
|
||||
Name: "origin",
|
||||
URLs: []string{gitServer.HTTPAddress() + repositoryPath},
|
||||
URLs: []string{gitServer.HTTPAddressWithCredentials() + repositoryPath},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
9
go.mod
9
go.mod
|
|
@ -11,17 +11,18 @@ require (
|
|||
github.com/fluxcd/image-automation-controller/api v0.4.0
|
||||
github.com/fluxcd/image-reflector-controller/api v0.4.0
|
||||
github.com/fluxcd/pkg/apis/meta v0.7.0
|
||||
github.com/fluxcd/pkg/gittestserver v0.1.0
|
||||
github.com/fluxcd/pkg/gittestserver v0.2.1
|
||||
github.com/fluxcd/pkg/runtime v0.8.1
|
||||
github.com/fluxcd/source-controller v0.7.0
|
||||
github.com/fluxcd/pkg/ssh v0.0.5
|
||||
github.com/fluxcd/source-controller v0.7.4
|
||||
// If you bump this, change SOURCE_VER in the Makefile to match
|
||||
github.com/fluxcd/source-controller/api v0.7.0
|
||||
github.com/fluxcd/source-controller/api v0.7.4
|
||||
github.com/go-git/go-billy/v5 v5.0.0
|
||||
github.com/go-git/go-git/v5 v5.2.0
|
||||
github.com/go-logr/logr v0.3.0
|
||||
github.com/go-openapi/spec v0.19.5
|
||||
github.com/google/go-containerregistry v0.1.1
|
||||
github.com/libgit2/git2go/v31 v31.3.0
|
||||
github.com/libgit2/git2go/v31 v31.4.7
|
||||
github.com/onsi/ginkgo v1.14.1
|
||||
github.com/onsi/gomega v1.10.2
|
||||
github.com/otiai10/copy v1.2.0
|
||||
|
|
|
|||
22
go.sum
22
go.sum
|
|
@ -306,11 +306,11 @@ github.com/fluxcd/image-reflector-controller/api v0.4.0 h1:/7mxmTsjmwmzTchWG06Fa
|
|||
github.com/fluxcd/image-reflector-controller/api v0.4.0/go.mod h1:MS3mGjZLnzZsfSqVLGbp0WNJr/k8XRFpw4G6ApLFTbc=
|
||||
github.com/fluxcd/pkg/apis/meta v0.7.0 h1:5e8gm4OLqjuKWdrOIY5DEEsjcwzyJFK8rCDesJ+V8IY=
|
||||
github.com/fluxcd/pkg/apis/meta v0.7.0/go.mod h1:yHuY8kyGHYz22I0jQzqMMGCcHViuzC/WPdo9Gisk8Po=
|
||||
github.com/fluxcd/pkg/gittestserver v0.1.0 h1:BvIG+bBhgbmqhtpSS2qUpOXRIL1P1Ow2jauloH8X86U=
|
||||
github.com/fluxcd/pkg/gittestserver v0.1.0/go.mod h1:HWZaoib03fQeSsauCAN2iAFdr6bnjKQ+CFxMFD2mwDY=
|
||||
github.com/fluxcd/pkg/gittestserver v0.2.1 h1:SidG8/2hPVEV4XL7ofI76RMfen9zt1LLIoXddzkAhhI=
|
||||
github.com/fluxcd/pkg/gittestserver v0.2.1/go.mod h1:HWZaoib03fQeSsauCAN2iAFdr6bnjKQ+CFxMFD2mwDY=
|
||||
github.com/fluxcd/pkg/helmtestserver v0.1.0/go.mod h1:3L+tbPn74PsHwHsyhbfk/kZAosrwMFTTA92XEFiwVAE=
|
||||
github.com/fluxcd/pkg/lockedfile v0.0.5/go.mod h1:uAtPUBId6a2RqO84MTH5HKGX0SbM1kNW3Wr/FhYyDVA=
|
||||
github.com/fluxcd/pkg/runtime v0.8.0/go.mod h1:tQwEN+RESjJmtwSSv7I+6bkNM9raIXpGsCjruaIVX6A=
|
||||
github.com/fluxcd/pkg/runtime v0.8.1 h1:8UxNz7GeI/HC3U5tpNCfrjRx2V7UjUegQOwCsd+EWxk=
|
||||
github.com/fluxcd/pkg/runtime v0.8.1/go.mod h1:tQwEN+RESjJmtwSSv7I+6bkNM9raIXpGsCjruaIVX6A=
|
||||
github.com/fluxcd/pkg/ssh v0.0.5 h1:rnbFZ7voy2JBlUfMbfyqArX2FYaLNpDhccGFC3qW83A=
|
||||
|
|
@ -319,10 +319,10 @@ github.com/fluxcd/pkg/testserver v0.0.2/go.mod h1:pgUZTh9aQ44FSTQo+5NFlh7YMbUfdz
|
|||
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
|
||||
github.com/fluxcd/pkg/version v0.0.1 h1:/8asQoDXSThz3csiwi4Qo8Zb6blAxLXbtxNgeMJ9bCg=
|
||||
github.com/fluxcd/pkg/version v0.0.1/go.mod h1:WAF4FEEA9xyhngF8TDxg3UPu5fA1qhEYV8Pmi2Il01Q=
|
||||
github.com/fluxcd/source-controller v0.7.0 h1:OvvD0a9ZhlIshZt0NzkXJ5hAD8Zce7xERFC1UyhfXZA=
|
||||
github.com/fluxcd/source-controller v0.7.0/go.mod h1:hfpk9y5iDJlSZqL+/OZTqvYDFZgIKz1PV26bOy404+M=
|
||||
github.com/fluxcd/source-controller/api v0.7.0 h1:QDpr6ZjHtTxw+mc+mZ1p9qRujHb+PzPdoQP3YgWlqOA=
|
||||
github.com/fluxcd/source-controller/api v0.7.0/go.mod h1:u2sdc/QDm0tzXHL7mZVj928hc3MMU+4mKCuAQg+94Bk=
|
||||
github.com/fluxcd/source-controller v0.7.4 h1:1I+vPPJUHI4f1775E34EUBbATLt2QfEykvlfFJRMiUk=
|
||||
github.com/fluxcd/source-controller v0.7.4/go.mod h1:W/C32SFn9P7WXwjILjhAfN7F+zuWG5YAaQUUgHDlbes=
|
||||
github.com/fluxcd/source-controller/api v0.7.4 h1:Hy29SUyanKNHbb4AQZo7PqzmTx4y8TfkeO0GqBcb5PE=
|
||||
github.com/fluxcd/source-controller/api v0.7.4/go.mod h1:u2sdc/QDm0tzXHL7mZVj928hc3MMU+4mKCuAQg+94Bk=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
|
|
@ -548,6 +548,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
|
|||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
|
|
@ -694,6 +696,8 @@ github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
|||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/libgit2/git2go/v31 v31.3.0 h1:d8ciyYVKir+gKwra3KuNxTyVvbgGKn4admdt1PNNAOg=
|
||||
github.com/libgit2/git2go/v31 v31.3.0/go.mod h1:mnc0hPGPs0nDi9INrurTpioeRzje9DvSXqON/+JEhwY=
|
||||
github.com/libgit2/git2go/v31 v31.4.7 h1:P85qB5at5un4qPqUcvOZbAom7P0G4KAG/OLVyD29kQ0=
|
||||
github.com/libgit2/git2go/v31 v31.4.7/go.mod h1:c/rkJcBcUFx6wHaT++UwNpKvIsmPNqCeQ/vzO4DrEec=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
|
|
@ -1120,6 +1124,8 @@ golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c h1:9HhBz5L/UjnK9XLtiZhYAdue5BVKep3PMmS2LuPDt8k=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
|
@ -1277,6 +1283,10 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY=
|
||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
|
|||
Loading…
Reference in New Issue