Merge pull request #11465 from pmorie/git-bc-type

Refactor git repo volume to separate builder and cleaner
This commit is contained in:
Daniel Smith 2015-07-27 16:11:01 -07:00
commit 11899c3080
2 changed files with 61 additions and 38 deletions

View File

@ -58,43 +58,64 @@ func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool {
} }
func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
return &gitRepo{ return &gitRepoVolumeBuilder{
gitRepoVolume: &gitRepoVolume{
volName: spec.Name,
podUID: pod.UID,
mounter: mounter,
plugin: plugin,
},
pod: *pod, pod: *pod,
volName: spec.Name,
source: spec.VolumeSource.GitRepo.Repository, source: spec.VolumeSource.GitRepo.Repository,
revision: spec.VolumeSource.GitRepo.Revision, revision: spec.VolumeSource.GitRepo.Revision,
exec: exec.New(), exec: exec.New(),
plugin: plugin,
opts: opts, opts: opts,
mounter: mounter,
}, nil }, nil
} }
func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return &gitRepo{ return &gitRepoVolumeCleaner{
pod: api.Pod{ObjectMeta: api.ObjectMeta{UID: podUID}}, &gitRepoVolume{
volName: volName, volName: volName,
plugin: plugin, podUID: podUID,
mounter: mounter, mounter: mounter,
plugin: plugin,
},
}, nil }, nil
} }
// gitRepo volumes are directories which are pre-filled from a git repository. // gitRepo volumes are directories which are pre-filled from a git repository.
// These do not persist beyond the lifetime of a pod. // These do not persist beyond the lifetime of a pod.
type gitRepo struct { type gitRepoVolume struct {
volName string volName string
podUID types.UID
mounter mount.Interface
plugin *gitRepoPlugin
}
var _ volume.Volume = &gitRepoVolume{}
func (gr *gitRepoVolume) GetPath() string {
name := gitRepoPluginName
return gr.plugin.host.GetPodVolumeDir(gr.podUID, util.EscapeQualifiedNameForDisk(name), gr.volName)
}
// gitRepoVolumeBuilder builds git repo volumes.
type gitRepoVolumeBuilder struct {
*gitRepoVolume
pod api.Pod pod api.Pod
source string source string
revision string revision string
exec exec.Interface exec exec.Interface
plugin *gitRepoPlugin
opts volume.VolumeOptions opts volume.VolumeOptions
mounter mount.Interface
} }
var _ volume.Builder = &gitRepoVolumeBuilder{}
// SetUp creates new directory and clones a git repo. // SetUp creates new directory and clones a git repo.
func (gr *gitRepo) SetUp() error { func (b *gitRepoVolumeBuilder) SetUp() error {
return gr.SetUpAt(gr.GetPath()) return b.SetUpAt(b.GetPath())
} }
// This is the spec for the volume that this plugin wraps. // This is the spec for the volume that this plugin wraps.
@ -104,13 +125,13 @@ var wrappedVolumeSpec = &volume.Spec{
} }
// SetUpAt creates new directory and clones a git repo. // SetUpAt creates new directory and clones a git repo.
func (gr *gitRepo) SetUpAt(dir string) error { func (b *gitRepoVolumeBuilder) SetUpAt(dir string) error {
if volumeutil.IsReady(gr.getMetaDir()) { if volumeutil.IsReady(b.getMetaDir()) {
return nil return nil
} }
// Wrap EmptyDir, let it do the setup. // Wrap EmptyDir, let it do the setup.
wrapped, err := gr.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &gr.pod, gr.opts, gr.mounter) wrapped, err := b.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &b.pod, b.opts, b.mounter)
if err != nil { if err != nil {
return err return err
} }
@ -118,8 +139,8 @@ func (gr *gitRepo) SetUpAt(dir string) error {
return err return err
} }
if output, err := gr.execCommand("git", []string{"clone", gr.source}, dir); err != nil { if output, err := b.execCommand("git", []string{"clone", b.source}, dir); err != nil {
return fmt.Errorf("failed to exec 'git clone %s': %s: %v", gr.source, output, err) return fmt.Errorf("failed to exec 'git clone %s': %s: %v", b.source, output, err)
} }
files, err := ioutil.ReadDir(dir) files, err := ioutil.ReadDir(dir)
@ -129,48 +150,50 @@ func (gr *gitRepo) SetUpAt(dir string) error {
if len(files) != 1 { if len(files) != 1 {
return fmt.Errorf("unexpected directory contents: %v", files) return fmt.Errorf("unexpected directory contents: %v", files)
} }
if len(gr.revision) == 0 { if len(b.revision) == 0 {
// Done! // Done!
volumeutil.SetReady(gr.getMetaDir()) volumeutil.SetReady(b.getMetaDir())
return nil return nil
} }
subdir := path.Join(dir, files[0].Name()) subdir := path.Join(dir, files[0].Name())
if output, err := gr.execCommand("git", []string{"checkout", gr.revision}, subdir); err != nil { if output, err := b.execCommand("git", []string{"checkout", b.revision}, subdir); err != nil {
return fmt.Errorf("failed to exec 'git checkout %s': %s: %v", gr.revision, output, err) return fmt.Errorf("failed to exec 'git checkout %s': %s: %v", b.revision, output, err)
} }
if output, err := gr.execCommand("git", []string{"reset", "--hard"}, subdir); err != nil { if output, err := b.execCommand("git", []string{"reset", "--hard"}, subdir); err != nil {
return fmt.Errorf("failed to exec 'git reset --hard': %s: %v", output, err) return fmt.Errorf("failed to exec 'git reset --hard': %s: %v", output, err)
} }
volumeutil.SetReady(gr.getMetaDir()) volumeutil.SetReady(b.getMetaDir())
return nil return nil
} }
func (gr *gitRepo) getMetaDir() string { func (b *gitRepoVolumeBuilder) getMetaDir() string {
return path.Join(gr.plugin.host.GetPodPluginDir(gr.pod.UID, util.EscapeQualifiedNameForDisk(gitRepoPluginName)), gr.volName) return path.Join(b.plugin.host.GetPodPluginDir(b.podUID, util.EscapeQualifiedNameForDisk(gitRepoPluginName)), b.volName)
} }
func (gr *gitRepo) execCommand(command string, args []string, dir string) ([]byte, error) { func (b *gitRepoVolumeBuilder) execCommand(command string, args []string, dir string) ([]byte, error) {
cmd := gr.exec.Command(command, args...) cmd := b.exec.Command(command, args...)
cmd.SetDir(dir) cmd.SetDir(dir)
return cmd.CombinedOutput() return cmd.CombinedOutput()
} }
func (gr *gitRepo) GetPath() string { // gitRepoVolumeCleaner cleans git repo volumes.
name := gitRepoPluginName type gitRepoVolumeCleaner struct {
return gr.plugin.host.GetPodVolumeDir(gr.pod.UID, util.EscapeQualifiedNameForDisk(name), gr.volName) *gitRepoVolume
} }
var _ volume.Cleaner = &gitRepoVolumeCleaner{}
// TearDown simply deletes everything in the directory. // TearDown simply deletes everything in the directory.
func (gr *gitRepo) TearDown() error { func (c *gitRepoVolumeCleaner) TearDown() error {
return gr.TearDownAt(gr.GetPath()) return c.TearDownAt(c.GetPath())
} }
// TearDownAt simply deletes everything in the directory. // TearDownAt simply deletes everything in the directory.
func (gr *gitRepo) TearDownAt(dir string) error { func (c *gitRepoVolumeCleaner) TearDownAt(dir string) error {
// Wrap EmptyDir, let it do the teardown. // Wrap EmptyDir, let it do the teardown.
wrapped, err := gr.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, gr.pod.UID, gr.mounter) wrapped, err := c.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, c.podUID, c.mounter)
if err != nil { if err != nil {
return err return err
} }

View File

@ -78,7 +78,7 @@ func testSetUp(plug volume.VolumePlugin, builder volume.Builder, t *testing.T) {
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
}, },
} }
g := builder.(*gitRepo) g := builder.(*gitRepoVolumeBuilder)
g.exec = &fake g.exec = &fake
err := g.SetUp() err := g.SetUp()