summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastermain
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster/toastermain')
-rw-r--r--bitbake/lib/toaster/toastermain/__init__.py0
-rw-r--r--bitbake/lib/toaster/toastermain/management/__init__.py0
-rw-r--r--bitbake/lib/toaster/toastermain/management/commands/__init__.py0
-rw-r--r--bitbake/lib/toaster/toastermain/management/commands/builddelete.py33
-rw-r--r--bitbake/lib/toaster/toastermain/management/commands/buildslist.py13
-rw-r--r--bitbake/lib/toaster/toastermain/management/commands/perf.py53
-rw-r--r--bitbake/lib/toaster/toastermain/settings.py304
-rw-r--r--bitbake/lib/toaster/toastermain/urls.py60
-rw-r--r--bitbake/lib/toaster/toastermain/wsgi.py35
9 files changed, 498 insertions, 0 deletions
diff --git a/bitbake/lib/toaster/toastermain/__init__.py b/bitbake/lib/toaster/toastermain/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/__init__.py
diff --git a/bitbake/lib/toaster/toastermain/management/__init__.py b/bitbake/lib/toaster/toastermain/management/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/management/__init__.py
diff --git a/bitbake/lib/toaster/toastermain/management/commands/__init__.py b/bitbake/lib/toaster/toastermain/management/commands/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/management/commands/__init__.py
diff --git a/bitbake/lib/toaster/toastermain/management/commands/builddelete.py b/bitbake/lib/toaster/toastermain/management/commands/builddelete.py
new file mode 100644
index 0000000000..5cec436714
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/management/commands/builddelete.py
@@ -0,0 +1,33 @@
1from django.core.management.base import BaseCommand, CommandError
2from orm.models import Build
3import os
4
5
6
7class Command(BaseCommand):
8 args = "buildId"
9 help = "Deletes selected build"
10
11 def handle(self, buildId, *args, **options):
12 b = Build.objects.get(pk = buildId)
13 # theoretically, just b.delete() would suffice
14 # however SQLite runs into problems when you try to
15 # delete too many rows at once, so we delete some direct
16 # relationships from Build manually.
17
18 for t in b.target_set.all():
19 t.delete()
20 for t in b.task_build.all():
21 t.delete()
22 for p in b.package_set.all():
23 p.delete()
24 for lv in b.layer_version_build.all():
25 lv.delete()
26 for v in b.variable_build.all():
27 v.delete()
28 for l in b.logmessage_set.all():
29 l.delete()
30
31 # this should take care of the rest
32 b.delete()
33
diff --git a/bitbake/lib/toaster/toastermain/management/commands/buildslist.py b/bitbake/lib/toaster/toastermain/management/commands/buildslist.py
new file mode 100644
index 0000000000..cad987fd93
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/management/commands/buildslist.py
@@ -0,0 +1,13 @@
1from django.core.management.base import NoArgsCommand, CommandError
2from orm.models import Build
3import os
4
5
6
7class Command(NoArgsCommand):
8 args = ""
9 help = "Lists current builds"
10
11 def handle_noargs(self,**options):
12 for b in Build.objects.all():
13 print "%d: %s %s %s" % (b.pk, b.machine, b.distro, ",".join([x.target for x in b.target_set.all()]))
diff --git a/bitbake/lib/toaster/toastermain/management/commands/perf.py b/bitbake/lib/toaster/toastermain/management/commands/perf.py
new file mode 100644
index 0000000000..d28f26ab16
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/management/commands/perf.py
@@ -0,0 +1,53 @@
1from django.core.management.base import BaseCommand
2from django.test.client import Client
3import os, sys, re
4import requests
5import toastermain.settings as settings
6
7class Command(BaseCommand):
8 help = "Test the response time for all toaster urls"
9
10 def handle(self, *args, **options):
11 root_urlconf = __import__(settings.ROOT_URLCONF)
12 patterns = root_urlconf.urls.urlpatterns
13 global full_url
14 for pat in patterns:
15 if pat.__class__.__name__ == 'RegexURLResolver':
16 url_root_res = str(pat).split('^')[1].replace('>', '')
17 if 'gui' in url_root_res:
18 for url_patt in pat.url_patterns:
19 full_url = self.get_full_url(url_patt, url_root_res)
20 info = self.url_info(full_url)
21 status_code = info[0]
22 load_time = info[1]
23 print 'Trying \'' + full_url + '\', ' + str(status_code) + ', ' + str(load_time)
24
25 def get_full_url(self, url_patt, url_root_res):
26 full_url = str(url_patt).split('^')[1].replace('$>', '').replace('(?P<file_path>(?:/[', '/bin/busybox').replace('.*', '')
27 full_url = str(url_root_res + full_url)
28 full_url = re.sub('\(\?P<.*?>\\\d\+\)', '1', full_url)
29 full_url = 'http://localhost:8000/' + full_url
30 return full_url
31
32 def url_info(self, full_url):
33 client = Client()
34 info = []
35 try:
36 resp = client.get(full_url, follow = True)
37 except Exception as e_status_code:
38 self.error('Url: %s, error: %s' % (full_url, e_status_code))
39 resp = type('object', (), {'status_code':0, 'content': str(e_status_code)})
40 status_code = resp.status_code
41 info.append(status_code)
42 try:
43 req = requests.get(full_url)
44 except Exception as e_load_time:
45 self.error('Url: %s, error: %s' % (full_url, e_load_time))
46 load_time = req.elapsed
47 info.append(load_time)
48 return info
49
50 def error(self, *args):
51 for arg in args:
52 print >>sys.stderr, arg,
53 print >>sys.stderr
diff --git a/bitbake/lib/toaster/toastermain/settings.py b/bitbake/lib/toaster/toastermain/settings.py
new file mode 100644
index 0000000000..42581f2df4
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/settings.py
@@ -0,0 +1,304 @@
1#
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# BitBake Toaster Implementation
6#
7# Copyright (C) 2013 Intel Corporation
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License along
19# with this program; if not, write to the Free Software Foundation, Inc.,
20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22# Django settings for Toaster project.
23
24DEBUG = True
25TEMPLATE_DEBUG = DEBUG
26
27ADMINS = (
28 # ('Your Name', 'your_email@example.com'),
29)
30
31MANAGERS = ADMINS
32
33DATABASES = {
34 'default': {
35 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
36 'NAME': 'toaster.sqlite', # Or path to database file if using sqlite3.
37 'USER': '',
38 'PASSWORD': '',
39 'HOST': '127.0.0.1', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
40 'PORT': '3306', # Set to empty string for default.
41 }
42}
43
44# Reinterpret database settings if we have DATABASE_URL environment variable defined
45import os, re
46
47if 'DATABASE_URL' in os.environ:
48 dburl = os.environ['DATABASE_URL']
49 if dburl.startswith('sqlite3://'):
50 result = re.match('sqlite3://(.*)', dburl)
51 if result is None:
52 raise Exception("ERROR: Could not read sqlite database url: %s" % dburl)
53 DATABASES['default'] = {
54 'ENGINE': 'django.db.backends.sqlite3',
55 'NAME': result.group(1),
56 'USER': '',
57 'PASSWORD': '',
58 'HOST': '',
59 'PORT': '',
60 }
61 elif dburl.startswith('mysql://'):
62 # URL must be in this form: mysql://user:pass@host:port/name
63 result = re.match(r"mysql://([^:]*):([^@]*)@([^:]*):(\d+)/([^/]*)", dburl)
64 if result is None:
65 raise Exception("ERROR: Could not read mysql database url: %s" % dburl)
66 DATABASES['default'] = {
67 'ENGINE': 'django.db.backends.mysql',
68 'NAME': result.group(5),
69 'USER': result.group(1),
70 'PASSWORD': result.group(2),
71 'HOST': result.group(3),
72 'PORT': result.group(4),
73 }
74 else:
75 raise Exception("FIXME: Please implement missing database url schema for url: %s" % dburl)
76
77
78if 'TOASTER_MANAGED' in os.environ and os.environ['TOASTER_MANAGED'] == "1":
79 MANAGED = True
80else:
81 MANAGED = False
82
83# Allows current database settings to be exported as a DATABASE_URL environment variable value
84
85def getDATABASE_URL():
86 d = DATABASES['default']
87 if d['ENGINE'] == 'django.db.backends.sqlite3':
88 if d['NAME'] == ':memory:':
89 return 'sqlite3://:memory:'
90 elif d['NAME'].startswith("/"):
91 return 'sqlite3://' + d['NAME']
92 return "sqlite3://" + os.path.join(os.getcwd(), d['NAME'])
93
94 elif d['ENGINE'] == 'django.db.backends.mysql':
95 return "mysql://" + d['USER'] + ":" + d['PASSWORD'] + "@" + d['HOST'] + ":" + d['PORT'] + "/" + d['NAME']
96
97 raise Exception("FIXME: Please implement missing database url schema for engine: %s" % d['ENGINE'])
98
99
100
101# Hosts/domain names that are valid for this site; required if DEBUG is False
102# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
103ALLOWED_HOSTS = []
104
105# Local time zone for this installation. Choices can be found here:
106# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
107# although not all choices may be available on all operating systems.
108# In a Windows environment this must be set to your system time zone.
109
110# Always use local computer's time zone, find
111import hashlib
112if 'TZ' in os.environ:
113 TIME_ZONE = os.environ['TZ']
114else:
115 # need to read the /etc/localtime file which is the libc standard
116 # and do a reverse-mapping to /usr/share/zoneinfo/;
117 # since the timezone may match any number of identical timezone definitions,
118
119 zonefilelist = {}
120 ZONEINFOPATH = '/usr/share/zoneinfo/'
121 for dirpath, dirnames, filenames in os.walk(ZONEINFOPATH):
122 for fn in filenames:
123 filepath = os.path.join(dirpath, fn)
124 zonename = filepath.lstrip(ZONEINFOPATH).strip()
125 try:
126 import pytz
127 from pytz.exceptions import UnknownTimeZoneError
128 pass
129 try:
130 if pytz.timezone(zonename) is not None:
131 zonefilelist[hashlib.md5(open(filepath).read()).hexdigest()] = zonename
132 except UnknownTimeZoneError, ValueError:
133 # we expect timezone failures here, just move over
134 pass
135 except ImportError:
136 zonefilelist[hashlib.md5(open(filepath).read()).hexdigest()] = zonename
137
138 TIME_ZONE = zonefilelist[hashlib.md5(open('/etc/localtime').read()).hexdigest()]
139
140# Language code for this installation. All choices can be found here:
141# http://www.i18nguy.com/unicode/language-identifiers.html
142LANGUAGE_CODE = 'en-us'
143
144SITE_ID = 1
145
146# If you set this to False, Django will make some optimizations so as not
147# to load the internationalization machinery.
148USE_I18N = True
149
150# If you set this to False, Django will not format dates, numbers and
151# calendars according to the current locale.
152USE_L10N = True
153
154# If you set this to False, Django will not use timezone-aware datetimes.
155USE_TZ = True
156
157# Absolute filesystem path to the directory that will hold user-uploaded files.
158# Example: "/var/www/example.com/media/"
159MEDIA_ROOT = ''
160
161# URL that handles the media served from MEDIA_ROOT. Make sure to use a
162# trailing slash.
163# Examples: "http://example.com/media/", "http://media.example.com/"
164MEDIA_URL = ''
165
166# Absolute path to the directory static files should be collected to.
167# Don't put anything in this directory yourself; store your static files
168# in apps' "static/" subdirectories and in STATICFILES_DIRS.
169# Example: "/var/www/example.com/static/"
170STATIC_ROOT = ''
171
172# URL prefix for static files.
173# Example: "http://example.com/static/", "http://static.example.com/"
174STATIC_URL = '/static/'
175
176# Additional locations of static files
177STATICFILES_DIRS = (
178 # Put strings here, like "/home/html/static" or "C:/www/django/static".
179 # Always use forward slashes, even on Windows.
180 # Don't forget to use absolute paths, not relative paths.
181)
182
183# List of finder classes that know how to find static files in
184# various locations.
185STATICFILES_FINDERS = (
186 'django.contrib.staticfiles.finders.FileSystemFinder',
187 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
188# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
189)
190
191# Make this unique, and don't share it with anybody.
192SECRET_KEY = 'NOT_SUITABLE_FOR_HOSTED_DEPLOYMENT'
193
194# List of callables that know how to import templates from various sources.
195TEMPLATE_LOADERS = (
196 'django.template.loaders.filesystem.Loader',
197 'django.template.loaders.app_directories.Loader',
198# 'django.template.loaders.eggs.Loader',
199)
200
201MIDDLEWARE_CLASSES = (
202 'django.middleware.common.CommonMiddleware',
203 'django.contrib.sessions.middleware.SessionMiddleware',
204 'django.middleware.csrf.CsrfViewMiddleware',
205 'django.contrib.auth.middleware.AuthenticationMiddleware',
206 'django.contrib.messages.middleware.MessageMiddleware',
207 # Uncomment the next line for simple clickjacking protection:
208 # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
209)
210
211ROOT_URLCONF = 'toastermain.urls'
212
213# Python dotted path to the WSGI application used by Django's runserver.
214WSGI_APPLICATION = 'toastermain.wsgi.application'
215
216TEMPLATE_DIRS = (
217 # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
218 # Always use forward slashes, even on Windows.
219 # Don't forget to use absolute paths, not relative paths.
220)
221
222TEMPLATE_CONTEXT_PROCESSORS = ('django.contrib.auth.context_processors.auth',
223 'django.core.context_processors.debug',
224 'django.core.context_processors.i18n',
225 'django.core.context_processors.media',
226 'django.core.context_processors.static',
227 'django.core.context_processors.tz',
228 'django.contrib.messages.context_processors.messages',
229 "django.core.context_processors.request",
230 'toastergui.views.managedcontextprocessor',
231 )
232
233INSTALLED_APPS = (
234 #'django.contrib.sites',
235 'django.contrib.staticfiles',
236 # Uncomment the next line to enable admin documentation:
237 # 'django.contrib.admindocs',
238 'django.contrib.humanize',
239 'orm',
240 'toastermain',
241 'south',
242)
243
244SOUTH_TESTS_MIGRATE = False
245
246# if we run in managed mode, we need user support
247if MANAGED:
248 INSTALLED_APPS = ('django.contrib.auth',
249 'django.contrib.contenttypes',
250 'django.contrib.messages',
251 'django.contrib.sessions',
252 # Uncomment the next line to enable the admin:
253 'django.contrib.admin',
254 ) + INSTALLED_APPS
255
256
257# We automatically detect and install applications here if
258# they have a 'models.py' or 'views.py' file
259import os
260currentdir = os.path.dirname(__file__)
261for t in os.walk(os.path.dirname(currentdir)):
262 modulename = os.path.basename(t[0])
263 if ("views.py" in t[2] or "models.py" in t[2]) and not modulename in INSTALLED_APPS:
264 INSTALLED_APPS = INSTALLED_APPS + (modulename,)
265
266# A sample logging configuration. The only tangible logging
267# performed by this configuration is to send an email to
268# the site admins on every HTTP 500 error when DEBUG=False.
269# See http://docs.djangoproject.com/en/dev/topics/logging for
270# more details on how to customize your logging configuration.
271LOGGING = {
272 'version': 1,
273 'disable_existing_loggers': False,
274 'filters': {
275 'require_debug_false': {
276 '()': 'django.utils.log.RequireDebugFalse'
277 }
278 },
279 'handlers': {
280 'mail_admins': {
281 'level': 'ERROR',
282 'filters': ['require_debug_false'],
283 'class': 'django.utils.log.AdminEmailHandler'
284 }
285 },
286 'loggers': {
287 'django.request': {
288 'handlers': ['mail_admins'],
289 'level': 'ERROR',
290 'propagate': True,
291 },
292 }
293}
294
295# If we're using sqlite, we need to tweak the performance a bit
296from django.db.backends.signals import connection_created
297def activate_synchronous_off(sender, connection, **kwargs):
298 if connection.vendor == 'sqlite':
299 cursor = connection.cursor()
300 cursor.execute('PRAGMA synchronous = 0;')
301connection_created.connect(activate_synchronous_off)
302#
303
304
diff --git a/bitbake/lib/toaster/toastermain/urls.py b/bitbake/lib/toaster/toastermain/urls.py
new file mode 100644
index 0000000000..1ae6245cc3
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/urls.py
@@ -0,0 +1,60 @@
1#
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# BitBake Toaster Implementation
6#
7# Copyright (C) 2013 Intel Corporation
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License along
19# with this program; if not, write to the Free Software Foundation, Inc.,
20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22from django.conf.urls import patterns, include, url
23from django.views.generic import RedirectView
24from django.views.decorators.cache import never_cache
25
26
27# Uncomment the next two lines to enable the admin:
28from django.contrib import admin
29admin.autodiscover()
30
31urlpatterns = patterns('',
32 # the api-s are not auto-discoverable
33 url(r'^api/1.0/', include('bldviewer.api')),
34
35 # Examples:
36 # url(r'^toaster/', include('toaster.foo.urls')),
37
38 # Uncomment the admin/doc line below to enable admin documentation:
39 # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
40
41
42 # if no application is selected, we have the magic toastergui app here
43 url(r'^$', never_cache(RedirectView.as_view(url='/toastergui/'))),
44)
45
46import toastermain.settings
47if toastermain.settings.MANAGED:
48 urlpatterns = urlpatterns + [
49 # Uncomment the next line to enable the admin:
50 url(r'^admin/', include(admin.site.urls)),
51 ]
52# Automatically discover urls.py in various apps, beside our own
53# and map module directories to the patterns
54
55import os
56currentdir = os.path.dirname(__file__)
57for t in os.walk(os.path.dirname(currentdir)):
58 if "urls.py" in t[2] and t[0] != currentdir:
59 modulename = os.path.basename(t[0])
60 urlpatterns.append( url(r'^' + modulename + '/', include ( modulename + '.urls')))
diff --git a/bitbake/lib/toaster/toastermain/wsgi.py b/bitbake/lib/toaster/toastermain/wsgi.py
new file mode 100644
index 0000000000..031b314b1a
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/wsgi.py
@@ -0,0 +1,35 @@
1"""
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5WSGI config for Toaster project.
6
7This module contains the WSGI application used by Django's development server
8and any production WSGI deployments. It should expose a module-level variable
9named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
10this application via the ``WSGI_APPLICATION`` setting.
11
12Usually you will have the standard Django WSGI application here, but it also
13might make sense to replace the whole Django WSGI application with a custom one
14that later delegates to the Django one. For example, you could introduce WSGI
15middleware here, or combine a Django application with an application of another
16framework.
17
18"""
19import os
20
21# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
22# if running multiple sites in the same mod_wsgi process. To fix this, use
23# mod_wsgi daemon mode with each site in its own daemon process, or use
24# os.environ["DJANGO_SETTINGS_MODULE"] = "Toaster.settings"
25os.environ.setdefault("DJANGO_SETTINGS_MODULE", "toastermain.settings")
26
27# This application object is used by any WSGI server configured to use this
28# file. This includes Django's development server, if the WSGI_APPLICATION
29# setting points here.
30from django.core.wsgi import get_wsgi_application
31application = get_wsgi_application()
32
33# Apply WSGI middleware here.
34# from helloworld.wsgi import HelloWorldApplication
35# application = HelloWorldApplication(application)