foreman_xen 0.0.4.1 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ # Development policy #
2
+
3
+ Currently we hold master branch as tested and verified version, please submit your changes into development branch only.
4
+
1
5
  # Foreman XEN Plugin
2
6
 
3
7
  This plugin enables provisioning and managing XEN Server in Foreman.
@@ -0,0 +1,176 @@
1
+ module ForemanXen
2
+ class SnapshotsController < ::ApplicationController
3
+ helper :all
4
+ skip_before_filter :verify_authenticity_token
5
+
6
+ #GET - foreman_xen/snapshots/:host_id
7
+ def show
8
+ id = params[:id]
9
+ if id != nil && id != ""
10
+ @host = get_host_by_id(id)
11
+ end
12
+ puts @host.inspect
13
+ if !@host.nil? && @host.compute_resource_id
14
+ @compute_resource = get_compute_resource_for_host(@host)
15
+ if !@compute_resource.nil?
16
+ vm = @compute_resource.find_vm_by_uuid(@host.uuid)
17
+ if !vm.nil?
18
+ @snapshots = @compute_resource.get_snapshots_for_vm(vm)
19
+ else
20
+ process_error({:error_msg => "Error retrieving compute resource #{@host.compute_resource_id} from provider."})
21
+ return
22
+ end
23
+ end
24
+ elsif @host.nil?
25
+ process_error({:error_msg => "No host found with ID: #{id}."})
26
+ return
27
+ else
28
+ process_error({:error_msg => "No compute resource found for host with ID: #{id}."})
29
+ return
30
+ end
31
+ end
32
+
33
+ #GET = foreman_xen/snapshots/revert
34
+ def revert
35
+ id = params[:id]
36
+ ref = params[:ref]
37
+ @host = get_host_by_id(id)
38
+ @compute_resource = get_compute_resource_by_host_id(id)
39
+ if @compute_resource
40
+ if @host
41
+ vm = @compute_resource.find_vm_by_uuid(@host.uuid)
42
+ vm.revert(ref)
43
+ vm.start
44
+ process_success({:success_msg => "Succesfully reverted and powered on #{@host.name}", :success_redirect => "/foreman_xen/snapshots/#{id}"})
45
+ return
46
+ else
47
+ process_error({:error_msg => "Error retrieving host information for #{@host.name}" })
48
+ return
49
+ end
50
+ else
51
+ process_error({:error_msg => "Error retrieving compute resource information for #{@host.name}" })
52
+ return
53
+ end
54
+ process_success({:success_msg => ("Succesfully reverted #{@host.name}"), :success_redirect => "/foreman_xen/snapshots/#{id}"})
55
+ return
56
+ end
57
+
58
+ #GET = foreman_xen/snapshots/delete
59
+ def destroy
60
+ ref = params[:ref]
61
+ id = params[:id]
62
+ @host = get_host_by_id(id)
63
+ @compute_resource = get_compute_resource_by_host_id(id)
64
+ name = nil
65
+ if @compute_resource
66
+ if @host
67
+ snapshots = @compute_resource.get_snapshots
68
+ snapshots.each do | snapshot |
69
+ if snapshot.reference == ref
70
+ name = snapshot.name
71
+ snapshot.destroy
72
+ notice ("Succesfully deleted snapshot #{snapshot.name}")
73
+ break
74
+ end
75
+ end
76
+ else
77
+ process_error({:error_msg => ("Error retrieving host information for host id: #{id}")})
78
+ return
79
+ end
80
+ else
81
+ process_error({:error_msg => ("Error retrieving compute resource information for host id: #{id}")})
82
+ return
83
+ end
84
+ process_success({:success_msg => ("Succesfully deleted snapshot: #{name}"), :success_redirect => "/foreman_xen/snapshots/#{id}"})
85
+ return
86
+ end
87
+
88
+ #GET = foreman_xen/snapshots/:id/new
89
+ def new
90
+ id = params[:id]
91
+ @host = get_host_by_id(id)
92
+ if !@host.nil?
93
+ @compute_resource = get_compute_resource_by_host_id(id)
94
+ if @compute_resource.nil?
95
+ process_error({:error_msg => "Error retrieving compute information for compute resource id: #{@host.compute_resource_id}"})
96
+ return
97
+ end
98
+ else
99
+ process_error({:error_msg => "Error retrieving host information for host id: #{id}"})
100
+ return
101
+ end
102
+ end
103
+
104
+ #POST = foreman_xen/snapshots/:id/create
105
+ def create
106
+ id = params[:id]
107
+ name = params[:name]
108
+ if name.nil? || name == ""
109
+ process_error({:error_msg => "You must supply a name."})
110
+ return
111
+ end
112
+ @host = get_host_by_id(id)
113
+ if !@host.nil?
114
+ @compute_resource = get_compute_resource_by_host_id(id)
115
+ else
116
+ process_error({:error_msg => "Error retrieving host information for host id #{id}"})
117
+ return
118
+ end
119
+ if !@compute_resource.nil?
120
+ vm = @compute_resource.find_vm_by_uuid(@host.uuid)
121
+ if !vm.nil?
122
+ vm.snapshot(name)
123
+ process_success({:success_msg => "Succesfully created snapshot #{name} for #{@host.name}", :success_redirect => "/foreman_xen/snapshots/#{id}"})
124
+ return
125
+ else
126
+ process_error({:error_msg => "Error retrieving compute resource information for #{@host.name}"})
127
+ return
128
+ end
129
+ else
130
+ process_error({:error_msg => "Error retrieving compute provider information for #{@host.name}"})
131
+ return
132
+ end
133
+ end
134
+
135
+ def snapshots_url
136
+ case params[:action]
137
+ when 'show'
138
+ return '/'
139
+ when 'new'
140
+ id = params[:id]
141
+ if id.nil?
142
+ return '/'
143
+ else
144
+ return "/foreman_xen/snapshots/#{id}"
145
+ end
146
+ when 'create'
147
+ id = params[:id]
148
+ if id.nil?
149
+ return '/'
150
+ else
151
+ return "/foreman_xen/snapshots/#{id}/new"
152
+ end
153
+ end
154
+ end
155
+
156
+ private
157
+
158
+ def get_host_by_id(host_id)
159
+ Host::Managed.where(:id => host_id).to_a[0]
160
+ end
161
+
162
+ def get_compute_resource_by_host_id(host_id)
163
+ host = get_host_by_id(host_id)
164
+ if host
165
+ ComputeResource.where(:id => host.compute_resource_id).to_a[0]
166
+ end
167
+ end
168
+
169
+ def get_compute_resource_for_host(host)
170
+ if host
171
+ ComputeResource.where(:id => host.compute_resource_id).to_a[0]
172
+ end
173
+ end
174
+
175
+ end
176
+ end
@@ -0,0 +1,78 @@
1
+ module ForemanXen
2
+ module HostHelperExtensions
3
+ extend ActiveSupport::Concern
4
+ def host_title_actions(host)
5
+ title_actions(
6
+ button_group(
7
+ link_to_if_authorized(_("Edit"), hash_for_edit_host_path(:id => host).merge(:auth_object => host),
8
+ :title => _("Edit your host")),
9
+ if host.build
10
+ link_to_if_authorized(_("Cancel build"), hash_for_cancelBuild_host_path(:id => host).merge(:auth_object => host, :permission => 'build_hosts'),
11
+ :disabled => host.can_be_built?,
12
+ :title => _("Cancel build request for this host"))
13
+ else
14
+ link_to_if_authorized(_("Build"), hash_for_setBuild_host_path(:id => host).merge(:auth_object => host, :permission => 'build_hosts'),
15
+ :disabled => !host.can_be_built?,
16
+ :title => _("Enable rebuild on next host boot"),
17
+ :confirm => _("Rebuild %s on next reboot?\nThis would also delete all of its current facts and reports") % host)
18
+ end
19
+ ),
20
+ if host.compute_resource_id || host.bmc_available?
21
+ button_group(
22
+ link_to(_("Loading power state ..."), '#', :disabled => true, :id => :loading_power_state)
23
+ )
24
+ end,
25
+ button_group(
26
+ if host.try(:puppet_proxy)
27
+ link_to_if_authorized(_("Run puppet"), hash_for_puppetrun_host_path(:id => host).merge(:auth_object => host, :permission => 'puppetrun_hosts'),
28
+ :disabled => !Setting[:puppetrun],
29
+ :title => _("Trigger a puppetrun on a node; requires that puppet run is enabled"))
30
+ end
31
+ ),
32
+ button_group(
33
+ link_to_if_authorized(_("Delete"), hash_for_host_path(:id => host).merge(:auth_object => host, :permission => 'destroy_hosts'),
34
+ :class => "btn btn-danger", :confirm => _('Are you sure?'), :method => :delete)
35
+ )
36
+ )
37
+ end
38
+
39
+ def xen_host_title_actions(host)
40
+ title_actions(
41
+ button_group(
42
+ link_to_if_authorized(_("Edit"), hash_for_edit_host_path(:id => host).merge(:auth_object => host),
43
+ :title => _("Edit your host")),
44
+ if host.compute_resource_id
45
+ link_to(_("Snapshots"), "../foreman_xen/snapshots/#{@host.id}/",
46
+ :title => _("Manage machine snapshots"))
47
+ end,
48
+ if host.build
49
+ link_to_if_authorized(_("Cancel build"), hash_for_cancelBuild_host_path(:id => host).merge(:auth_object => host, :permission => 'build_hosts'),
50
+ :disabled => host.can_be_built?,
51
+ :title => _("Cancel build request for this host"))
52
+ else
53
+ link_to_if_authorized(_("Build"), hash_for_setBuild_host_path(:id => host).merge(:auth_object => host, :permission => 'build_hosts'),
54
+ :disabled => !host.can_be_built?,
55
+ :title => _("Enable rebuild on next host boot"),
56
+ :confirm => _("Rebuild %s on next reboot?\nThis would also delete all of its current facts and reports") % host)
57
+ end
58
+ ),
59
+ if host.compute_resource_id || host.bmc_available?
60
+ button_group(
61
+ link_to(_("Loading power state ..."), '#', :disabled => true, :id => :loading_power_state)
62
+ )
63
+ end,
64
+ button_group(
65
+ if host.try(:puppet_proxy)
66
+ link_to_if_authorized(_("Run puppet"), hash_for_puppetrun_host_path(:id => host).merge(:auth_object => host, :permission => 'puppetrun_hosts'),
67
+ :disabled => !Setting[:puppetrun],
68
+ :title => _("Trigger a puppetrun on a node; requires that puppet run is enabled"))
69
+ end
70
+ ),
71
+ button_group(
72
+ link_to_if_authorized(_("Delete"), hash_for_host_path(:id => host).merge(:auth_object => host, :permission => 'destroy_hosts'),
73
+ :class => "btn btn-danger", :confirm => _('Are you sure?'), :method => :delete)
74
+ )
75
+ )
76
+ end
77
+ end
78
+ end
@@ -104,6 +104,23 @@ module ForemanXen
104
104
  Host.authorized(:view_hosts, Host).where(:ip => ips).first
