diff --git a/scripts/bootstrap8.sh b/scripts/bootstrap8.sh
new file mode 100644
index 0000000..cd60a33
--- /dev/null
+++ b/scripts/bootstrap8.sh
@@ -0,0 +1,54 @@
+KOJI="/usr/bin/koji"
+URLS=http://composes.rdu2.centos.org/CentOS-Stream-20191210.n.0/compose/
+URLX=http://composes.rdu2.centos.org/CentOS-Stream-20191210.n.0/compose/
+BUILDROOT_DEFAULT="curl bash bzip2 coreutils cpio diffutils redhat-release findutils gawk gcc gcc-c++ grep gzip info make patch redhat-rpm-config rpm-build sed shadow-utils tar unzip util-linux-ng which buildsys-tools tar"
+
+create_tag () {
+	local name="$1"
+	local arches="$2"
+	local disttag="$3"
+	local dist="$4" # s or x
+	$KOJI remove-tag ${name}-build
+	$KOJI add-tag --arches "${arches}" ${name}-build
+	$KOJI add-external-repo --tag=${name}-build centos8${dist}-cr --mode bare
+	$KOJI add-external-repo --tag=${name}-build centos8${dist}-powertools --mode bare 
+	$KOJI add-external-repo --tag=${name}-build centos8${dist}-appstream --mode bare
+	$KOJI add-external-repo --tag=${name}-build centos8${dist}-baseos  --mode bare
+	$KOJI add-tag --arches "${arches}" ${name}-candidate 2> /dev/null # never delete destination tags with content 
+	$KOJI add-tag --arches "${arches}" ${name}-testing 2> /dev/null # never delete destination tags with content
+	$KOJI add-tag --arches "${arches}" ${name}-release  2> /dev/null # never delete destination tags with content
+	$KOJI add-group ${name}-build build
+	$KOJI add-group ${name}-build srpm-build
+	$KOJI add-group-pkg ${name}-build build $BUILDROOT_DEFAULT
+	$KOJI add-group-pkg ${name}-build srpm-build $BUILDROOT_DEFAULT
+	$KOJI add-target ${name} ${name}-build ${name}-candidate
+	$KOJI edit-tag ${name}-build --extra="mock.package_manager=dnf"
+	$KOJI edit-tag ${name}-build --extra="mock.new_chroot=1"
+	$KOJI regen-repo --nowait ${name}-build
+}
+
+add_or_update_repo () {
+	local name="$1"
+	local url="$2"
+	$KOJI edit-external-repo $name --name $name 2>/dev/null
+	if [ $? -gt 0 ]
+	then
+		$KOJI add-external-repo "$name" "$url"
+	else
+		$KOJI edit-external-repo $name --url="$url"
+	fi
+}
+
+add_or_update_repo "centos8s-appstream" "$URLS/AppStream/\$arch/os/"
+add_or_update_repo "centos8s-baseos" "$URLS/BaseOS/\$arch/os/"
+add_or_update_repo "centos8s-powertools" "$URLS/PowerTools/\$arch/os/"
+add_or_update_repo "centos8s-cr" "$URLS/CR/\$arch/os/"
+
+add_or_update_repo "centos8x-appstream" "$URLX/AppStream/\$arch/os/"
+add_or_update_repo "centos8x-baseos" "$URLX/BaseOS/\$arch/os/"
+add_or_update_repo "centos8x-powertools" "$URLX/PowerTools/\$arch/os/"
+add_or_update_repo "centos8x-cr" "$URLX/CR/\$arch/os/"
+
+#create_tag "buildsys8" "x86_64 aarch64 ppcle64" "el8" "s"
+create_tag "buildsys8" "x86_64 aarch64 ppc64le" "el8" "x"
+create_tag "test8" "x86_64" "el8" "x"
diff --git a/scripts/migration/1.11-1.16.3/1 b/scripts/migration/1.11-1.16.3/1
deleted file mode 100644
index d76b1e5..0000000
--- a/scripts/migration/1.11-1.16.3/1
+++ /dev/null
@@ -1,4 +0,0 @@
-CHANGES from original schema:
-- We created the 'image' role in 1.11 -> removed
-- A user nobody need to exist with id=1 -> insert into users (id,name,password,status,usertype,krb_principal) VALUES (1, 'nobody', '',0,0,''); was executed on production database.
-- A deleted constrain in 1.15 -> 1.16, didn't exist -> commented out.
diff --git a/scripts/migration/schema-upgrade-1.16-1.17.sql b/scripts/migration/schema-upgrade-1.16-1.17.sql
new file mode 100644
index 0000000..6cb9ad6
--- /dev/null
+++ b/scripts/migration/schema-upgrade-1.16-1.17.sql
@@ -0,0 +1,13 @@
+-- upgrade script to migrate the Koji database schema
+-- from version 1.16 to 1.17
+
+
+BEGIN;
+
+-- Change VARCHAR field for build_target names to TEXT to allow longer names
+ALTER TABLE build_target ALTER COLUMN name TYPE TEXT;
+
+-- Allow different merge modes for mergerepo
+ALTER TABLE tag_external_repos ADD COLUMN merge_mode TEXT DEFAULT 'koji';
+
+COMMIT;
diff --git a/scripts/migration/schema-upgrade-1.17-1.18.sql b/scripts/migration/schema-upgrade-1.17-1.18.sql
new file mode 100644
index 0000000..751d7d7
--- /dev/null
+++ b/scripts/migration/schema-upgrade-1.17-1.18.sql
@@ -0,0 +1,45 @@
+-- upgrade script to migrate the Koji database schema
+-- from version 1.17 to 1.18
+
+
+BEGIN;
+
+-- new table for notifications' optouts
+CREATE TABLE build_notifications_block (
+    id SERIAL NOT NULL PRIMARY KEY,
+    user_id INTEGER NOT NULL REFERENCES users (id),
+    package_id INTEGER REFERENCES package (id),
+    tag_id INTEGER REFERENCES tag (id)
+) WITHOUT OIDS;
+
+-- add tgz to list of tar's extensions
+UPDATE archivetypes SET extensions = 'tar tar.gz tar.bz2 tar.xz tgz' WHERE name = 'tar';
+INSERT INTO archivetypes (name, description, extensions) VALUES ('vhdx', 'Hyper-V Virtual Hard Disk v2 image', 'vhdx');
+
+-- add compressed raw-gzip and compressed qcow2 images
+insert into archivetypes (name, description, extensions) values ('raw-gz', 'GZIP compressed raw disk image', 'raw.gz');
+insert into archivetypes (name, description, extensions) values ('qcow2-compressed', 'Compressed QCOW2 image', 'qcow2.gz qcow2.xz');
+
+-- add better index for sessions
+CREATE INDEX sessions_expired ON sessions(expired);
+
+-- table for content generator build reservations
+CREATE TABLE build_reservations (
+	build_id INTEGER NOT NULL REFERENCES build(id),
+	token VARCHAR(64),
+        created TIMESTAMP NOT NULL,
+	PRIMARY KEY (build_id)
+) WITHOUT OIDS;
+CREATE INDEX build_reservations_created ON build_reservations(created);
+
+ALTER TABLE build ADD COLUMN cg_id INTEGER REFERENCES content_generator(id);
+
+
+-- new indexes added in 1.18
+CREATE INDEX tag_packages_active_tag_id ON tag_packages(active, tag_id);
+CREATE INDEX tag_packages_create_event ON tag_packages(create_event);
+CREATE INDEX tag_packages_revoke_event ON tag_packages(revoke_event);
+CREATE INDEX tag_packages_owner ON tag_packages(owner);
+
+
+COMMIT;
diff --git a/scripts/migration/schema-upgrade-1.18-1.19.sql b/scripts/migration/schema-upgrade-1.18-1.19.sql
new file mode 100644
index 0000000..e071f2a
--- /dev/null
+++ b/scripts/migration/schema-upgrade-1.18-1.19.sql
@@ -0,0 +1,93 @@
+-- upgrade script to migrate the Koji database schema
+-- from version 1.18 to 1.19
+
+
+BEGIN;
+
+CREATE TABLE tag_package_owners (
+	package_id INTEGER NOT NULL REFERENCES package(id),
+	tag_id INTEGER NOT NULL REFERENCES tag (id),
+	owner INTEGER NOT NULL REFERENCES users(id),
+-- versioned - see earlier description of versioning
+	create_event INTEGER NOT NULL REFERENCES events(id) DEFAULT get_event(),
+	revoke_event INTEGER REFERENCES events(id),
+	creator_id INTEGER NOT NULL REFERENCES users(id),
+	revoker_id INTEGER REFERENCES users(id),
+	active BOOLEAN DEFAULT 'true' CHECK (active),
+	CONSTRAINT active_revoke_sane CHECK (
+		(active IS NULL AND revoke_event IS NOT NULL AND revoker_id IS NOT NULL)
+		OR (active IS NOT NULL AND revoke_event IS NULL AND revoker_id IS NULL)),
+	PRIMARY KEY (create_event, package_id, tag_id),
+	UNIQUE (package_id,tag_id,active)
+) WITHOUT OIDS;
+
+CREATE OR REPLACE FUNCTION convert_owners() RETURNS SETOF tag_packages AS
+$BODY$
+DECLARE
+    r tag_packages%rowtype;
+    r2 tag_packages%rowtype;
+    last_owner int;
+BEGIN
+    FOR r IN SELECT package_id, tag_id FROM tag_packages GROUP BY package_id, tag_id ORDER BY package_id, tag_id
+    LOOP
+        last_owner := 0;
+        FOR r2 IN SELECT * FROM tag_packages WHERE package_id = r.package_id AND tag_id = r.tag_id ORDER BY create_event
+        LOOP
+            -- always use first and last (active) row
+            IF last_owner = 0 OR r2.active IS TRUE THEN
+                last_owner := r2.owner;
+                RETURN NEXT r2; -- return current row of SELECT
+            ELSE
+                -- copy others only if owner changed
+                IF last_owner <> r2.owner THEN
+                    RETURN NEXT r2;
+                    last_owner := r2.owner;
+                END IF;
+            END IF;
+        END LOOP;
+    END LOOP;
+    RETURN;
+END
+$BODY$
+LANGUAGE plpgsql;
+
+INSERT INTO tag_package_owners (SELECT package_id, tag_id, owner, create_event, revoke_event, creator_id, revoker_id, active FROM convert_owners());
+DROP INDEX IF EXISTS tag_packages_owner;
+ALTER TABLE tag_packages DROP COLUMN owner;
+DROP FUNCTION convert_owners();
+
+-- add compressed iso-compressed, vhd-compressed, vhdx-compressed, and vmdk-compressed
+insert into archivetypes (name, description, extensions) values ('iso-compressed', 'Compressed iso image', 'iso.gz iso.xz');
+insert into archivetypes (name, description, extensions) values ('vhd-compressed', 'Compressed VHD image', 'vhd.gz vhd.xz');
+insert into archivetypes (name, description, extensions) values ('vhdx-compressed', 'Compressed VHDx image', 'vhd.gz vhd.xz');
+insert into archivetypes (name, description, extensions) values ('vmdk-compressed', 'Compressed VMDK image', 'vmdk.gz vmdk.xz');
+
+-- add kernel-image and imitramfs
+insert into archivetypes (name, description, extensions) values ('kernel-image', 'Kernel BZ2 Image', 'vmlinuz vmlinuz.gz vmlinuz.xz');
+insert into archivetypes (name, description, extensions) values ('initramfs', 'Compressed Initramfs Image', 'img');
+
+-- schema update for https://pagure.io/koji/issue/1629
+CREATE TABLE user_krb_principals (
+    user_id INTEGER NOT NULL REFERENCES users(id),
+    krb_principal VARCHAR(255) NOT NULL UNIQUE,
+    PRIMARY KEY (user_id, krb_principal)
+) WITHOUT OIDS;
+
+INSERT INTO user_krb_principals ( SELECT id, krb_principal FROM users WHERE users.krb_principal IS NOT NULL);
+
+ALTER TABLE users DROP COLUMN krb_principal;
+
+-- Disallow duplicate content generator names
+ALTER TABLE content_generator ADD UNIQUE (name);
+ALTER TABLE content_generator ALTER COLUMN name SET NOT NULL;
+
+
+-- add all basic permissions
+INSERT INTO permissions (name) SELECT 'dist-repo' WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE name = 'dist-repo');
+INSERT INTO permissions (name) SELECT 'host' WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE name = 'host');
+INSERT INTO permissions (name) SELECT 'image-import' WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE name = 'image-import');
+INSERT INTO permissions (name) SELECT 'sign' WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE name = 'sign');
+INSERT INTO permissions (name) SELECT 'tag' WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE name = 'tag');
+INSERT INTO permissions (name) SELECT 'target' WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE name = 'target');
+
+COMMIT;