Skip to content

Commit

Permalink
daemon: auto-attach when pro license added on gcp
Browse files Browse the repository at this point in the history
  • Loading branch information
orndorffgrant committed Feb 7, 2022
1 parent dc131c2 commit c691cc7
Show file tree
Hide file tree
Showing 29 changed files with 981 additions and 13 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ by a string formatted as:

`<protocol>://[<username>:<password>@]<fqdn>:<port>`

### Pro Upgrade Daemon
UA client sets up a daemon on supported platforms (currently GCP only) to
detect if an Ubuntu Pro license is purchased for the machine. If a Pro license
is detected, then the machine is automatically attached.

If you are uninterested in UA services, you can safely stop and disable the
daemon using systemctl:

```
sudo systemctl stop ubuntu-advantage.service
sudo systemctl disable ubuntu-advantage.service
```

### Timer jobs
UA client sets up a systemd timer to run jobs that need to be executed recurrently.
The timer itself ticks every 5 minutes on average, and decides which jobs need
Expand Down
2 changes: 2 additions & 0 deletions debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ override_dh_systemd_enable:
dh_systemd_enable -pubuntu-advantage-tools ua-license-check.timer
dh_systemd_enable -pubuntu-advantage-tools ua-license-check.service
dh_systemd_enable -pubuntu-advantage-tools ua-license-check.path
dh_systemd_enable -pubuntu-advantage-tools ubuntu-advantage.service

override_dh_systemd_start:
dh_systemd_start -pubuntu-advantage-tools ua-timer.timer
dh_systemd_start -pubuntu-advantage-tools ua-license-check.path
dh_systemd_start -pubuntu-advantage-tools ubuntu-advantage.service

override_dh_auto_install:
dh_auto_install --destdir=debian/ubuntu-advantage-tools
Expand Down
1 change: 1 addition & 0 deletions debian/ubuntu-advantage-tools.postrm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ remove_logs(){
rm -f /var/log/ubuntu-advantage.log*
rm -f /var/log/ubuntu-advantage-timer.log*
rm -f /var/log/ubuntu-advantage-license-check.log*
rm -f /var/log/ubuntu-advantage-daemon.log*
}

remove_gpg_files(){
Expand Down
4 changes: 4 additions & 0 deletions features/attached_commands.feature
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ Feature: Command behaviour when attached to an UA subscription
And I run `sh -c "ls /var/log/ubuntu-advantage* | sort -d"` as non-root
Then stdout matches regexp:
"""
/var/log/ubuntu-advantage-daemon.log
/var/log/ubuntu-advantage.log
/var/log/ubuntu-advantage-timer.log
"""
When I run `logrotate --force /etc/logrotate.d/ubuntu-advantage-tools` with sudo
And I run `sh -c "ls /var/log/ubuntu-advantage* | sort -d"` as non-root
Then stdout matches regexp:
"""
/var/log/ubuntu-advantage-daemon.log.1
/var/log/ubuntu-advantage.log.1
/var/log/ubuntu-advantage-timer.log.1
"""
Expand Down Expand Up @@ -837,7 +839,9 @@ Feature: Command behaviour when attached to an UA subscription
ua-status.json
ua-timer.service.txt
ua-timer.timer.txt
ubuntu-advantage-daemon.log
ubuntu-advantage.log
ubuntu-advantage.service.txt
ubuntu-advantage-timer.log
ubuntu-esm-apps.list
ubuntu-esm-infra.list
Expand Down
228 changes: 228 additions & 0 deletions features/daemon.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
Feature: Pro Upgrade Daemon only runs in environments where necessary

@series.lts
@uses.config.contract_token
@uses.config.machine_type.gcp.generic
Scenario Outline: daemon should run when appropriate on gcp generic lts
Given a `<release>` machine with ubuntu-advantage-tools installed
# verify its enabled, but stops itself when not configured to poll
# TODO-BEGIN: remove this chunk once cloud-init supports this feature
When I run `touch /run/cloud-init/cloud-id-gce` with sudo
When I run `truncate -s 0 /var/log/ubuntu-advantage-daemon.log` with sudo
When I run `systemctl restart ubuntu-advantage.service` with sudo
# TODO-END: remove this chunk once cloud-init supports this feature
When I wait `1` seconds
When I run `cat /var/log/ubuntu-advantage-daemon.log` with sudo
Then stdout matches regexp:
"""
daemon starting
"""
Then stdout matches regexp:
"""
Configured to not poll for pro license, shutting down
"""
Then stdout matches regexp:
"""
daemon ending
"""
# verify it stays on when configured to do so
When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following:
"""
ua_config:
poll_for_pro_license: true
"""
When I run `truncate -s 0 /var/log/ubuntu-advantage-daemon.log` with sudo
When I run `systemctl restart ubuntu-advantage.service` with sudo
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `0`
Then stdout matches regexp:
"""
Active: active \(running\)
"""
When I run `cat /var/log/ubuntu-advantage-daemon.log` with sudo
Then stdout matches regexp:
"""
daemon starting
"""
Then stdout does not match regexp:
"""
daemon ending
"""
# verify attach tops it immediately and doesn't restart after reboot
When I attach `contract_token` with sudo
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
"""
When I reboot the `<release>` machine
# TODO-BEGIN: remove this chunk once cloud-init supports this feature
When I run `touch /run/cloud-init/cloud-id-gce` with sudo
When I run `truncate -s 0 /var/log/ubuntu-advantage-daemon.log` with sudo
When I run `systemctl restart ubuntu-advantage.service` with sudo
# TODO-END: remove this chunk once cloud-init supports this feature
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
\s*Condition: start condition failed
"""
# verify detach starts it and it starts again after reboot
When I run `truncate -s 0 /var/log/ubuntu-advantage-daemon.log` with sudo
When I run `ua detach --assume-yes` with sudo
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `0`
Then stdout matches regexp:
"""
Active: active \(running\)
"""
When I run `cat /var/log/ubuntu-advantage-daemon.log` with sudo
Then stdout matches regexp:
"""
daemon starting
"""
Then stdout does not match regexp:
"""
daemon ending
"""
When I reboot the `<release>` machine
# TODO-BEGIN: remove this chunk once cloud-init supports this feature
When I run `touch /run/cloud-init/cloud-id-gce` with sudo
When I run `truncate -s 0 /var/log/ubuntu-advantage-daemon.log` with sudo
When I run `systemctl restart ubuntu-advantage.service` with sudo
# TODO-END: remove this chunk once cloud-init supports this feature
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `0`
Then stdout matches regexp:
"""
Active: active \(running\)
"""
When I run `cat /var/log/ubuntu-advantage-daemon.log` with sudo
Then stdout matches regexp:
"""
daemon starting
"""
Then stdout does not match regexp:
"""
daemon ending
"""
# Verify manual stop & disable persists across reconfigure
When I run `systemctl stop ubuntu-advantage.service` with sudo
When I run `systemctl disable ubuntu-advantage.service` with sudo
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
"""
When I run `dpkg-reconfigure ubuntu-advantage-tools` with sudo
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
"""
# Verify manual stop & disable persists across reboot
When I reboot the `<release>` machine
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
"""
Examples: version
| release |
| xenial |
| bionic |
| focal |

@series.impish
@uses.config.contract_token
@uses.config.machine_type.gcp.generic
Scenario Outline: daemon does not start on gcp generic non lts
Given a `<release>` machine with ubuntu-advantage-tools installed
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
\s*Condition: start condition failed
"""
Then I verify that running `cat /var/log/ubuntu-advantage-daemon.log` `with sudo` exits `1`
When I attach `contract_token` with sudo
When I run `ua detach --assume-yes` with sudo
When I reboot the `<release>` machine
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
\s*Condition: start condition failed
"""
Then I verify that running `cat /var/log/ubuntu-advantage-daemon.log` `with sudo` exits `1`
Examples: version
| release |
| impish |

@series.all
@uses.config.contract_token
@uses.config.machine_type.lxd.container
@uses.config.machine_type.lxd.vm
@uses.config.machine_type.aws.generic
@uses.config.machine_type.azure.generic
Scenario Outline: daemon does not start when not on gcpgeneric
Given a `<release>` machine with ubuntu-advantage-tools installed
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
\s*Condition: start condition failed
"""
Then I verify that running `cat /var/log/ubuntu-advantage-daemon.log` `with sudo` exits `1`
When I attach `contract_token` with sudo
When I run `ua detach --assume-yes` with sudo
When I reboot the `<release>` machine
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
\s*Condition: start condition failed
"""
Then I verify that running `cat /var/log/ubuntu-advantage-daemon.log` `with sudo` exits `1`
Examples: version
| release |
| xenial |
| bionic |
| focal |
| impish |
| jammy |

@series.lts
@uses.config.machine_type.aws.pro
@uses.config.machine_type.azure.pro
@uses.config.machine_type.gcp.pro
Scenario Outline: daemon does not start when not on gcpgeneric
Given a `<release>` machine with ubuntu-advantage-tools installed
When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following:
"""
contract_url: 'https://contracts.canonical.com'
data_dir: /var/lib/ubuntu-advantage
log_level: debug
log_file: /var/log/ubuntu-advantage.log
"""
When I run `ua auto-attach` with sudo
When I run `systemctl restart ubuntu-advantage.service` with sudo
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
\s*Condition: start condition failed
"""
Then I verify that running `cat /var/log/ubuntu-advantage-daemon.log` `with sudo` exits `1`
When I attach `contract_token` with sudo
When I run `ua detach --assume-yes` with sudo
When I reboot the `<release>` machine
Then I verify that running `systemctl status ubuntu-advantage.service` `with sudo` exits `3`
Then stdout matches regexp:
"""
Active: inactive \(dead\)
\s*Condition: start condition failed
"""
Then I verify that running `cat /var/log/ubuntu-advantage-daemon.log` `with sudo` exits `1`
Examples: version
| release |
| xenial |
| bionic |
| focal |
10 changes: 6 additions & 4 deletions features/unattached_commands.feature
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ Feature: Command behaviour when unattached

@series.all
@uses.config.machine_type.lxd.container
Scenario Outline: Run collect-logs on an attached machine
Scenario Outline: Run collect-logs on an unattached machine
Given a `<release>` machine with ubuntu-advantage-tools installed
When I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
And I verify that running `ua collect-logs` `as non-root` exits `1`
Expand All @@ -500,7 +500,7 @@ Feature: Command behaviour when unattached
Then I verify that files exist matching `ua_logs.tar.gz`
When I run `tar zxf ua_logs.tar.gz` as non-root
Then I verify that files exist matching `logs/`
When I run `ls -1 logs/` as non-root
When I run `sh -c "ls -1 logs/ | sort -d"` as non-root
Then stdout matches regexp:
"""
build.info
Expand All @@ -511,16 +511,18 @@ Feature: Command behaviour when unattached
systemd-timers.txt
ua-auto-attach.path.txt-error
ua-auto-attach.service.txt-error
uaclient.conf
ua-license-check.path.txt
ua-license-check.service.txt
ua-license-check.timer.txt
ua-reboot-cmds.service.txt
ua-status.json
ua-timer.service.txt
ua-timer.timer.txt
uaclient.conf
ubuntu-advantage-timer.log
ubuntu-advantage.service.txt
ubuntu-advantage-daemon.log
ubuntu-advantage.log
ubuntu-advantage-timer.log
"""
Examples: ubuntu release
| release |
Expand Down
39 changes: 39 additions & 0 deletions lib/daemon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import logging
import sys

from systemd.daemon import notify # type: ignore

from uaclient import daemon
from uaclient.cli import setup_logging
from uaclient.config import UAConfig

LOG = logging.getLogger("ua")


def main() -> int:

cfg = UAConfig()
setup_logging(
logging.INFO, logging.DEBUG, log_file=cfg.daemon_log_file, logger=LOG
)
# The ua-daemon logger should log everything to its file
# Make sure the ua-daemon logger does not generate double logging
# by propagating to the root logger
LOG.propagate = False
# The root logger should only log errors to the daemon log file
setup_logging(
logging.CRITICAL, logging.ERROR, log_file=cfg.daemon_log_file
)

LOG.debug("daemon starting")

notify("READY=1")

daemon.poll_for_pro_license(cfg)

LOG.debug("daemon ending")
return 0


if __name__ == "__main__":
sys.exit(main())
Loading

0 comments on commit c691cc7

Please sign in to comment.