SaltStack State: DNF-Automatic



  • I wanted to add dnf-automatic to my serverhardening SaltStack State.

    I remembered that Jared posted a nice how-to on dnf-automatic, which I used to port to a simple SaltStack state.

    I verified functionality by first uninstalling dnf-automatic: dnf remove dnf-automatic, then verifying all is gone, including the timers, and then ran a highstate. I verified everything was again successfully in place.

    dnf-automatic:
      pkg.installed: []
    
    /etc/dnf/automatic.conf:
      file.managed:
        - user: root
        - group: root
        - mode: 644
        - source: salt://serverhardening/files/automatic.conf
        - require:
          - pkg: dnf-automatic
    
    /usr/lib/systemd/system/dnf-automatic-install.timer:
      file.managed:
        - user: root
        - group: root
        - mode: 644
        - source: salt://serverhardening/files/dnf-automatic-install.timer
        - require:
          - pkg: dnf-automatic
    
    dnf-automatic-install.timer:
      service.running:
        - enable: True
        - require:
          - file: /usr/lib/systemd/system/dnf-automatic-install.timer
    
    

    Early Xmas present for Jared:

    automatic.conf:

    [commands]
    #  What kind of upgrade to perform:
    # default                            = all available upgrades
    # security                           = only the security upgrades
    upgrade_type = default
    random_sleep = 300
    
    # To just receive updates use dnf-automatic-notifyonly.timer
    
    # Whether updates should be downloaded when they are available, by
    # dnf-automatic.timer. notifyonly.timer, download.timer and
    # install.timer override this setting.
    download_updates = yes
    
    # Whether updates should be applied when they are available, by
    # dnf-automatic.timer. notifyonly.timer, download.timer and
    # install.timer override this setting.
    apply_updates = yes
    
    
    [emitters]
    # Name to use for this system in messages that are emitted.  Default is the
    # hostname.
    # system_name = my-host
    
    # How to send messages.  Valid options are stdio, email and motd.  If
    # emit_via includes stdio, messages will be sent to stdout; this is useful
    # to have cron send the messages.  If emit_via includes email, this
    # program will send email itself according to the configured options.
    # If emit_via includes motd, /etc/motd file will have the messages. if
    # emit_via includes command_email, then messages will be send via a shell
    # command compatible with sendmail.
    # Default is email,stdio.
    # If emit_via is None or left blank, no messages will be sent.
    emit_via = email
    
    
    [email]
    # The address to send email messages from.
    email_from = [email protected]
    
    # List of addresses to send messages to.
    email_to = [email protected]
    
    # Name of the host to connect to to send email messages.
    email_host = localhost
    
    
    [command]
    # The shell command to execute. This is a Python format string, as used in
    # str.format(). The format function will pass a shell-quoted argument called
    # `body`.
    # command_format = "cat"
    
    # The contents of stdin to pass to the command. It is a format string with the
    # same arguments as `command_format`.
    # stdin_format = "{body}"
    
    
    [command_email]
    # The shell command to use to send email. This is a Python format string,
    # as used in str.format(). The format function will pass shell-quoted arguments
    # called body, subject, email_from, email_to.
    # command_format = "mail -s {subject} -r {email_from} {email_to}"
    
    # The contents of stdin to pass to the command. It is a format string with the
    # same arguments as `command_format`.
    # stdin_format = "{body}"
    
    # The address to send email messages from.
    email_from = [email protected]
    
    # List of addresses to send messages to.
    email_to = root
    
    
    [base]
    # This section overrides dnf.conf
    
    # Use this to filter DNF core messages
    debuglevel = 1
    

    dnf-automatic-install.timer:

    [Unit]
    Description=dnf-automatic-install timer
    # See comment in dnf-makecache.service
    ConditionPathExists=!/run/ostree-booted
    
    [Timer]
    OnBootSec=1h
    OnUnitInactiveSec=6h
    
    [Install]
    WantedBy=basic.target
    


  • @tim_g said in SaltStack State: DNF-Automatic:

    I won't post the config and timer files, those are easy enough to get.

    That defeats the purpose of a simple guide. Your want to provide 100% of the pieces someone needs to do something when you make a guide like this.

    This kinds of stuff is why I almost always have to make my own guides for things (and post them here). Because half the shit on the net is missing pieces like this.

    When I am looking for something like this, I will choose the Google result that has everything I need in one good guide instead of using 5 different ones jsut to get all the pieces of information.



  • If you're already using Salt, why use dnf-automatic? Just schedule Salt to do the updates. Here's what I do nightly for my DNS servers. It runs serially so one is up while the other is updating. You also have all of your update logs in one place this way.

    ---
    - name: Update playbook
      hosts: dns_servers
      user: centos
      become: true
      gather_facts: true
      serial: 1   
    
      tasks:
        - block:
          - name: update packages
            package:
              name: '*'
              state: latest
          - name: reboot servers
            shell: sleep 2 && /sbin/shutdown -r now "Ansible system upgraded"
            async: 1
            poll: 0
            ignore_errors: true
    
          - name: wait for server to come back
            wait_for:
              host: "{{ openstack.networks.private[1] }}"
              port: 22
              delay: 10
            delegate_to: localhost
    
          - name: Send Slack notification
            slack:
              token: "{{ slack_token }}"
              channel: #ansible
              msg: "Updates completed on {{ openstack.name }} successfully"
            delegate_to: localhost
    
          rescue:
            - name: fail
              slack:
                token: "{{ slack_token }}"
                channel: #ansible
                msg: "Updates on {{ openstack.name }} failed"
              delegate_to: localhost
    


  • @jaredbusch said in SaltStack State: DNF-Automatic:

    @tim_g said in SaltStack State: DNF-Automatic:

    I won't post the config and timer files, those are easy enough to get.

    That defeats the purpose of a simple guide. Your want to provide 100% of the pieces someone needs to do something when you make a guide like this.

    This kinds of stuff is why I almost always have to make my own guides for things (and post them here). Because half the shit on the net is missing pieces like this.

    When I am looking for something like this, I will choose the Google result that has everything I need in one good guide instead of using 5 different ones jsut to get all the pieces of information.

    Maybe I'm alone in that I like to grab config files myself even if they're posted to make sure I'm using the correct and latest one.

    But you do make a good a point. I'll add them to my OP in a bit.



  • @tim_g said in SaltStack State: DNF-Automatic:

    Maybe I'm alone in that I like to grab config files myself even if they're posted to make sure I'm using the correct and latest one.

    This would be the default one that comes down with the package. So that means there is nothing to grab.

    In this case your state should just be editing an existing and not "grabbing" anything.



  • @jaredbusch said in SaltStack State: DNF-Automatic:

    @tim_g said in SaltStack State: DNF-Automatic:

    Maybe I'm alone in that I like to grab config files myself even if they're posted to make sure I'm using the correct and latest one.

    In this case your state should just be editing an existing and not "grabbing" anything.

    That's why I like Salt config files (as an easy example). You can leave the default config files in place untouched, and include your own custom config files, and it will use that to overwrite the defaults.

    However with dnf-automatic, I'm not aware of it having that capability. I also didn't bother to check. I do prefer to host config files on my GitLab server and use those.

    If there's a way to look for and pick out certain bits of a config file, and change those to something specified in a file on GitLab (via Salt), I'd prefer doing it that way. But I haven't gotten that far yet, if there is.

    My plan is to be able to fully set up my VPS host 100% in all aspects via Salt and GitLab, and my Fedora Linux Desktop clients along the way.

    Once I accomplish that, I will be able to dive deeper into things. And perhaps that will be one of those I touch before others.



  • @jaredbusch said in SaltStack State: DNF-Automatic:

    This would be the default one that comes down with the package. So that means there is nothing to grab.

    Correct. I installed it on something first to get the config files, so I know what I'm working with.



  • @tim_g said in SaltStack State: DNF-Automatic:

    @jaredbusch said in SaltStack State: DNF-Automatic:

    This would be the default one that comes down with the package. So that means there is nothing to grab.

    Correct. I installed it on something first to get the config files, so I know what I'm working with.

    That is more work and does nothing to help you when the file is updated upstream.



  • @jaredbusch said in SaltStack State: DNF-Automatic:

    @tim_g said in SaltStack State: DNF-Automatic:

    @jaredbusch said in SaltStack State: DNF-Automatic:

    This would be the default one that comes down with the package. So that means there is nothing to grab.

    Correct. I installed it on something first to get the config files, so I know what I'm working with.

    That is more work...

    Not with salt. I get the config file, then I can use it on 10,000 machines instantly.



  • @jaredbusch said in SaltStack State: DNF-Automatic:

    ...and does nothing to help you when the file is updated upstream.

    I realized that going into this thing. I know that for the time being, the present config file "should" be fine for now until I'm finished and can learn more as I mentioned earlier. If the config file would change in a future update, I doubt it would be significant enough to matter, at least in my specific case for the near future.

    It's great and works well as-is to get things going and into gear.



  • The point of this topic was that if you are using Salt, and want to quickly get dnf-automatic installed, configured, and working... it will get that done.

    Feel free to make any other adjustments you see fit in your own environment.



  • Added files to original post.



  • @jaredbusch said in SaltStack State: DNF-Automatic:

    @tim_g said in SaltStack State: DNF-Automatic:

    @jaredbusch said in SaltStack State: DNF-Automatic:

    This would be the default one that comes down with the package. So that means there is nothing to grab.

    Correct. I installed it on something first to get the config files, so I know what I'm working with.

    That is more work and does nothing to help you when the file is updated upstream.

    I did find how to easily modify files with SaltStack: https://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.file.html#salt.modules.file.replace

    But I think I would still rather host my own config file(s) at least for now. If they change in future updates, I'll just modify the config files on GitLab.

    Anyways, link above for future reference when I come back to this later.