105
105
  end
106
106
 
107
+ def get_snapshots_for_vm(vm)
108
+ if vm.snapshots.empty?
109
+ return []
110
+ end
111
+ tmps = client.servers.templates.select { |t| t.is_a_snapshot } rescue []
112
+ retval = []
113
+ tmps.each do | snapshot |
114
+ retval << snapshot if vm.snapshots.include?(snapshot.reference)
115
+ end
116
+ retval
117
+ end
118
+
119
+ def get_snapshots
120
+ tmps = client.servers.templates.select { |t| t.is_a_snapshot } rescue []
121
+ tmps.sort { |a, b| a.name <=> b.name }
122
+ end
123
+
107
124
  def new_vm(attr={})
108
125
 
109
126
  test_connection
@@ -0,0 +1,2 @@
1
+ <!-- replace 'erb[loud]:contains("host_title_actions")' -->
2
+ <%= xen_host_title_actions(@host) %>
@@ -0,0 +1,2 @@
1
+ <!-- replace 'code[erb-loud]:contains("host_title_actions")' -->
2
+ <%= xen_host_title_actions(@host) %>
@@ -0,0 +1,23 @@
1
+ <% title _("Create Snapshot") %>
2
+
3
+ <%= form_tag("create", method: "post") do %>
4
+ <div class="clearfix">
5
+ <div class="form-group">
6
+ <%= label_tag 'name', 'Name:', class: 'col-md-2 control-label' %>
7
+ <div class="col-md-8">
8
+ <%= text_field_tag(:name, nil, class: "form-control") %>
9
+ </div>
10
+
11
+ <div class="col-md-8">
12
+
13
+ </div>
14
+ </div>
15
+ </div>
16
+ <div class = "row form-group"></div>
17
+ <div class="clearfix">
18
+ <div class="form-actions">
19
+ <%= link_to("Cancel", "/foreman_xen/snapshots/#{@host.id}", :id => "cancel_button", :class => "btn btn-danger") %>
20
+ <%= submit_tag("Create", class: "btn btn-primary") %>
21
+ </div>
22
+ </div>
23
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <% title _("Snapshots: #{@host.name}") %>
2
+ <%= title_actions(
3
+ button_group(link_to("Take Snapshot", "/foreman_xen/snapshots/#{@host.id}/new", :id => "takeSnapshotButton", :class => "btn btn-success"),
4
+ link_to_if_authorized(_("Back to host"), hash_for_host_path(:id => @host), :title => _("Back to host"), :class => 'btn btn-default')
5
+ ) ) %>
6
+
7
+ <table class="table table-hover">
8
+ <tbody>
9
+ <th>Name</th>
10
+ <th>Snapshot Time</th>
11
+ <th>Actions</th>
12
+ <% @snapshots.each do |snapshot| %>
13
+ <tr>
14
+ <td><%= h snapshot.name %></a></td>
15
+ <td><%= h "#{snapshot.snapshot_time.to_date} #{snapshot.snapshot_time.to_time} " %></a></td>
16
+ <td>
17
+ <div class="form-group">
18
+ <%= link_to("Revert", "/foreman_xen/snapshots/#{@host.id}/revert/#{snapshot.reference}", :id => "revertSnapshotButton", :class => "btn btn-danger", data: { confirm: "Confirm revert to #{snapshot.name}? Please note that all changes since the snapshot time will be lost, and the system will be restarted."})%>
19
+ <%= link_to("Delete", "/foreman_xen/snapshots/#{@host.id}/delete/#{snapshot.reference}", :id => "deleteSnapshotButton", :class => "btn btn-danger", data: { confirm: "Delete snapshot #{snapshot.name}?"})%>
20
+ </div>
21
+ </td>
22
+ </tr>
23
+ <% end %>
24
+ </tbody>
25
+ </table>
data/config/routes.rb ADDED
@@ -0,0 +1,12 @@
1
+ Rails.application.routes.draw do
2
+
3
+ namespace :foreman_xen do
4
+ match 'snapshots/:id', :to => 'snapshots#show', :via => 'get'
5
+ match 'snapshots/:id/revert/:ref', :to => 'snapshots#revert', :via => 'get'
6
+ match 'snapshots/:id/new', :to => 'snapshots#new', :via => 'get'
7
+ match 'snapshots/:id/delete/:ref', :to => 'snapshots#destroy', :via => 'get'
8
+
9
+ match 'snapshots/:id/create', :to => 'snapshots#create', :via => 'post'
10
+ end
11
+
12
+ end
@@ -1,6 +1,7 @@
1
1
  require 'fast_gettext'
2
2
  require 'gettext_i18n_rails'
3
3
  require 'fog'
4
+ require 'deface'
4
5
 
5
6
  module ForemanXen
6
7
  #Inherit from the Rails module of the parent app (Foreman), not the plugin.
@@ -23,10 +24,23 @@ module ForemanXen
23
24
 
24
25
  end
25
26
 
27
+ config.to_prepare do
28
+ begin
29
+ # extend fog xen server and image models.
30
+ require 'fog/xenserver/models/compute/server'
31
+ require File.expand_path('../../../app/models/concerns/fog_extensions/xenserver/server', __FILE__)
32
+ require File.expand_path('../../../app/models/concerns/foreman_xen/host_helper_extensions', __FILE__)
33
+
34
+ Fog::Compute::XenServer::Server.send(:include, ::FogExtensions::Xenserver::Server)
35
+ ::HostsHelper.send(:include, ForemanXen::HostHelperExtensions)
36
+ rescue => e
37
+ puts "Foreman-Xen: skipping engine hook (#{e.to_s})"
38
+ end
39
+ end
40
+
26
41
  end
27
42
 
28
- # extend fog xen server and image models.
29
- require 'fog/xenserver/models/compute/server'
30
- require File.expand_path('../../../app/models/concerns/fog_extensions/xenserver/server', __FILE__)
31
- Fog::Compute::XenServer::Server.send(:include, ::FogExtensions::Xenserver::Server)
43
+
44
+
45
+
32
46
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanXen
2
- VERSION = "0.0.4.1"
2
+ VERSION = "0.0.5"
3
3
  end
