I have been testing the proposed package for jammy against the test plan
and I'm happy to report that it passes validation! See the steps I took
below.
---
Install terraform and LXD
sudo snap install terraform --classic
sudo snap install lxd
Make sure you're in the `lxd` group:
if ! getent group lxd | grep "$USER"; then
sudo usermod -aG lxd "$USER"
newgrp lxd
fi
If you've not already set up LXD do so now:
lxd init --minimal
Start up Landscape Server, enable autoregistration and get the
registration info.
Extract the benchmarking patch from the original test plan to a file
called `benchmark_patch.py`, which will add CPU profiling to package
reporter:
def main():
original_function = '''def _compute_packages_changes(self):'''
replacement_function = '''def _compute_packages_changes(self):
import cProfile
import pstats
from datetime import datetime
import psutil
profile = cProfile.Profile()
process = psutil.Process()
start_cpu_times = process.cpu_times()
profile.enable()
result = self.compute_packages_change_inner()
end_cpu_times = process.cpu_times()
profile.disable()
user_time = end_cpu_times.user - start_cpu_times.user
system_time = end_cpu_times.system - start_cpu_times.system
total_cpu_time = user_time + system_time
output_path = "/var/lib/landscape/client/result.txt"
with open(output_path, "a") as fp:
now = datetime.now()
fp.write(f"\\n--------- Run on: {now.strftime('%Y-%m-%d
%H:%M:%S')} ---------\\n\\n")
stats = pstats.Stats(profile, stream=fp)
stats.strip_dirs().sort_stats("cumulative").print_stats(10)
fp.write(f"CPU Time: {total_cpu_time}s\\n")
return result
def compute_packages_change_inner(self):'''
file_path = '/usr/lib/python3/dist-
packages/landscape/client/package/reporter.py'
try:
with open(file_path, 'r') as f:
content = f.read()
modified_content = content.replace(original_function,
replacement_function)
with open(file_path, 'w') as f:
f.write(modified_content)
except Exception as e:
print(f"Error adding benchmarking: {str(e)}")
if __name__ == "__main__":
main()
Create a file called `main.tf` and paste the following, making sure to
replace the server/pro info. This will create two jammy instances, one
with the proposed version of Landscape Client and one with the current
version in the jammy archives. It will copy over the
`benchmark_patch.py` file to both instances and run it to add the
profiling to package reporter:
module "landscape-client" {
source = "jansdhillon/landscape-client/lxd"
pro_token = "xxxxx" # replace with real pro token
account_name = "onward"
landscape_root_url = "10.1.77.207"
registration_key = "key"
image_alias = "jammy"
instances = [
{
client_config = {
computer_title = "jammy-lp2099283-proposed-validator"
ping_interval = 10
exchange_interval = 10
urgent_exchange_interval = 10
}
landscape_client_package = "landscape-
client=23.02-0ubuntu1~22.04.6"
files = [
{
content = <<EOT
Package: landscape-client landscape-common
Pin: release a=jammy-proposed
Pin-Priority: 600
EOT
target_path = "/etc/apt/preferences.d/proposed"
},
{
source_path = "./benchmark_patch.py"
target_path = "/tmp/benchmark_patch.py"
}
]
additional_cloud_init = <<EOT
#cloud-config
apt:
sources:
jammy-proposed:
source: "deb http://archive.ubuntu.com/ubuntu
jammy-proposed main restricted universe multiverse"
package-upgrades: true
packages:
- python3-psutil
runcmd:
- python3 /tmp/benchmark_patch.py && sleep 60
EOT
},
{
client_config = {
computer_title = "jammy-lp2099283-control-validator"
ping_interval = 10
exchange_interval = 10
urgent_exchange_interval = 10
}
landscape_client_package = "landscape-
client=23.02-0ubuntu1~22.04.4"
files = [
{
source_path = "./benchmark_patch.py"
target_path = "/tmp/benchmark_patch.py"
}
]
additional_cloud_init = <<EOT
#cloud-config
package-upgrades: true
packages:
- python3-psutil
runcmd:
- python3 /tmp/benchmark_patch.py && sleep 60
EOT
},
]
}
Initialize and apply the terraform plan:
terraform init && terraform apply -auto-approve
Once both machines have registered and run their benchmarks (apply
finishes), view the results:
printf "\njammy-lp2099283-proposed-validator: \n"
lxc exec jammy-lp2099283-proposed-validator -- cat
/var/lib/landscape/client/result.txt
printf "\njammy-lp2099283-control-validator (currently in archives): \n"
lxc exec jammy-lp2099283-control-validator -- cat
/var/lib/landscape/client/result.txt
Example output:
jammy-lp2099283-proposed-validator:
--------- Run on: 2025-09-16 00:40:25 ---------
2892510 function calls (2892506 primitive calls) in 3.308
seconds
Ordered by: cumulative time
List reduced from 86 to 10 due to restriction <10>
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.245 0.245 3.308 3.308
reporter.py:626(compute_packages_change_inner)
123190 0.083 0.000 2.424 0.000 store.py:146(get_hash_id)
123196 0.144 0.000 2.333 0.000 store.py:19(inner)
123190 0.101 0.000 2.137 0.000 store.py:49(get_hash_id)
123196 2.024 0.000 2.024 0.000 {method 'execute' of
'sqlite3.Cursor' objects}
1 0.000 0.000 0.394 0.394
facade.py:183(get_locked_packages)
1 0.025 0.025 0.394 0.394 facade.py:188(<listcomp>)
123647 0.054 0.000 0.369 0.000
facade.py:446(is_package_installed)
129593 0.030 0.000 0.300 0.000 package.py:453(__eq__)
129593 0.141 0.000 0.270 0.000 package.py:423(_cmp)
CPU Time: 3.240000000000001s
...
jammy-lp2099283-control-validator (currently in archives):
--------- Run on: 2025-09-16 00:40:46 ---------
2970716 function calls (2970712 primitive calls) in 33.562
seconds
Ordered by: cumulative time
List reduced from 137 to 10 due to restriction <10>
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.226 0.226 33.562 33.562
reporter.py:626(compute_packages_change_inner)
117326 0.200 0.000 30.032 0.000 package.py:726(origins)
159154 0.238 0.000 29.812 0.000 package.py:316(__init__)
159154 29.574 0.000 29.574 0.000 {method 'find_index' of
'apt_pkg.SourceList' objects}
116412 0.098 0.000 2.659 0.000 store.py:146(get_hash_id)
116418 0.166 0.000 2.549 0.000 store.py:19(inner)
116412 0.114 0.000 2.316 0.000 store.py:49(get_hash_id)
116418 2.188 0.000 2.188 0.000 {method 'execute' of
'sqlite3.Cursor' objects}
1 0.000 0.000 0.377 0.377
facade.py:183(get_locked_packages)
1 0.024 0.024 0.377 0.377 facade.py:188(<listcomp>)
CPU Time: 32.94s
These findings validate those in the original test plan, as we see a
performance improvement of over 10x in the proposed version in this
sample run.
Additionally, I was able to install a package, remove a package and
upgrade all packages on the proposed version, through Landscape Server.
Cleanup:
terraform destroy -auto-approve
TF module used: https://github.com/jansdhillon/terraform-lxd-landscape-
client/tree/main/examples/benchmark
** Tags removed: verification-needed-jammy
** Tags added: verification-done-jammy
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2099283
Title:
[SRU] Update Focal, Jammy, Noble, Oracular, Plucky, Questing to reduce
CPU usage of landscape-package-reporter
To manage notifications about this bug go to:
https://bugs.launchpad.net/landscape-client/+bug/2099283/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs