Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch window not respected #97

Open
franck-iaropoli-arm opened this issue Jul 17, 2024 · 4 comments
Open

Patch window not respected #97

franck-iaropoli-arm opened this issue Jul 17, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@franck-iaropoli-arm
Copy link

franck-iaropoli-arm commented Jul 17, 2024

Describe the Bug

Hi all,
I am struggling to understand why my patch window is not respected when using patching_as_code module.
For example I have a node with 2 patch schedules assigned:
Extract of fact patching_as_code_config on that machine:

  patch_schedule => {
    friday => {
      count_of_week => [
        1,
        2,
        3,
        4,
        5
      ],
      day_of_week => "Friday",
      hours => "09:00 - 12:00",
      max_runs => 4,
      reboot => "never"
    },
    wednesday => {
      count_of_week => [
        1,
        2,
        3,
        4,
        5
      ],
      day_of_week => "Wednesday",
      hours => "09:00 - 12:00",
      max_runs => 4,
      reboot => "never"
    }
  },

I want this node to be patched between 9h and 12h on Wednesday and Fridays but patching happened very early this Wednesday (last_patch_run => "2024-07-17 01:04")

This is fact patching_as_code:

{
  choco_patches_installed_on_last_high_prio_run => [

  ],
  choco_patches_installed_on_last_run => [

  ],
  days_since_last_high_prio_patch_run => 0,
  days_since_last_patch_run => 0,
  last_high_prio_patch_run => "",
  last_patch_run => "2024-07-17 01:04",
  patches_installed_on_last_high_prio_run => [

  ],
  patches_installed_on_last_run => [
    "python3.8",
    "libpython3.8",
    "libpython3.8-stdlib",
    "python3.8-minimal",
    "libpython3.8-minimal",
    "firefox",
    "ghostscript-x",
    "ghostscript",
    "libgs9",
    "libgs9-common",
    "linux-headers-5.4.0-189",
    "linux-headers-5.4.0-189-generic",
    "linux-headers-generic",
    "linux-libc-dev"
  ]
}

In the apt history.log:

Start-Date: 2024-07-17  00:28:03
Commandline: /usr/bin/apt-get -q -y -o DPkg::Options::=--force-confold install python3.8
Upgrade: libpython3.8-minimal:amd64 (3.8.10-0ubuntu1~20.04.9, 3.8.10-0ubuntu1~20.04.10), libpython3.8:amd64 (3.8.10-0ubuntu1~20.04.9, 3.8.10-0ubuntu1~20.04.10), python3.8:amd64 (3.8.10-0ubuntu1~20.04.9, 3.8.10-0ubuntu1~20.04.10), python3.8-minimal:amd64 (3.8.10-0ubuntu1~20.04.9, 3.8.10-0ubuntu1~20.04.10), libpython3.8-stdlib:amd64 (3.8.10-0ubuntu1~20.04.9, 3.8.10-0ubuntu1~20.04.10)
End-Date: 2024-07-17  00:28:07

Start-Date: 2024-07-17  00:33:12
Commandline: /usr/bin/apt-get -q -y -o DPkg::Options::=--force-confold install firefox
Upgrade: firefox:amd64 (127.0.2+build1-0ubuntu0.20.04.1, 128.0+build2-0ubuntu0.20.04.1)
End-Date: 2024-07-17  00:33:21

Start-Date: 2024-07-17  00:38:23
Commandline: /usr/bin/apt-get -q -y -o DPkg::Options::=--force-confold install ghostscript-x
Upgrade: libgs9:amd64 (9.50~dfsg-5ubuntu4.12, 9.50~dfsg-5ubuntu4.13), ghostscript:amd64 (9.50~dfsg-5ubuntu4.12, 9.50~dfsg-5ubuntu4.13), ghostscript-x:amd64 (9.50~dfsg-5ubuntu4.12, 9.50~dfsg-5ubuntu4.13), libgs9-common:amd64 (9.50~dfsg-5ubuntu4.12, 9.50~dfsg-5ubuntu4.13)
End-Date: 2024-07-17  00:38:25

Start-Date: 2024-07-17  00:43:28
Commandline: /usr/bin/apt-get -q -y -o DPkg::Options::=--force-confold install linux-headers-5.4.0-189
Install: linux-headers-5.4.0-189:amd64 (5.4.0-189.209)
End-Date: 2024-07-17  00:43:32

Start-Date: 2024-07-17  00:48:33
Commandline: /usr/bin/apt-get -q -y -o DPkg::Options::=--force-confold install linux-headers-5.4.0-189-generic
Install: linux-headers-5.4.0-189-generic:amd64 (5.4.0-189.209)
End-Date: 2024-07-17  00:48:35

Start-Date: 2024-07-17  00:53:37
Commandline: /usr/bin/apt-get -q -y -o DPkg::Options::=--force-confold install linux-headers-generic
Upgrade: linux-headers-generic:amd64 (5.4.0.187.185, 5.4.0.189.187)
End-Date: 2024-07-17  00:53:37

