Revision 4dddae29

b/admin/static/main.js
1 1
$(function() {
2
	$("table.id-sorted").tablesorter({ sortList: [[0, 0]] });
2
	$('table.id-sorted').tablesorter({ sortList: [[0, 0]] });
3

  
4
	$('tr.row-template').hide();
5
});
6

  
7
$('.add-row').live('click', function() {
8
	template = $('tr.row-template');
9
	row = template.clone();
10
	row.removeClass('row-template');
11
	row.show();
12
	template.parent().append(row);
13
});
14

  
15
$('.delete-row').live('click', function() {
16
	$(this).parents('tr').remove();
3 17
});
b/admin/templates/images_info.html
1 1
{% extends "base.html" %}
2 2

  
3 3
{% block body %}
4

  
5 4
<form action="/admin/images/{{ image.id }}/modify" method="post">
6
  <div class="clearfix">
7
    <label for="image-id">ID</label>
8
    <div class="input">
9
      <span class="uneditable-input" id="image-id">{{ image.id }}</span>
10
    </div>
11
  </div>
5
  <div class="row">
6
    <div class="span7 columns">
12 7

  
13
  <div class="clearfix">
14
    <label for="image-name">Name</label>
15
    <div class="input">
16
      <input class="medium" id="image-name" name="name" value="{{ image.name }}" type="text" />
17
    </div>
18
  </div>
8
      <div class="clearfix">
9
        <label for="image-id">ID</label>
10
        <div class="input">
11
          <span class="uneditable-input" id="image-id">{{ image.id }}</span>
12
        </div>
13
      </div>
19 14

  
20
  <div class="clearfix">
21
    <label for="image-state">State</label>
22
    <div class="input">
23
      <select class="medium" id="image-state" name="state">
24
        {% for state in states %}
25
        <option{% ifequal state image.state %} selected{% endifequal %}>{{ state }}</option>
26
        {% endfor %}
27
      </select>
28
    </div>
29
  </div>
15
      <div class="clearfix">
16
        <label for="image-name">Name</label>
17
        <div class="input">
18
          <input class="medium" id="image-name" name="name" value="{{ image.name }}" type="text" />
19
        </div>
20
      </div>
30 21

  
31
  <div class="clearfix">
32
    <label for="image-owner">Owner ID</label>
33
    <div class="input">
34
      <input class="small" id="image-owner" name="owner" value="{{ image.owner.id }}" type="text" />
35
    </div>
36
  </div>
22
      <div class="clearfix">
23
        <label for="image-state">State</label>
24
        <div class="input">
25
          <select class="medium" id="image-state" name="state">
26
            {% for state in states %}
27
            <option{% ifequal state image.state %} selected{% endifequal %}>{{ state }}</option>
28
            {% endfor %}
29
          </select>
30
        </div>
31
      </div>
37 32

  
38
  <div class="clearfix">
39
    <label for="image-sourcevm">Virtual Machine ID</label>
40
    <div class="input">
41
      <input class="small" id="image-sourcevm" name="sourcevm" value="{{ image.sourcevm.id }}" type="text" />
42
    </div>
43
  </div>
33
      <div class="clearfix">
34
        <label for="image-owner">Owner ID</label>
35
        <div class="input">
36
          <input class="small" id="image-owner" name="owner" value="{{ image.owner.id }}" type="text" />
37
        </div>
38
      </div>
44 39

  
45
  <div class="clearfix">
46
    <label for="image-backend">Backend ID</label>
47
    <div class="input">
48
      <input class="large" id="image-backend" name="backend" value="{{ image.backend_id }}" type="text" />
49
    </div>
50
  </div>
40
      <div class="clearfix">
41
        <label for="image-sourcevm">Virtual Machine ID</label>
42
        <div class="input">
43
          <input class="small" id="image-sourcevm" name="sourcevm" value="{{ image.sourcevm.id }}" type="text" />
44
        </div>
45
      </div>
51 46

  
52
  <div class="clearfix">
53
    <label for="image-format">Format</label>
54
    <div class="input">
55
      <select class="medium" id="image-format" name="format">
56
        {% for format in formats %}
57
        <option{% ifequal format image.format %} selected{% endifequal %}>{{ format }}</option>
58
        {% endfor %}
59
      </select>
60
    </div>
61
  </div>
47
      <div class="clearfix">
48
        <label for="image-backend">Backend ID</label>
49
        <div class="input">
50
          <input class="large" id="image-backend" name="backend" value="{{ image.backend_id }}" type="text" />
51
        </div>
52
      </div>
62 53

  
63
  <div class="clearfix">
64
    <label for="image-format">Public</label>
65
    <div class="input">
66
      <ul class="inputs-list">
67
        <li>
68
          <label>
