summaryrefslogtreecommitdiff
path: root/lib/puppet/type/vcsrepo.rb
blob: 352f439cc0e44af6f9cb8cb0b4521652f486a4ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
require 'pathname'

Puppet::Type.newtype(:vcsrepo) do
  desc "A local version control repository"

  feature :gzip_compression,
          "The provider supports explicit GZip compression levels"
  feature :basic_auth,
          "The provider supports HTTP Basic Authentication"
  feature :bare_repositories,
          "The provider differentiates between bare repositories
          and those with working copies",
          :methods => [:bare_exists?, :working_copy_exists?]

  feature :filesystem_types,
          "The provider supports different filesystem types"

  feature :reference_tracking,
          "The provider supports tracking revision references that can change
           over time (eg, some VCS tags and branch names)"

  feature :ssh_identity,
          "The provider supports a configurable SSH identity file"
          
  feature :user,
          "The provider can run as a different user"

  feature :modules,
          "The repository contains modules that can be chosen of"

  feature :multiple_remotes,
          "The repository tracks multiple remote repositories"

  ensurable do
    attr_accessor :latest

    def insync?(is)
      @should ||= []

      case should
        when :present
          return true unless [:absent, :purged, :held].include?(is)
        when :latest
          if is == :latest
            return true
          else
            return false
          end
		when :bare
		  return is == :bare
      end
    end

    newvalue :present do
      notice "Creating repository from present"
      provider.create
    end

    newvalue :bare, :required_features => [:bare_repositories] do
	  if !provider.exists?
        provider.create
      end
    end

    newvalue :absent do
      provider.destroy
    end

    newvalue :latest, :required_features => [:reference_tracking] do
      if provider.exists?
        if provider.respond_to?(:update_references)
          provider.update_references
        end
        if provider.respond_to?(:latest?)
            reference = provider.latest || provider.revision
        else
          reference = resource.value(:revision) || provider.revision
        end
        notice "Updating to latest '#{reference}' revision"
        provider.revision = reference
      else
        notice "Creating repository from latest"
        provider.create
      end
    end

    def retrieve
      prov = @resource.provider
      if prov
        if prov.working_copy_exists?
          (@should.include?(:latest) && prov.latest?) ? :latest : :present
        elsif prov.class.feature?(:bare_repositories) and prov.bare_exists?
          :bare
        else
          :absent
        end
      else
        raise Puppet::Error, "Could not find provider"
      end
    end

  end

  newparam :path do
    desc "Absolute path to repository"
    isnamevar
    validate do |value|
      path = Pathname.new(value)
      unless path.absolute?
        raise ArgumentError, "Path must be absolute: #{path}"
      end
    end
  end

  newparam :source do
    desc "The source URI for the repository"
  end

  newparam :fstype, :required_features => [:filesystem_types] do
    desc "Filesystem type"
  end

  newproperty :revision do
    desc "The revision of the repository"
    newvalue(/^\S+$/)
  end

  newparam :owner do
    desc "The user/uid that owns the repository files"
  end

  newparam :group do
    desc "The group/gid that owns the repository files"
  end

  newparam :user do
    desc "The user to run for repository operations"
  end

  newparam :excludes do
    desc "Files to be excluded from the repository"
  end

  newparam :force do
    desc "Force repository creation, destroying any files on the path in the process."
    newvalues(:true, :false)
    defaultto false
  end

  newparam :compression, :required_features => [:gzip_compression] do
    desc "Compression level"
    validate do |amount|
      unless Integer(amount).between?(0, 6)
        raise ArgumentError, "Unsupported compression level: #{amount} (expected 0-6)"
      end
    end
  end

  newparam :basic_auth_username, :required_features => [:basic_auth] do
    desc "HTTP Basic Auth username"
  end

  newparam :basic_auth_password, :required_features => [:basic_auth] do
    desc "HTTP Basic Auth password"
  end

  newparam :identity, :required_features => [:ssh_identity] do
    desc "SSH identity file"
  end
  
  newparam :module, :required_features => [:modules] do
    desc "The repository module to manage"
  end

  newparam :remote, :required_features => [:multiple_remotes] do
    desc "The remote repository to track"
    defaultto "origin"
  end

end