metadata CHANGED
@@ -1,98 +1,126 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: foreman_xen
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.4.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 5
10
+ version: 0.0.5
5
11
  platform: ruby
6
- authors:
7
- - Pavel Nemirovsky, Michał Piotrowski, Avi Israeli
12
+ authors:
13
+ - "Pavel Nemirovsky, Micha\xC5\x82 Piotrowski, Avi Israeli"
8
14
  autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
- date: 2014-11-21 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2014-12-17 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
14
22
  name: rake
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '>='
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
23
  prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '>='
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
28
36
  name: fog
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '>='
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
37
  prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '>='
39
- - !ruby/object:Gem::Version
40
- version: '0'
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
41
49
  description: Provision and manage XEN Server from Foreman.
42
- email:
50
+ email:
43
51
  - operations@oovoo.com
44
52
  executables: []
53
+
45
54
  extensions: []
55
+
46
56
  extra_rdoc_files: []
47
- files:
57
+
58
+ files:
59
+ - app/models/concerns/foreman_xen/host_helper_extensions.rb
60
+ - app/models/concerns/fog_extensions/xenserver/server.rb
61
+ - app/models/foreman_xen/xenserver.rb
48
62
  - app/views/compute_resources/show/_xenserver.html.erb
49
63
  - app/views/compute_resources/form/_xenserver.html.erb
50
- - app/views/api/v2/compute_resources/xenserver.json.rabl
51
64
  - app/views/api/v1/compute_resources/xenserver.json.rabl
65
+ - app/views/api/v2/compute_resources/xenserver.json.rabl
66
+ - app/views/foreman_xen/snapshots/show.html.erb
67
+ - app/views/foreman_xen/snapshots/new.html.erb
52
68
  - app/views/compute_resources_vms/show/_xenserver.html.erb
53
- - app/views/compute_resources_vms/form/_xenstore.html.erb
69
+ - app/views/compute_resources_vms/index/_xenserver.html.erb
54
70
  - app/views/compute_resources_vms/form/_volume.html.erb
71
+ - app/views/compute_resources_vms/form/_xenserver.html.erb
55
72
  - app/views/compute_resources_vms/form/_templates.html.erb
73
+ - app/views/compute_resources_vms/form/_xenstore.html.erb
56
74
  - app/views/compute_resources_vms/form/_network.html.erb
57
- - app/views/compute_resources_vms/form/_xenserver.html.erb
58
- - app/views/compute_resources_vms/index/_xenserver.html.erb
59
- - app/models/concerns/fog_extensions/xenserver/server.rb
60
- - app/models/foreman_xen/xenserver.rb
61
- - lib/foreman_xen.rb
75
+ - app/controllers/foreman_xen/snapshots_controller.rb
76
+ - app/overrides/hosts/show/snapshot_override_legacy.html.erb.deface
77
+ - app/overrides/hosts/show/snapshot_override.html.erb.deface
78
+ - config/routes.rb
79
+ - lib/tasks/foreman_xen_tasks.rake
80
+ - lib/foreman_xen/vnc_tunnel.rb
62
81
  - lib/foreman_xen/engine.rb
63
82
  - lib/foreman_xen/version.rb
64
- - lib/foreman_xen/vnc_tunnel.rb
65
- - lib/tasks/foreman_xen_tasks.rake
83
+ - lib/foreman_xen.rb
66
84
  - locale/Makefile
67
85
  - LICENSE
68
86
  - Rakefile
69
87
  - README.md
70
- - test/foreman_xen_test.rb
71
88
  - test/test_helper.rb
89
+ - test/foreman_xen_test.rb
90
+ has_rdoc: true
72
91
  homepage: http://github.com/theforeman/foreman-xen
73
- licenses:
92
+ licenses:
74
93
  - GPL-3
75
- metadata: {}
76
94
  post_install_message:
77
95
  rdoc_options: []
78
- require_paths:
96
+
97
+ require_paths:
79
98
  - lib
80
- required_ruby_version: !ruby/object:Gem::Requirement
81
- requirements:
82
- - - '>='
83
- - !ruby/object:Gem::Version
84
- version: '0'
85
- required_rubygems_version: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - '>='
88
- - !ruby/object:Gem::Version
89
- version: '0'
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ hash: 3
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
90
117
  requirements: []
118
+
91
119
  rubyforge_project:
92
- rubygems_version: 2.0.6
120
+ rubygems_version: 1.3.7
93
121
  signing_key:
94
- specification_version: 4
122
+ specification_version: 3
95
123
  summary: Provision and manage XEN Server from Foreman
96
- test_files:
97
- - test/foreman_xen_test.rb
124
+ test_files:
98
125
  - test/test_helper.rb
126
+ - test/foreman_xen_test.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: f37dcf6c9110e2acf87ef685d655b24890cbc920
4
- data.tar.gz: 1be46948238513d6e9c1f11ef016e156a2c8ec07
5
- SHA512:
6
- metadata.gz: 4e08405948fc85e6251932fd9a20e6d0e903fa3abe06af8ed7d3402dfa887cdaac0ac9d6c35996115492a194fe719a750927b6676e283925523d92f7f6a6aa0b
7
- data.tar.gz: d958ac6baba71844c0f219d571851206527640e20b92a4cc6475becb89865c5440f80470daf7f9b448b039909911b911be250c0a5f36903f475b9bfd402f68ec