69
            <input type="checkbox" id="image-public" name="public"{% if image.public %} checked{% endif %}>
70
          </label>
71
        </li>
72
      </ul>
73
    </div>
74
  </div>
54
      <div class="clearfix">
55
        <label for="image-format">Format</label>
56
        <div class="input">
57
          <select class="medium" id="image-format" name="format">
58
            {% for format in formats %}
59
            <option{% ifequal format image.format %} selected{% endifequal %}>{{ format }}</option>
60
            {% endfor %}
61
          </select>
62
        </div>
63
      </div>
64

  
65
      <div class="clearfix">
66
        <label for="image-format">Public</label>
67
        <div class="input">
68
          <ul class="inputs-list">
69
            <li>
70
              <label>
71
                <input type="checkbox" id="image-public" name="public"{% if image.public %} checked{% endif %}>
72
              </label>
73
            </li>
74
          </ul>
75
        </div>
76
      </div>
77

  
78
      <div class="clearfix">
79
        <label for="image-created">Created</label>
80
        <div class="input">
81
          <span class="uneditable-input" id="image-created">{{ image.created }}</span>
82
        </div>
83
      </div>
75 84

  
76
  <div class="clearfix">
77
    <label for="image-created">Created</label>
78
    <div class="input">
79
      <span class="uneditable-input" id="image-created">{{ image.created }}</span>
85
      <div class="clearfix">
86
        <label for="image-updated">Updated</label>
87
        <div class="input">
88
          <span class="uneditable-input" id="image-updated">{{ image.updated }}</span>
89
        </div>
90
      </div>
80 91
    </div>
81
  </div>
82 92

  
83
  <div class="clearfix">
84
    <label for="image-updated">Updated</label>
85
    <div class="input">
86
      <span class="uneditable-input" id="image-updated">{{ image.updated }}</span>
93
    <div class="span7 columns offset1">
94
      <table>
95
        <thead>
96
          <tr>
97
            <th>Key</th>
98
            <th>Value</th>
99
            <th></th>
100
          </tr>
101
        </thead>
102
        <tbody>
103
          <tr class="row-template">
104
            <td><input class="medium" type="text" name="key"></td>
105
            <td><input class="medium" type="text" name="value"></td>
106
            <td><a class="btn danger delete-row"><strong>-</strong></a></td>
107
          </tr>
108
          {% for meta in metadata %}
109
          <tr>
110
            <td><input type="text" class="medium" name="key" value="{{ meta.meta_key }}"></td>
111
            <td><input type="text" class="medium" name="value" value="{{ meta.meta_value }}"></td>
112
            <td><a class="btn danger delete-row"><strong>-</strong></a></td>
113
          </tr>
114
          {% endfor %}
115
        </tbody>
116
      </table>
117
      <a class="btn success add-row"><strong>+</strong></a>
87 118
    </div>
88 119
  </div>
89 120

  
......
92 123
    <button type="reset" class="btn">Reset</button>
93 124
  </div>
94 125
</form>
95

  
96 126
{% endblock body %}
b/admin/views.py
27 27
    stats['ganeti_instances'] = len(backend.get_ganeti_instances())
28 28
    stats['ganeti_nodes'] = len(backend.get_ganeti_nodes())
29 29
    stats['ganeti_jobs'] = len(backend.get_ganeti_jobs())
30
    
30

  
31 31
    images = []
32 32
    for image in models.Image.objects.exclude(state='DELETED'):
33 33
        vms = models.VirtualMachine.objects.filter(sourceimage=image)
......
103 103
    formats = [x[0] for x in models.Image.FORMATS]
104 104
    if not image.format:
105 105
        formats = [''] + formats
106
    
107
    metadata = image.imagemetadata_set.order_by('meta_key')
106 108
    html = render('images_info.html', 'images',
107
                    image=image, states=states, formats=formats)
109
                    image=image,
110
                    states=states,
111
                    formats=formats,
112
                    metadata=metadata)
108 113
    return HttpResponse(html)
109 114

  
110 115
def images_modify(request, image_id):
......
119 124
    image.format = request.POST.get('format')
120 125
    image.public = True if request.POST.get('public') else False
121 126
    image.save()
127
    
128
    keys = request.POST.getlist('key')
129
    vals = request.POST.getlist('value')
130
    meta = dict(zip(keys, vals))
131
    image.imagemetadata_set.all().delete()
132
    for key, val in meta.items():
133
        if key:
134
            image.imagemetadata_set.create(meta_key=key, meta_value=val)
135
    
122 136
    return redirect(images_info, image.id)
123 137

  
124

  
125 138
def servers_list(request):
126 139
    vms = models.VirtualMachine.objects.order_by('id')
127 140
    html = render('servers_list.html', 'servers', vms=vms)

Also available in: Unified diff