-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Save package relations and collect installed packages from client.
- Loading branch information
Showing
3 changed files
with
87 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,23 @@ | ||
from django.contrib import admin | ||
from django.db import models | ||
from django.forms import widgets | ||
|
||
from mountain.packages.models import Package, PackageRelation | ||
|
||
|
||
class RelationInline(admin.TabularInline): | ||
model = PackageRelation | ||
extra = 0 | ||
formfield_overrides = { | ||
models.TextField: {'widget': widgets.TextInput}, | ||
} | ||
|
||
from mountain.packages.models import * | ||
|
||
class PackageAdmin(admin.ModelAdmin): | ||
list_display = ('name', 'summary', 'section', 'type') | ||
list_filter = ('section',) | ||
ordering = ('name',) | ||
search_fields = ('name',) | ||
inlines = [RelationInline] | ||
|
||
admin.site.register(PackageHash, PackageAdmin) | ||
admin.site.register(Package, PackageAdmin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,58 @@ | ||
from django.db import models | ||
|
||
from landscape.package import skeleton | ||
|
||
from mountain.core.models import Computer | ||
|
||
class PackageHashManager(models.Manager): | ||
|
||
TYPE_CHOICES = ( | ||
(skeleton.DEB_PACKAGE, 'Package'), | ||
(skeleton.DEB_PROVIDES, 'Provides'), | ||
(skeleton.DEB_NAME_PROVIDES, 'Name provides'), | ||
(skeleton.DEB_REQUIRES, 'Requires'), | ||
(skeleton.DEB_OR_REQUIRES, 'Or Requires'), | ||
(skeleton.DEB_UPGRADES, 'Upgrades'), | ||
(skeleton.DEB_CONFLICTS, 'Conflicts'), | ||
) | ||
|
||
STATUS_CHOICES = ( | ||
(0, 'installed'), | ||
(1, 'available'), | ||
(2, 'available-upgrades'), | ||
(3, 'locked'), | ||
) | ||
|
||
class PackageManager(models.Manager): | ||
def hashes_in_bulk(self, id_list): | ||
qs = self.model.objects.filter(hash__in=id_list) | ||
return dict((obj.hash, obj) for obj in qs.iterator()) | ||
|
||
class PackageHash(models.Model): | ||
|
||
class Package(models.Model): | ||
hash = models.CharField(max_length=40, db_index=True, unique=True) | ||
name = models.CharField(max_length=255) | ||
summary = models.CharField(max_length=255) | ||
version = models.CharField(max_length=255) | ||
description = models.TextField() | ||
installed_size = models.IntegerField(null=True) | ||
size = models.IntegerField() | ||
type = models.IntegerField() | ||
type = models.IntegerField(choices=TYPE_CHOICES) | ||
section = models.CharField(max_length=255) | ||
|
||
objects = PackageHashManager() | ||
objects = PackageManager() | ||
|
||
class Meta: | ||
verbose_name = "Package hash" | ||
verbose_name_plural = "Package hashes" | ||
verbose_name = 'Package' | ||
verbose_name_plural = 'Packages' | ||
|
||
|
||
class PackageRelation(models.Model): | ||
package = models.ForeignKey(Package) | ||
type = models.IntegerField(choices=TYPE_CHOICES) | ||
target = models.TextField() | ||
|
||
|
||
class PackageStatus(models.Model): | ||
computer = models.ForeignKey(Computer) | ||
package = models.ForeignKey(Package) | ||
status = models.IntegerField(choices=STATUS_CHOICES) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,55 @@ | ||
from mountain.core.signals import message_available | ||
from mountain.core.utils import MessageType | ||
from mountain.packages.models import PackageHash | ||
from mountain.packages.models import Package, PackageRelation, PackageStatus, STATUS_CHOICES | ||
from mountain.packages.utils import get_hash | ||
|
||
def handle_unknown_hashes(sender, computer, request_data, msg_data, **kwargs): | ||
hashes = [i.encode('hex') for i in msg_data['hashes']] | ||
data = PackageHash.objects.hashes_in_bulk(hashes) | ||
data = Package.objects.hashes_in_bulk(hashes) | ||
ids = [(data.get(hash).id if data.get(hash) else None) for hash in hashes] | ||
return [{'type': 'package-ids', 'ids':ids, 'request-id':msg_data['request-id']}] | ||
|
||
def handle_add_packages(sender, computer, request_data, msg_data, **kwargs): | ||
ids = [] | ||
for p in msg_data['packages']: | ||
hash = get_hash(p['type'], p['name'], p['version'], p['relations']) | ||
m = PackageHash(hash = hash) | ||
m = Package(hash=hash) | ||
for i in ('name', 'summary', 'version', 'description', | ||
'installed-size', 'size', 'type', 'section'): | ||
setattr(m, i.replace('-', '_'), p.get(i)) | ||
m.save() | ||
for relation in p['relations']: | ||
PackageRelation.objects.create(package=m, type=relation[0], | ||
target=relation[1]) | ||
ids.append(m.id) | ||
|
||
return [{'type': 'package-ids', 'ids':ids, 'request-id':msg_data['request-id']}] | ||
|
||
message_available.connect(handle_unknown_hashes, sender=MessageType("unknown-package-hashes")) | ||
message_available.connect(handle_add_packages, sender=MessageType("add-packages")) | ||
STATUS_TO_ID = dict(map(lambda x: x[::-1], STATUS_CHOICES)) | ||
|
||
def handle_packages(sender, computer, request_data, msg_data, **kwargs): | ||
for status in ('installed', 'available', 'available-upgrades', 'locked'): | ||
ids = [] | ||
remove_ids = [] | ||
|
||
for remove in (False, True): | ||
s = status if not remove else 'not-%s' % status | ||
for id_or_range in msg_data.get(s, []): | ||
ids_ = ids if not remove else remove_ids | ||
if isinstance(id_or_range, tuple): | ||
ids_.extend(range(id_or_range[0], id_or_range[1]+1)) | ||
else: | ||
ids_.append(id_or_range) | ||
|
||
for id in ids: | ||
PackageStatus.objects.create(computer=computer, | ||
package_id=id, status=STATUS_TO_ID[status]) | ||
if remove_ids: | ||
PackageStatus.objects.delete(computer=computer, | ||
package_id__in=remove_ids) | ||
|
||
return [] | ||
|
||
message_available.connect(handle_unknown_hashes, sender=MessageType('unknown-package-hashes')) | ||
message_available.connect(handle_add_packages, sender=MessageType('add-packages')) | ||
message_available.connect(handle_packages, sender=MessageType('packages')) |