Skip to content

Commit

Permalink
Make provider upgradable; Add logic to correctly switch between channels
Browse files Browse the repository at this point in the history
  • Loading branch information
root-expert committed Sep 11, 2024
1 parent 0ce158c commit 366e5f3
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 14 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,19 @@ package { 'hello-world':
install_options => ['classic'],
}
```

Same applies for options `jailmode` and `devmode`

This snippet
```puppet
package { 'hello-world':
ensure => latest,
provider => 'snap',
install_options => ['classic'],
}
```

installs by default the `latest/stable` channel

## Reference

See [REFERENCE](https://github.com/root-expert/puppet-snap/blob/master/REFERENCE.md)
Expand Down
59 changes: 46 additions & 13 deletions lib/puppet/provider/package/snap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,68 @@
"

commands snap_cmd: '/usr/bin/snap'
has_feature :installable, :versionable, :install_options, :uninstallable, :purgeable
has_feature :installable, :versionable, :install_options, :uninstallable, :purgeable, :upgradeable
confine feature: %i[net_http_unix_lib snapd_socket]

def self.instances
Puppet.info('called instances')
@installed_snaps ||= installed_snaps
Puppet.info("installed_snaps = #{@installed_snaps}")
@installed_snaps.map do |snap|
new(name: snap['name'], ensure: snap['tracking-channel'], provider: 'snap')
end
end

def query
installed = self.class.instances.find { |it| it.name == @resource['name'] }
if installed
{ ensure: installed[:ensure], name: @resource[:name] }
else
{ ensure: :absent, name: @resource[:name] }
end
end

def latest
query&.get(:ensure)
Puppet.info('called query')
installed = @installed_snaps&.find { |it| it.name == @resource['name'] }
Puppet.info("installed #{installed}")
{ ensure: installed.ensure, name: @resource[:name] } if installed
end

def install
modify_snap('install')
Puppet.info('called install')
current_ensure = query&.dig(:ensure)
current_ensure ||= :absent

Puppet.info("current_ensure = #{current_ensure}")
# Refresh the snap if we changed the channel
if current_ensure != @resource[:ensure] && current_ensure != :absent
Puppet.info('modify snap')
modify_snap('refresh') # Refresh will switch the channel AND trigger a refresh immediately. TODO Implement switch?
else
Puppet.info('install snap')
modify_snap('install')
end
end

def update
modify_snap('switch')
install
end

def latest
Puppet.info('called latest')
params = URI.encode_www_form(name: @resource[:name])
res = PuppetX::Snap::API.get("/v2/find?#{params}")

raise Puppet::Error, "Couldn't find latest version" if res['status-code'] != 200

# Search latest version for the specified channel. If channel is unspecified, fallback to latest/stable
channel = if @resource[:install_options].nil?
'latest/stable'
else
self.class.parse_channel(@resource[:install_options])
end

Puppet.info("channel = #{channel}")
selected_channel = res['result'].first&.dig('channels', channel)
Puppet.info("selected_channel = #{selected_channel}")
raise Puppet::Error, "No version in channel #{channel}" unless selected_channel

Puppet.info('Evaluating version')
Puppet.info("version = #{selected_channel['version']}")
# Return version
selected_channel['version']
end

def uninstall
Expand Down
37 changes: 37 additions & 0 deletions spec/acceptance/01_snapd_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,41 @@
end
end
end

describe 'purges the package' do
let(:manifest) do
<<-PUPPET
package { 'hello-world':
ensure => purged,
provider => snap,
}
PUPPET
end

it_behaves_like 'an idempotent resource'

describe command('snap list --unicode=never --color=never') do
its(:stdout) { is_expected.not_to match(%r{hello-world}) }
end
end

describe 'installs latest/stable when ensure: latest' do
let(:manifest) do
<<-PUPPET
package { 'hello-world':
ensure => latest,
provider => snap,
}
PUPPET
end

it_behaves_like 'an idempotent resource'

describe command('snap list --unicode=never --color=never') do
its(:stdout) do
is_expected.to match(%r{hello-world})
is_expected.to match(%r{stable})
end
end
end
end
1 change: 1 addition & 0 deletions spec/unit/puppet/provider/package/snap_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
it { is_expected.to be_install_options }
it { is_expected.to be_uninstallable }
it { is_expected.to be_purgeable }
it { is_expected.to be_upgradable }
end

context 'should respond to' do
Expand Down

0 comments on commit 366e5f3

Please sign in to comment.