Merge ~cjwatson/launchpad:merge-db-stable into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 2d74e12bc176de9e6cd12bf90a2ba23b3abb6375
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:merge-db-stable
Merge into: launchpad:master
Diff against target: 325 lines (+234/-0)
3 files modified
database/schema/patch-2210-33-0.sql (+203/-0)
database/schema/security.cfg (+27/-0)
lib/lp/registry/personmerge.py (+4/-0)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+404273@code.launchpad.net

Commit message

Merge db-stable 2d74e12bc1 (Add charm recipe tables)

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) wrote :

Deployed to the production database today.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/database/schema/patch-2210-33-0.sql b/database/schema/patch-2210-33-0.sql
2new file mode 100644
3index 0000000..e0966d9
4--- /dev/null
5+++ b/database/schema/patch-2210-33-0.sql
6@@ -0,0 +1,203 @@
7+-- Copyright 2021 Canonical Ltd. This software is licensed under the
8+-- GNU Affero General Public License version 3 (see the file LICENSE).
9+
10+SET client_min_messages=ERROR;
11+
12+CREATE TABLE CharmRecipe (
13+ id serial PRIMARY KEY,
14+ date_created timestamp without time zone DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC') NOT NULL,
15+ date_last_modified timestamp without time zone DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC') NOT NULL,
16+ registrant integer NOT NULL REFERENCES person,
17+ owner integer NOT NULL REFERENCES person,
18+ project integer NOT NULL REFERENCES product,
19+ name text NOT NULL,
20+ description text,
21+ git_repository integer REFERENCES gitrepository,
22+ git_path text,
23+ build_path text,
24+ require_virtualized boolean DEFAULT true NOT NULL,
25+ information_type integer NOT NULL,
26+ access_policy integer,
27+ access_grants integer[],
28+ auto_build boolean DEFAULT false NOT NULL,
29+ auto_build_channels jsonb,
30+ is_stale boolean DEFAULT true NOT NULL,
31+ store_upload boolean DEFAULT false NOT NULL,
32+ store_name text,
33+ store_secrets text,
34+ store_channels jsonb,
35+ CONSTRAINT valid_name CHECK (valid_name(name)),
36+ CONSTRAINT consistent_git_ref CHECK (
37+ (git_repository IS NULL) = (git_path IS NULL)),
38+ CONSTRAINT consistent_store_upload CHECK (
39+ NOT store_upload OR store_name IS NOT NULL)
40+);
41+
42+COMMENT ON TABLE CharmRecipe IS 'A charm recipe.';
43+COMMENT ON COLUMN CharmRecipe.registrant IS 'The person who registered this charm recipe.';
44+COMMENT ON COLUMN CharmRecipe.owner IS 'The owner of this charm recipe.';
45+COMMENT ON COLUMN CharmRecipe.project IS 'The project that this charm recipe belongs to.';
46+COMMENT ON COLUMN CharmRecipe.name IS 'The name of the charm recipe, unique per owner and project.';
47+COMMENT ON COLUMN CharmRecipe.description IS 'A description of the charm recipe.';
48+COMMENT ON COLUMN CharmRecipe.git_repository IS 'A Git repository with a branch containing a charmcraft.yaml recipe.';
49+COMMENT ON COLUMN CharmRecipe.git_path IS 'The path of the Git branch containing a charmcraft.yaml recipe.';
50+COMMENT ON COLUMN CharmRecipe.build_path IS 'Subdirectory within the branch containing charmcraft.yaml.';
51+COMMENT ON COLUMN CharmRecipe.require_virtualized IS 'If True, this snap package must be built only on a virtual machine.';
52+COMMENT ON COLUMN CharmRecipe.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine how to apply an access policy.';
53+COMMENT ON COLUMN CharmRecipe.auto_build IS 'Whether this charm recipe is built automatically when its branch changes.';
54+COMMENT ON COLUMN CharmRecipe.auto_build_channels IS 'A dictionary mapping snap names to channels to use when building this charm recipe.';
55+COMMENT ON COLUMN CharmRecipe.is_stale IS 'True if this charm recipe has not been built since a branch was updated.';
56+COMMENT ON COLUMN CharmRecipe.store_upload IS 'Whether builds of this charm recipe are automatically uploaded to the store.';
57+COMMENT ON COLUMN CharmRecipe.store_name IS 'The registered name of this charm in the store.';
58+COMMENT ON COLUMN CharmRecipe.store_secrets IS 'Serialized secrets issued by the store and the login service to authorize uploads of this charm.';
59+COMMENT ON COLUMN CharmRecipe.store_channels IS 'Channels to release this charm to after uploading it to the store.';
60+
61+CREATE UNIQUE INDEX charmrecipe__owner__project__name__key
62+ ON CharmRecipe (owner, project, name);
63+
64+CREATE INDEX charmrecipe__registrant__idx
65+ ON CharmRecipe (registrant);
66+CREATE INDEX charmrecipe__project__idx
67+ ON CharmRecipe (project);
68+CREATE INDEX charmrecipe__git_repository__idx
69+ ON CharmRecipe (git_repository);
70+CREATE INDEX charmrecipe__store_name__idx
71+ ON CharmRecipe (store_name);
72+
73+CREATE TABLE CharmRecipeBuild (
74+ id serial PRIMARY KEY,
75+ build_request integer NOT NULL REFERENCES job,
76+ requester integer NOT NULL REFERENCES person,
77+ recipe integer NOT NULL REFERENCES charmrecipe,
78+ distro_arch_series integer NOT NULL REFERENCES distroarchseries,
79+ channels jsonb,
80+ processor integer NOT NULL REFERENCES processor,
81+ virtualized boolean NOT NULL,
82+ date_created timestamp without time zone DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC') NOT NULL,
83+ date_started timestamp without time zone,
84+ date_finished timestamp without time zone,
85+ date_first_dispatched timestamp without time zone,
86+ builder integer REFERENCES builder,
87+ status integer NOT NULL,
88+ log integer REFERENCES libraryfilealias,
89+ upload_log integer REFERENCES libraryfilealias,
90+ dependencies text,
91+ failure_count integer DEFAULT 0 NOT NULL,
92+ build_farm_job integer NOT NULL REFERENCES buildfarmjob,
93+ revision_id text,
94+ store_upload_json_data jsonb
95+);
96+
97+COMMENT ON TABLE CharmRecipeBuild IS 'A build record for a charm recipe.';
98+COMMENT ON COLUMN CharmRecipeBuild.build_request IS 'The build request that caused this build to be created.';
99+COMMENT ON COLUMN CharmRecipeBuild.requester IS 'The person who requested this charm recipe build.';
100+COMMENT ON COLUMN CharmRecipeBuild.recipe IS 'The charm recipe to build.';
101+COMMENT ON COLUMN CharmRecipeBuild.distro_arch_series IS 'The distroarchseries that the charm recipe should build from.';
102+COMMENT ON COLUMN CharmRecipeBuild.channels IS 'A dictionary mapping snap names to channels to use for this build.';
103+COMMENT ON COLUMN CharmRecipeBuild.processor IS 'The processor that the charm recipe should be built for.';
104+COMMENT ON COLUMN CharmRecipeBuild.virtualized IS 'The virtualization setting required by this build farm job.';
105+COMMENT ON COLUMN CharmRecipeBuild.date_created IS 'When the build farm job record was created.';
106+COMMENT ON COLUMN CharmRecipeBuild.date_started IS 'When the build farm job started being processed.';
107+COMMENT ON COLUMN CharmRecipeBuild.date_finished IS 'When the build farm job finished being processed.';
108+COMMENT ON COLUMN CharmRecipeBuild.date_first_dispatched IS 'The instant the build was dispatched the first time. This value will not get overridden if the build is retried.';
109+COMMENT ON COLUMN CharmRecipeBuild.builder IS 'The builder which processed this build farm job.';
110+COMMENT ON COLUMN CharmRecipeBuild.status IS 'The current build status.';
111+COMMENT ON COLUMN CharmRecipeBuild.log IS 'The log file for this build farm job stored in the librarian.';
112+COMMENT ON COLUMN CharmRecipeBuild.upload_log IS 'The upload log file for this build farm job stored in the librarian.';
113+COMMENT ON COLUMN CharmRecipeBuild.dependencies IS 'A Debian-like dependency line specifying the current missing dependencies for this build.';
114+COMMENT ON COLUMN CharmRecipeBuild.failure_count IS 'The number of consecutive failures on this job. If excessive, the job may be terminated.';
115+COMMENT ON COLUMN CharmRecipeBuild.build_farm_job IS 'The build farm job with the base information.';
116+COMMENT ON COLUMN CharmRecipeBuild.revision_id IS 'The revision ID of the branch used for this build, if available.';
117+COMMENT ON COLUMN CharmRecipeBuild.store_upload_json_data IS 'Data that is related to the process of uploading a build to the store.';
118+
119+CREATE INDEX charmrecipebuild__build_request__idx
120+ ON CharmRecipeBuild (build_request);
121+CREATE INDEX charmrecipebuild__requester__idx
122+ ON CharmRecipeBuild (requester);
123+CREATE INDEX charmrecipebuild__recipe__idx
124+ ON CharmRecipeBuild (recipe);
125+CREATE INDEX charmrecipebuild__distro_arch_series__idx
126+ ON CharmRecipeBuild (distro_arch_series);
127+CREATE INDEX charmrecipebuild__log__idx
128+ ON CharmRecipeBuild (log);
129+CREATE INDEX charmrecipebuild__upload_log__idx
130+ ON CharmRecipeBuild (upload_log);
131+CREATE INDEX charmrecipebuild__build_farm_job__idx
132+ ON CharmRecipeBuild (build_farm_job);
133+
134+-- CharmRecipe.requestBuild
135+CREATE INDEX charmrecipebuild__recipe__das__status__idx
136+ ON CharmRecipeBuild (recipe, distro_arch_series, status);
137+
138+-- CharmRecipe.builds, CharmRecipe.completed_builds,
139+-- CharmRecipe.pending_builds
140+CREATE INDEX charmrecipebuild__recipe__status__started__finished__created__id__idx
141+ ON CharmRecipeBuild (
142+ recipe, status, GREATEST(date_started, date_finished) DESC NULLS LAST,
143+ date_created DESC, id DESC);
144+
145+-- CharmRecipeBuild.getMedianBuildDuration
146+CREATE INDEX charmrecipebuild__recipe__das__status__finished__idx
147+ ON CharmRecipeBuild (recipe, distro_arch_series, status, date_finished DESC)
148+ -- 1 == FULLYBUILT
149+ WHERE status = 1;
150+
151+CREATE TABLE CharmFile (
152+ id serial PRIMARY KEY,
153+ build integer NOT NULL REFERENCES charmrecipebuild,
154+ library_file integer NOT NULL REFERENCES libraryfilealias
155+);
156+
157+COMMENT ON TABLE CharmFile IS 'A link between a charm recipe build and a file in the librarian that it produces.';
158+COMMENT ON COLUMN CharmFile.build IS 'The charm recipe build producing this file.';
159+COMMENT ON COLUMN CharmFile.library_file IS 'A file in the librarian.';
160+
161+CREATE INDEX charmfile__build__idx
162+ ON CharmFile (build);
163+CREATE INDEX charmfile__library_file__idx
164+ ON CharmFile (library_file);
165+
166+CREATE TABLE CharmRecipeJob (
167+ job integer PRIMARY KEY REFERENCES job ON DELETE CASCADE NOT NULL,
168+ recipe integer NOT NULL REFERENCES charmrecipe,
169+ job_type integer NOT NULL,
170+ json_data jsonb NOT NULL
171+);
172+
173+COMMENT ON TABLE CharmRecipeJob IS 'Contains references to jobs that are executed for a charm recipe.';
174+COMMENT ON COLUMN CharmRecipeJob.job IS 'A reference to a Job row that has all the common job details.';
175+COMMENT ON COLUMN CharmRecipeJob.recipe IS 'The charm recipe that this job is for.';
176+COMMENT ON COLUMN CharmRecipeJob.job_type IS 'The type of a job, such as a build request.';
177+COMMENT ON COLUMN CharmRecipeJob.json_data IS 'Data that is specific to a particular job type.';
178+
179+CREATE INDEX charmrecipejob__recipe__job_type__job__idx
180+ ON CharmRecipeJob (recipe, job_type, job);
181+
182+CREATE TABLE CharmRecipeBuildJob (
183+ job integer PRIMARY KEY REFERENCES job ON DELETE CASCADE NOT NULL,
184+ build integer REFERENCES charmrecipebuild NOT NULL,
185+ job_type integer NOT NULL,
186+ json_data jsonb NOT NULL
187+);
188+
189+COMMENT ON TABLE CharmRecipeBuildJob IS 'Contains references to jobs that are executed for a build of a charm recipe.';
190+COMMENT ON COLUMN CharmRecipeBuildJob.job IS 'A reference to a Job row that has all the common job details.';
191+COMMENT ON COLUMN CharmRecipeBuildJob.build IS 'The charm recipe build that this job is for.';
192+COMMENT ON COLUMN CharmRecipeBuildJob.job_type IS 'The type of a job, such as a store upload.';
193+COMMENT ON COLUMN CharmRecipeBuildJob.json_data IS 'Data that is specific to a particular job type.';
194+
195+CREATE INDEX charmrecipebuildjob__build__job_type__job__idx
196+ ON CharmRecipeBuildJob(build, job_type, job);
197+
198+ALTER TABLE Webhook ADD COLUMN charm_recipe integer REFERENCES CharmRecipe;
199+
200+ALTER TABLE Webhook DROP CONSTRAINT one_target;
201+ALTER TABLE Webhook
202+ ADD CONSTRAINT one_target CHECK (
203+ null_count(ARRAY[git_repository, branch, snap, livefs, oci_recipe,
204+ charm_recipe]) = 5);
205+
206+CREATE INDEX webhook__charm_recipe__id__idx
207+ ON Webhook (charm_recipe, id) WHERE charm_recipe IS NOT NULL;
208+
209+INSERT INTO LaunchpadDatabaseRevision VALUES (2210, 33, 0);
210diff --git a/database/schema/security.cfg b/database/schema/security.cfg
211index 8225ec9..8ea0482 100644
212--- a/database/schema/security.cfg
213+++ b/database/schema/security.cfg
214@@ -154,6 +154,11 @@ public.bugtrackercomponentgroup = SELECT, INSERT, UPDATE
215 public.bugtrackerperson = SELECT, UPDATE
216 public.bugwatchactivity = SELECT, INSERT, UPDATE
217 public.buildfarmjob = DELETE
218+public.charmfile = SELECT, INSERT, UPDATE, DELETE
219+public.charmrecipe = SELECT, INSERT, UPDATE, DELETE
220+public.charmrecipebuild = SELECT, INSERT, UPDATE, DELETE
221+public.charmrecipebuildjob = SELECT, INSERT, UPDATE, DELETE
222+public.charmrecipejob = SELECT, INSERT, UPDATE, DELETE
223 public.codeimport = SELECT, INSERT, UPDATE, DELETE
224 public.codeimportevent = SELECT, INSERT, UPDATE
225 public.codeimporteventdata = SELECT, INSERT
226@@ -447,6 +452,8 @@ public.binarypackagefile = SELECT
227 public.branchmergeproposal = SELECT
228 public.bugattachment = SELECT
229 public.buildfarmjob = SELECT
230+public.charmfile = SELECT
231+public.charmrecipebuild = SELECT
232 public.codeimportresult = SELECT
233 public.diff = SELECT
234 public.distribution = SELECT
235@@ -704,6 +711,8 @@ public.bugsubscriptionfilterimportance = SELECT
236 public.bugsubscriptionfilterstatus = SELECT
237 public.bugsubscriptionfiltertag = SELECT
238 public.bugtag = SELECT
239+public.charmrecipe = SELECT, UPDATE
240+public.charmrecipebuild = SELECT
241 public.codeimport = SELECT
242 public.codereviewmessage = SELECT
243 public.codereviewvote = SELECT
244@@ -830,6 +839,9 @@ public.archivepermission = SELECT
245 public.branch = SELECT
246 public.buildfarmjob = SELECT, INSERT
247 public.buildqueue = SELECT, INSERT, UPDATE
248+public.charmrecipe = SELECT, UPDATE
249+public.charmrecipebuild = SELECT, INSERT
250+public.charmrecipebuildjob = SELECT
251 public.component = SELECT
252 public.distribution = SELECT
253 public.distroarchseries = SELECT
254@@ -992,6 +1004,11 @@ public.builder = SELECT, INSERT, UPDATE
255 public.builderprocessor = SELECT, INSERT, UPDATE, DELETE
256 public.buildfarmjob = SELECT, INSERT, UPDATE
257 public.buildqueue = SELECT, INSERT, UPDATE, DELETE
258+public.charmfile = SELECT
259+public.charmrecipe = SELECT
260+public.charmrecipebuild = SELECT, UPDATE
261+public.charmrecipebuildjob = SELECT, INSERT
262+public.charmrecipejob = SELECT
263 public.component = SELECT
264 public.componentselection = SELECT
265 public.distribution = SELECT, UPDATE
266@@ -1428,6 +1445,9 @@ public.builder = SELECT
267 public.builderprocessor = SELECT
268 public.buildfarmjob = SELECT, INSERT, UPDATE
269 public.buildqueue = SELECT, INSERT, UPDATE
270+public.charmfile = SELECT, INSERT, UPDATE
271+public.charmrecipe = SELECT, UPDATE
272+public.charmrecipebuild = SELECT, UPDATE
273 public.component = SELECT, INSERT
274 public.componentselection = SELECT
275 public.cve = SELECT, INSERT
276@@ -1558,6 +1578,8 @@ public.bugtrackeralias = SELECT, INSERT
277 public.bugwatch = SELECT, INSERT
278 public.buildfarmjob = SELECT, INSERT, UPDATE
279 public.buildqueue = SELECT, INSERT, UPDATE
280+public.charmfile = SELECT, UPDATE
281+public.charmrecipebuild = SELECT
282 public.component = SELECT
283 public.componentselection = SELECT
284 public.cve = SELECT, INSERT
285@@ -2298,6 +2320,8 @@ public.bugtracker = SELECT, UPDATE
286 public.bugtrackerperson = SELECT, UPDATE
287 public.bugwatch = SELECT, UPDATE
288 public.builder = SELECT, UPDATE
289+public.charmrecipe = SELECT, UPDATE
290+public.charmrecipebuild = SELECT, UPDATE
291 public.codeimport = SELECT, UPDATE
292 public.codeimportevent = SELECT, UPDATE
293 public.codeimportjob = SELECT, UPDATE
294@@ -2456,6 +2480,8 @@ public.bugtask = SELECT, UPDATE
295 public.bugtaskflat = SELECT
296 public.bugwatch = SELECT, UPDATE
297 public.bugwatchactivity = SELECT, DELETE
298+public.charmfile = SELECT, DELETE
299+public.charmrecipe = SELECT, UPDATE
300 public.codeimportevent = SELECT, DELETE
301 public.codeimporteventdata = SELECT, DELETE
302 public.codeimportresult = SELECT, DELETE
303@@ -2684,6 +2710,7 @@ public.sourcepackagename = SELECT
304 type=user
305 groups=script
306 public.branch = SELECT
307+public.charmrecipe = SELECT
308 public.distribution = SELECT
309 public.gitrepository = SELECT
310 public.job = SELECT, UPDATE
311diff --git a/lib/lp/registry/personmerge.py b/lib/lp/registry/personmerge.py
312index a2298fa..830c010 100644
313--- a/lib/lp/registry/personmerge.py
314+++ b/lib/lp/registry/personmerge.py
315@@ -827,6 +827,10 @@ def merge_people(from_person, to_person, reviewer, delete=False):
316 # OCI recipe code, but can be ignored for the purpose of deploying
317 # the database tables.
318 ('ocirecipe', 'owner'),
319+ # XXX cjwatson 2021-05-24: This needs handling before we deploy the
320+ # charm recipe code, but can be ignored for the purpose of deploying
321+ # the database tables.
322+ ('charmrecipe', 'owner'),
323 ]
324
325 references = list(postgresql.listReferences(cur, 'person', 'id'))

Subscribers

People subscribed via source and target branches

to status/vote changes: