blob: b61de58a3e552b0af027c39069e07943990498ff [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001from django.db import models
2from django.core.validators import MaxValueValidator, MinValueValidator
3from orm.models import Project, ProjectLayer, ProjectVariable, ProjectTarget, Build
4
5# a BuildEnvironment is the equivalent of the "build/" directory on the localhost
6class BuildEnvironment(models.Model):
7 SERVER_STOPPED = 0
8 SERVER_STARTED = 1
9 SERVER_STATE = (
10 (SERVER_STOPPED, "stopped"),
11 (SERVER_STARTED, "started"),
12 )
13
14 TYPE_LOCAL = 0
15 TYPE_SSH = 1
16 TYPE = (
17 (TYPE_LOCAL, "local"),
18 (TYPE_SSH, "ssh"),
19 )
20
21 LOCK_FREE = 0
22 LOCK_LOCK = 1
23 LOCK_RUNNING = 2
24 LOCK_STATE = (
25 (LOCK_FREE, "free"),
26 (LOCK_LOCK, "lock"),
27 (LOCK_RUNNING, "running"),
28 )
29
30 address = models.CharField(max_length = 254)
31 betype = models.IntegerField(choices = TYPE)
32 bbaddress = models.CharField(max_length = 254, blank = True)
33 bbport = models.IntegerField(default = -1)
34 bbtoken = models.CharField(max_length = 126, blank = True)
35 bbstate = models.IntegerField(choices = SERVER_STATE, default = SERVER_STOPPED)
36 sourcedir = models.CharField(max_length = 512, blank = True)
37 builddir = models.CharField(max_length = 512, blank = True)
38 lock = models.IntegerField(choices = LOCK_STATE, default = LOCK_FREE)
39 created = models.DateTimeField(auto_now_add = True)
40 updated = models.DateTimeField(auto_now = True)
41
42
43 def get_artifact_type(self, path):
44 if self.betype == BuildEnvironment.TYPE_LOCAL:
45 try:
46 import magic
47
48 # fair warning: this is a mess; there are multiple competeing and incompatible
49 # magic modules floating around, so we try some of the most common combinations
50
51 try: # we try ubuntu's python-magic 5.4
52 m = magic.open(magic.MAGIC_MIME_TYPE)
53 m.load()
54 return m.file(path)
55 except AttributeError:
56 pass
57
58 try: # we try python-magic 0.4.6
59 m = magic.Magic(magic.MAGIC_MIME)
60 return m.from_file(path)
61 except AttributeError:
62 pass
63
64 try: # we try pip filemagic 1.6
65 m = magic.Magic(flags=magic.MAGIC_MIME_TYPE)
66 return m.id_filename(path)
67 except AttributeError:
68 pass
69
70 return "binary/octet-stream"
71 except ImportError:
72 return "binary/octet-stream"
73 raise Exception("FIXME: artifact type not implemented for build environment type %s" % self.get_betype_display())
74
75
76 def get_artifact(self, path):
77 if self.betype == BuildEnvironment.TYPE_LOCAL:
78 return open(path, "r")
79 raise Exception("FIXME: artifact download not implemented for build environment type %s" % self.get_betype_display())
80
81 def has_artifact(self, path):
82 import os
83 if self.betype == BuildEnvironment.TYPE_LOCAL:
84 return os.path.exists(path)
85 raise Exception("FIXME: has artifact not implemented for build environment type %s" % self.get_betype_display())
86
87# a BuildRequest is a request that the scheduler will build using a BuildEnvironment
88# the build request queue is the table itself, ordered by state
89
90class BuildRequest(models.Model):
91 REQ_CREATED = 0
92 REQ_QUEUED = 1
93 REQ_INPROGRESS = 2
94 REQ_COMPLETED = 3
95 REQ_FAILED = 4
96 REQ_DELETED = 5
97 REQ_ARCHIVE = 6
98
99 REQUEST_STATE = (
100 (REQ_CREATED, "created"),
101 (REQ_QUEUED, "queued"),
102 (REQ_INPROGRESS, "in progress"),
103 (REQ_COMPLETED, "completed"),
104 (REQ_FAILED, "failed"),
105 (REQ_DELETED, "deleted"),
106 (REQ_ARCHIVE, "archive"),
107 )
108
109 search_allowed_fields = ("brtarget__target", "build__project__name")
110
111 project = models.ForeignKey(Project)
112 build = models.OneToOneField(Build, null = True) # TODO: toasterui should set this when Build is created
113 environment = models.ForeignKey(BuildEnvironment, null = True)
114 state = models.IntegerField(choices = REQUEST_STATE, default = REQ_CREATED)
115 created = models.DateTimeField(auto_now_add = True)
116 updated = models.DateTimeField(auto_now = True)
117
118 def get_duration(self):
119 return (self.updated - self.created).total_seconds()
120
121 def get_sorted_target_list(self):
122 tgts = self.brtarget_set.order_by( 'target' );
123 return( tgts );
124
125 def get_machine(self):
126 return self.brvariable_set.get(name="MACHINE").value
127
128 def __str__(self):
129 return "%s %s" % (self.project, self.get_state_display())
130
131# These tables specify the settings for running an actual build.
132# They MUST be kept in sync with the tables in orm.models.Project*
133
134class BRLayer(models.Model):
135 req = models.ForeignKey(BuildRequest)
136 name = models.CharField(max_length = 100)
137 giturl = models.CharField(max_length = 254)
138 commit = models.CharField(max_length = 254)
139 dirpath = models.CharField(max_length = 254)
140
141class BRBitbake(models.Model):
142 req = models.ForeignKey(BuildRequest, unique = True) # only one bitbake for a request
143 giturl = models.CharField(max_length =254)
144 commit = models.CharField(max_length = 254)
145 dirpath = models.CharField(max_length = 254)
146
147class BRVariable(models.Model):
148 req = models.ForeignKey(BuildRequest)
149 name = models.CharField(max_length=100)
150 value = models.TextField(blank = True)
151
152class BRTarget(models.Model):
153 req = models.ForeignKey(BuildRequest)
154 target = models.CharField(max_length=100)
155 task = models.CharField(max_length=100, null=True)
156
157class BRError(models.Model):
158 req = models.ForeignKey(BuildRequest)
159 errtype = models.CharField(max_length=100)
160 errmsg = models.TextField()
161 traceback = models.TextField()
162
163 def __str__(self):
164 return "%s (%s)" % (self.errmsg, self.req)