summaryrefslogtreecommitdiff
path: root/lib/chef/resource/kernel_module.rb
blob: 4f02e74166b3c0faaac3e8be85993044cf87a1f6 (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
#
# Resource:: kernel_module
#
# The MIT License (MIT)
#
# Copyright 2016-2018, Shopify Inc.
# Copyright 22018, Chef Software, Inc.

require "chef/resource"

class Chef
  class Resource
    class KernelModule < Chef::Resource
      resource_name :kernel_module
      provides(:kernel_module) { true }

      description "Use the kernel_module resource to manage kernel modules on Linux systems. This resource can load, unload, blacklist, install, and uninstall modules."
      introduced "15.0"

      property :modname, String,
               description: "The name of the kernel module.",
               name_property: true, identity: true

      property :load_dir, String,
               description: "The directory to load modules from.",
               default: "/etc/modules-load.d"

      property :unload_dir, String,
               description: "The modprobe.d directory.",
               default: "/etc/modprobe.d"

      action :install do
        description "Load kernel module, and ensure it loads on reboot"

        declare_resource(:directory, new_resource.load_dir) do
          recursive true
        end

        declare_resource(:file, "#{new_resource.load_dir}/#{new_resource.modname}.conf") do
          content "#{new_resource.modname}\n"
          notifies :run, "execute[update initramfs]"
        end

        declare_resource(:execute, "update initramfs") do
          command initramfs_command
          action :nothing
        end

        new_resource.run_action(:load)
      end

      action :uninstall do
        description "Unload a kernel module and remove module config, so it doesn't load on reboot."

        declare_resource(:file, "#{new_resource.load_dir}/#{new_resource.modname}.conf") do
          action :delete
          notifies :run, "execute[update initramfs]"
        end

        declare_resource(:file, "#{new_resource.unload_dir}/blacklist_#{new_resource.modname}.conf") do
          action :delete
          notifies :run, "execute[update initramfs]"
        end

        declare_resource(:execute, "update initramfs") do
          command initramfs_command
          action :nothing
        end

        new_resource.run_action(:unload)
      end

      action :blacklist do
        description "Blacklist a kernel module."

        declare_resource(:file, "#{new_resource.unload_dir}/blacklist_#{new_resource.modname}.conf") do
          content "blacklist #{new_resource.modname}"
          notifies :run, "execute[update initramfs]"
        end

        declare_resource(:execute, "update initramfs") do
          command initramfs_command
          action :nothing
        end

        new_resource.run_action(:unload)
      end

      action :load do
        description "Load a kernel module."

        unless module_loaded?
          converge_by("load kernel module #{new_resource.modname}") do
            shell_out!("modprobe #{new_resource.modname}")
          end
        end
      end

      action :unload do
        description "Unload kernel module"

        if module_loaded?
          converge_by("unload kernel module #{new_resource.modname}") do
            shell_out!("modprobe -r #{new_resource.modname}")
          end
        end
      end

      action_class do
        # determine the correct command to regen the initramfs based on platform
        # @return [String]
        def initramfs_command
          if platform_family?("debian")
            "update-initramfs -u"
          else
            "dracut -f"
          end
        end

        # see if the module is listed in /proc/modules or not
        # @return [Boolean]
        def module_loaded?
          /^#{new_resource.modname}/.match?(::File.read("/proc/modules"))
        end
      end
    end
  end
end