Start-Date: 2024-07-17  00:58:39
Commandline: /usr/bin/apt-get -q -y -o DPkg::Options::=--force-confold install linux-libc-dev
Upgrade: linux-libc-dev:amd64 (5.4.0-187.207, 5.4.0-189.209)
End-Date: 2024-07-17  00:58:40

*** command from post patching script ***

Start-Date: 2024-07-17  01:04:48
Commandline: /usr/bin/apt-get -y autoremove
Remove: libnatpmp1:amd64 (20150609-7build1), linux-headers-5.4.0-187:amd64 (5.4.0-187.207), libsysmetrics1:amd64 (1.6.1ubuntu0.1), linux-headers-5.4.0-187-generic:amd64 (5.4.0-187.207), libevent-2.1-7:amd64 (2.1.11-stable-1)
End-Date: 2024-07-17  01:04:50

Date and time are correct on the machine:

~# date
Wed 17 Jul 2024 11:26:17 AM CEST

~# timedatectl 
               Local time: Wed 2024-07-17 11:26:28 CEST
           Universal time: Wed 2024-07-17 09:26:28 UTC 
                 RTC time: Wed 2024-07-17 09:26:28     
                Time zone: Europe/Paris (CEST, +0200)  
System clock synchronized: yes                         
              NTP service: n/a                         
          RTC in local TZ: no                          

Offset detection seems correct too:

~# facter -p patching_as_code_utc_offset
2.0

Why was patching done on Wednesday but around 00:28 and not during the patch schedule window I set:

      day_of_week => "Wednesday",
      hours => "09:00 - 12:00",

?

Expected Behavior

Patches are installed between 9h and 12h on Wednesdays, Fridays

Steps to Reproduce

Set a patch schedule between 9h and 12h

Environment

  • Version 1.1.7
  • Platform Ubuntu 20.04 (I have also done the same setup on different OS and different days. I will update this case if it happens with other OS)
@franck-iaropoli-arm franck-iaropoli-arm added the bug Something isn't working label Jul 17, 2024
@Boxx1483
Copy link

It seems that the "is_patchday.pp" is the only check if patch run should be executed. That is indeed not efficient, because it is only checking weekdays with patchwindow range.

I have another module calling this module, where I've implemented a ruby function that checks if, the patch is actually in the patchwindow before executing patching_as_code.

@franck-iaropoli-arm
Copy link
Author

Thanks @Boxx1483 but is it not the role of process_patch_groups function (functions/process_patch_groups.pp) to setup schedule based on hours set in your patch group schedule?
Reading https://www.puppet.com/docs/puppet/7/types/schedule

"Currently, schedules can only be used to stop a resource from being applied; they cannot cause a resource to be applied when it otherwise wouldn't be, and they cannot accurately specify a time when a resource should run."

Can it be the reason why I am having this issue? Do I need to play with repeat value?

@Boxx1483
Copy link

Boxx1483 commented Aug 13, 2024

You are right, that seems to be the right function.
I've just tried to reproduce with max_runs/repeat set to 1, and it is indeed starting outside the patchwindow. I'm not 100% sure how max_runs/repeat is supposed to work. I'd assume it's amount of patch runs in a single window.
I've also tested this, but it will just continue to run multiple times in the same patch-window, even if max_runs/repeat is set to 1.

As said I've implemented a ruby function, in a module that calls patching_as_code class. That function checks the actual hour window. Code is pasted below.
manifests/init.pp
$is_patch_schedule_now = patchmanagement::is_within_hour_window($primary_schedule)
lib/puppet/functions/module_name/is_within_hour_window.rb


  Puppet::Functions.create_function(:'module_name::is_within_hour_window') do
    dispatch :is_within_hour_window do
      param 'Hash', :patch_schedule_hash
    end

  def is_within_hour_window(patch_schedule_hash) # rubocop:disable Naming/PredicateName
    time_now = Time.now # Variable to call .hour and .min from
    start_hour = patch_schedule_hash['start_hour']
    start_minute = patch_schedule_hash['start_minute']
    end_hour = patch_schedule_hash['end_hour']
    end_minute = patch_schedule_hash['end_minute']
    # all dates are just a generic date, it's only the hour calculus that is important, so ignore the 2024/04/18

    current_time_date = DateTime.new(2024, 4, 18, time_now.hour, time_now.min, 0o0)
    start_time_date = DateTime.new(2024, 4, 18, start_hour, start_minute, 0o0)
    end_time_date = DateTime.new(2024, 4, 18, end_hour, end_minute, 0o0)

    current_time_date.between?(start_time_date, end_time_date)
  end
end

This is quite a hack, I'm not sure how this would fit into patching_as_code.
Hope this helps somehow.

@Boxx1483
Copy link

Seems here #88
That max_runs is indeed not controlling amount of patch runs within a window

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants