Trees | Indices | Help |
---|
|
1 import re 2 from six.moves.urllib.parse import urlparse 3 4 import flask 5 import wtforms 6 import json 7 8 from flask_wtf.file import FileRequired, FileField 9 from fnmatch import fnmatch 10 11 try: # get rid of deprecation warning with newer flask_wtf 12 from flask_wtf import FlaskForm 13 except ImportError: 14 from flask_wtf import Form as FlaskForm 15 16 from coprs import constants 17 from coprs import app 18 from coprs import helpers 19 from coprs import models 20 from coprs.logic.coprs_logic import CoprsLogic, MockChrootsLogic 21 from coprs.logic.users_logic import UsersLogic 22 from coprs import exceptions 23 24 25 FALSE_VALUES = {False, "false", ""}29 """ 30 Params 31 ------ 32 source_type_text : str 33 name of the source type (scm/pypi/rubygems/git_and_tito/mock_scm) 34 35 Returns 36 ------- 37 BasePackageForm child 38 based on source_type_text input 39 """ 40 if source_type_text == 'scm': 41 return PackageFormScm 42 elif source_type_text == 'pypi': 43 return PackageFormPyPI 44 elif source_type_text == 'rubygems': 45 return PackageFormRubyGems 46 elif source_type_text == 'git_and_tito': 47 return PackageFormTito # deprecated 48 elif source_type_text == 'mock_scm': 49 return PackageFormMock # deprecated 50 elif source_type_text == "custom": 51 return PackageFormCustom 52 else: 53 raise exceptions.UnknownSourceTypeException("Invalid source type")5457 widget = wtforms.widgets.ListWidget(prefix_label=False) 58 option_widget = wtforms.widgets.CheckboxInput()59628264 if not message: 65 message = ("A list of http[s] URLs separated by whitespace characters" 66 " is needed ('{0}' doesn't seem to be a valid URL).") 67 self.message = message6870 urls = field.data.split() 71 for u in urls: 72 if not self.is_url(u): 73 raise wtforms.ValidationError(self.message.format(u))7485 """ Allows also `repo://` schema"""10187 parsed = urlparse(url) 88 if parsed.scheme not in ["http", "https", "copr"]: 89 return False 90 if not parsed.netloc: 91 return False 92 # copr://username/projectname 93 # ^^ schema ^^ netlock ^^ path 94 if parsed.scheme == "copr": 95 # check if projectname missed 96 path_split = parsed.path.split("/") 97 if len(path_split) < 2 or path_split[1] == "": 98 return False 99 100 return True115105 if not message: 106 message = ("URLs must end with .src.rpm, .nosrc.rpm, or .spec" 107 " ('{0}' doesn't seem to be a valid URL).") 108 super(UrlSrpmListValidator, self).__init__(message)109127119 if not message: 120 message = "You can upload only .src.rpm, .nosrc.rpm, and .spec files" 121 self.message = message122130153132 if not message: 133 if group is None: 134 message = "You already have project named '{}'." 135 else: 136 message = "Group {} ".format(group) + "already have project named '{}'." 137 self.message = message 138 if not user: 139 user = flask.g.user 140 self.user = user 141 self.group = group142144 if self.group: 145 existing = CoprsLogic.exists_for_group( 146 self.group, field.data).first() 147 else: 148 existing = CoprsLogic.exists_for_user( 149 self.user, field.data).first() 150 151 if existing and str(existing.id) != form.id.data: 152 raise wtforms.ValidationError(self.message.format(field.data))166157 if not message: 158 message = "Name must contain only letters, digits, underscores, dashes and dots." 159 self.message = message160179170 # Allow it to be truly optional and has None value 171 if not field.data: 172 return 173 174 selected = set(field.data.split()) 175 enabled = set(MockChrootsLogic.active_names()) 176 177 if selected - enabled: 178 raise wtforms.ValidationError("Such chroot is not available: {}".format(", ".join(selected - enabled)))182191 208184 if not message: 185 message = "Project's name can not be just number." 186 self.message = message187211221213 if not value: 214 return '' 215 # Replace every whitespace string with one newline 216 # Formats ideally for html form filling, use replace('\n', ' ') 217 # to get space-separated values or split() to get list 218 result = value.strip() 219 regex = re.compile(r"\s+") 220 return regex.sub(lambda x: '\n', result)224229226 if value: 227 return helpers.PermissionEnum("request") 228 return helpers.PermissionEnum("nothing")232 233 @staticmethod380 381 def validate_mock_chroots_not_empty(self): 382 have_any = False 383 for c in self.chroots_list: 384 if getattr(self, c).data: 385 have_any = True 386 return have_any 387 388 F.chroots_list = MockChrootsLogic.active_names() 389 F.chroots_list.sort() 390 # sets of chroots according to how we should print them in columns 391 F.chroots_sets = {} 392 for ch in F.chroots_list: 393 checkbox_default = False 394 if mock_chroots and ch in [x.name for x in mock_chroots]: 395 checkbox_default = True 396 397 setattr(F, ch, wtforms.BooleanField(ch, default=checkbox_default, false_values=FALSE_VALUES)) 398 if ch[0] in F.chroots_sets: 399 F.chroots_sets[ch[0]].append(ch) 400 else: 401 F.chroots_sets[ch[0]] = [ch] 402 403 return F 404235 class F(FlaskForm): 236 # also use id here, to be able to find out whether user 237 # is updating a copr if so, we don't want to shout 238 # that name already exists 239 id = wtforms.HiddenField() 240 group_id = wtforms.HiddenField() 241 242 name = wtforms.StringField( 243 "Name", 244 validators=[ 245 wtforms.validators.DataRequired(), 246 NameCharactersValidator(), 247 CoprUniqueNameValidator(user=user, group=group), 248 NameNotNumberValidator() 249 ]) 250 251 homepage = wtforms.StringField( 252 "Homepage", 253 validators=[ 254 wtforms.validators.Optional(), 255 wtforms.validators.URL()]) 256 257 contact = wtforms.StringField( 258 "Contact", 259 validators=[ 260 wtforms.validators.Optional(), 261 EmailOrURL()]) 262 263 description = wtforms.TextAreaField("Description") 264 265 instructions = wtforms.TextAreaField("Instructions") 266 267 delete_after_days = wtforms.IntegerField( 268 "Delete after days", 269 validators=[ 270 wtforms.validators.Optional(), 271 wtforms.validators.NumberRange(min=0, max=60), 272 ], 273 render_kw={'disabled': bool(copr and copr.persistent)}) 274 275 repos = wtforms.TextAreaField( 276 "External Repositories", 277 validators=[UrlRepoListValidator()], 278 filters=[StringListFilter()]) 279 280 initial_pkgs = wtforms.TextAreaField( 281 "Initial packages to build", 282 validators=[ 283 UrlListValidator(), 284 UrlSrpmListValidator()], 285 filters=[StringListFilter()]) 286 287 disable_createrepo = wtforms.BooleanField(default=False, 288 label="Create repositories manually", 289 description="""Repository meta data is normally refreshed 290 after each build. If you want to do this manually, turn 291 this option on.""", 292 false_values=FALSE_VALUES) 293 294 unlisted_on_hp = wtforms.BooleanField( 295 "Project will not be listed on home page", 296 default=False, 297 false_values=FALSE_VALUES) 298 299 persistent = wtforms.BooleanField( 300 "Protect project and its builds against deletion", 301 description="""Project's builds and the project itself 302 cannot be deleted by any means. This option is set once and 303 for all (this option can not be changed after project is 304 created).""", 305 render_kw={'disabled': bool(copr)}, 306 default=False, false_values=FALSE_VALUES) 307 308 auto_prune = wtforms.BooleanField( 309 "Old builds will be deleted automatically", 310 default=True, false_values=FALSE_VALUES, 311 description="""Build will be deleted only if there is a 312 newer build (with respect to package version) and it is 313 older than 14 days""") 314 315 use_bootstrap_container = wtforms.BooleanField( 316 "Enable mock's use_bootstrap_container experimental feature", 317 description="""This will make the build slower but it has an 318 advantage that the dnf _from_ the given chroot will be used 319 to setup the chroot (otherwise host system dnf and rpm is 320 used)""", 321 default=False, 322 false_values=FALSE_VALUES) 323 324 follow_fedora_branching = wtforms.BooleanField( 325 "Follow Fedora branching", 326 description="""When Fedora is branched from rawhide, the 327 respective chroots for the new branch are automatically 328 created for you (as soon as they are available) as rawhide 329 chroot forks.""", 330 default=True, 331 false_values=FALSE_VALUES) 332 333 multilib = wtforms.BooleanField( 334 "Multilib support", 335 description="""When users enable this copr repository on 336 64bit variant of multilib capable architecture (e.g. 337 x86_64), they will be able to install 32bit variants of the 338 packages (e.g. i386 for x86_64 arch)""", 339 default=False, 340 false_values=FALSE_VALUES) 341 342 # Deprecated, use `enable_net` instead 343 build_enable_net = wtforms.BooleanField( 344 "Enable internet access during builds", 345 default=False, false_values=FALSE_VALUES) 346 347 enable_net = wtforms.BooleanField( 348 "Enable internet access during builds", 349 default=False, false_values=FALSE_VALUES) 350 351 module_hotfixes = wtforms.BooleanField( 352 "This repository contains module hotfixes", 353 description="""This will make packages from this project 354 available on along with packages from the active module 355 streams.""", 356 default=False, false_values=FALSE_VALUES) 357 358 @property 359 def selected_chroots(self): 360 selected = [] 361 for ch in self.chroots_list: 362 if getattr(self, ch).data: 363 selected.append(ch) 364 return selected365 366 def validate(self): 367 if not super(F, self).validate(): 368 return False 369 370 if not self.validate_mock_chroots_not_empty(): 371 self.errors["chroots"] = ["At least one chroot must be selected"] 372 return False 373 374 if self.persistent.data and self.delete_after_days.data: 375 self.delete_after_days.errors.append( 376 "'delete after' can not be combined with persistent") 377 return False 378 379 return True407 verify = wtforms.StringField( 408 "Confirm deleting by typing 'yes'", 409 validators=[ 410 wtforms.validators.DataRequired(), 411 wtforms.validators.Regexp( 412 r"^yes$", 413 message="Type 'yes' - without the quotes, lowercase.") 414 ])415 419420 421 # @TODO jkadlcik - rewrite via BaseBuildFormFactory after fe-dev-cloud is back online 422 -class BuildFormRebuildFactory(object):423 @staticmethod453 454 F.chroots_list = list(map(lambda x: x.name, active_chroots)) 455 F.chroots_list.sort() 456 F.chroots_sets = {} 457 for ch in F.chroots_list: 458 setattr(F, ch, wtforms.BooleanField(ch, default=True, false_values=FALSE_VALUES)) 459 if ch[0] in F.chroots_sets: 460 F.chroots_sets[ch[0]].append(ch) 461 else: 462 F.chroots_sets[ch[0]] = [ch] 463 464 return F 465425 class F(FlaskForm): 426 @property 427 def selected_chroots(self): 428 selected = [] 429 for ch in self.chroots_list: 430 if getattr(self, ch).data: 431 selected.append(ch) 432 return selected433 434 memory_reqs = wtforms.IntegerField( 435 "Memory requirements", 436 validators=[ 437 wtforms.validators.NumberRange( 438 min=constants.MIN_BUILD_MEMORY, 439 max=constants.MAX_BUILD_MEMORY)], 440 default=constants.DEFAULT_BUILD_MEMORY) 441 442 timeout = wtforms.IntegerField( 443 "Timeout", 444 validators=[ 445 wtforms.validators.NumberRange( 446 min=constants.MIN_BUILD_TIMEOUT, 447 max=constants.MAX_BUILD_TIMEOUT)], 448 default=constants.DEFAULT_BUILD_TIMEOUT) 449 450 enable_net = wtforms.BooleanField(false_values=FALSE_VALUES) 451 background = wtforms.BooleanField(false_values=FALSE_VALUES) 452 project_dirname = wtforms.StringField(default=None)468 @staticmethod475470 form = BuildFormRebuildFactory.create_form_cls(active_chroots) 471 form.package_name = wtforms.StringField( 472 "Package name", 473 validators=[wtforms.validators.DataRequired()]) 474 return form478 if not string: 479 return string 480 fields = [x.lstrip().rstrip() for x in string.split(',')] 481 return ', '.join(fields)482485 if field.data: 486 string = field.data 487 fields = [x.lstrip().rstrip() for x in string.split(',')] 488 for field in fields: 489 pattern = r'^[a-z0-9-*]+$' 490 if not re.match(pattern, field): 491 raise wtforms.ValidationError('Pattern "{0}" does not match "{1}"'.format(field, pattern)) 492 493 matched = set() 494 all_chroots = MockChrootsLogic.active_names() 495 for chroot in all_chroots: 496 if fnmatch(chroot, field): 497 matched.add(chroot) 498 499 if not matched: 500 raise wtforms.ValidationError('no chroot matched by pattern "{0}"'.format(field)) 501 502 if matched == all_chroots: 503 raise wtforms.ValidationError('patterns are black-listing all chroots')504507 package_name = wtforms.StringField( 508 "Package name", 509 validators=[wtforms.validators.DataRequired()]) 510 webhook_rebuild = wtforms.BooleanField(default=False, false_values=FALSE_VALUES) 511 chroot_blacklist = wtforms.StringField( 512 "Chroot blacklist", 513 filters=[cleanup_chroot_blacklist], 514 validators=[ 515 wtforms.validators.Optional(), 516 validate_chroot_blacklist, 517 ], 518 ) 519 max_builds = wtforms.IntegerField( 520 "Max number of builds", 521 description="""Keep only the specified number of the newest-by-id builds 522 (garbage collector is run daily)""", 523 render_kw={'placeholder': 'Optional - integer, e.g. 10, zero/empty disables'}, 524 validators=[ 525 wtforms.validators.Optional(), 526 wtforms.validators.NumberRange(min=0, max=100)], 527 default=None, 528 )529532 scm_type = wtforms.SelectField( 533 "Type", 534 choices=[("git", "Git"), ("svn", "SVN")], 535 default="git") 536 537 clone_url = wtforms.StringField( 538 "Clone url", 539 validators=[ 540 wtforms.validators.DataRequired(), 541 wtforms.validators.URL()]) 542 543 committish = wtforms.StringField( 544 "Committish", 545 validators=[ 546 wtforms.validators.Optional()]) 547 548 subdirectory = wtforms.StringField( 549 "Subdirectory", 550 validators=[ 551 wtforms.validators.Optional()]) 552 553 spec = wtforms.StringField( 554 "Spec File", 555 validators=[ 556 wtforms.validators.Optional(), 557 wtforms.validators.Regexp( 558 r"^.+\.spec$", 559 message="RPM spec file must end with .spec")]) 560 561 srpm_build_method = wtforms.SelectField( 562 "SRPM build method", 563 choices=[(x, x) for x in ["rpkg", "tito", "tito_test", "make_srpm"]], 564 default="rpkg") 565 566 @property576568 return json.dumps({ 569 "type": self.scm_type.data, 570 "clone_url": self.clone_url.data, 571 "subdirectory": self.subdirectory.data, 572 "committish": self.committish.data, 573 "spec": self.spec.data, 574 "srpm_build_method": self.srpm_build_method.data, 575 })579 pypi_package_name = wtforms.StringField( 580 "PyPI package name", 581 validators=[wtforms.validators.DataRequired()]) 582 583 pypi_package_version = wtforms.StringField( 584 "PyPI package version", 585 validators=[ 586 wtforms.validators.Optional(), 587 ]) 588 589 spec_template = wtforms.SelectField( 590 "Spec template", 591 choices=[ 592 ("", "default"), 593 ("fedora", "fedora"), 594 ("epel7", "epel7"), 595 ("mageia", "mageia"), 596 ("pld", "pld"), 597 ], default="") 598 599 python_versions = MultiCheckboxField( 600 'Build for Python', 601 choices=[ 602 ('3', 'python3'), 603 ('2', 'python2') 604 ], 605 default=['3', '2']) 606 607 @property615609 return json.dumps({ 610 "pypi_package_name": self.pypi_package_name.data, 611 "pypi_package_version": self.pypi_package_version.data, 612 "spec_template": self.spec_template.data, 613 "python_versions": self.python_versions.data 614 })618 gem_name = wtforms.StringField( 619 "Gem Name", 620 validators=[wtforms.validators.DataRequired()]) 621 622 @property627630 """ 631 @deprecated 632 """ 633 git_url = wtforms.StringField( 634 "Git URL", 635 validators=[ 636 wtforms.validators.DataRequired(), 637 wtforms.validators.URL()]) 638 639 git_directory = wtforms.StringField( 640 "Git Directory", 641 validators=[ 642 wtforms.validators.Optional()]) 643 644 git_branch = wtforms.StringField( 645 "Git Branch", 646 validators=[ 647 wtforms.validators.Optional()]) 648 649 tito_test = wtforms.BooleanField(default=False, false_values=FALSE_VALUES) 650 651 @property661653 return json.dumps({ 654 "type": 'git', 655 "clone_url": self.git_url.data, 656 "committish": self.git_branch.data, 657 "subdirectory": self.git_directory.data, 658 "spec": '', 659 "srpm_build_method": 'tito_test' if self.tito_test.data else 'tito', 660 })664 """ 665 @deprecated 666 """ 667 scm_type = wtforms.SelectField( 668 "SCM Type", 669 choices=[("git", "Git"), ("svn", "SVN")]) 670 671 scm_url = wtforms.StringField( 672 "SCM URL", 673 validators=[ 674 wtforms.validators.DataRequired(), 675 wtforms.validators.URL()]) 676 677 scm_branch = wtforms.StringField( 678 "Git Branch", 679 validators=[ 680 wtforms.validators.Optional()]) 681 682 scm_subdir = wtforms.StringField( 683 "Subdirectory", 684 validators=[ 685 wtforms.validators.Optional()]) 686 687 spec = wtforms.StringField( 688 "Spec File", 689 validators=[ 690 wtforms.validators.Optional(), 691 wtforms.validators.Regexp( 692 r"^.+\.spec$", 693 message="RPM spec file must end with .spec")]) 694 695 @property705708 """ 709 @deprecated 710 """ 711 clone_url = wtforms.StringField( 712 "Clone Url", 713 validators=[wtforms.validators.DataRequired()]) 714 715 branch = wtforms.StringField( 716 "Branch", 717 validators=[wtforms.validators.Optional()]) 718 719 @property729732 if not string: 733 return string 734 735 if string.split('\n')[0].endswith('\r'): 736 # This script is most probably coming from the web-UI, where 737 # web-browsers mistakenly put '\r\n' as EOL; and that would just 738 # mean that the script is not executable (any line can mean 739 # syntax error, but namely shebang would cause 100% fail) 740 string = string.replace('\r\n', '\n') 741 742 # And append newline to have a valid unix file. 743 if not string.endswith('\n'): 744 string += '\n' 745 746 return string747750 script = wtforms.TextAreaField( 751 "Script", 752 validators=[ 753 wtforms.validators.DataRequired(), 754 wtforms.validators.Length( 755 max=4096, 756 message="Maximum script size is 4kB"), 757 ], 758 filters=[cleanup_script], 759 ) 760 761 builddeps = wtforms.StringField( 762 "Build dependencies", 763 validators=[wtforms.validators.Optional()]) 764 765 chroot = wtforms.SelectField( 766 'Mock chroot', 767 choices=[], 768 default='fedora-latest-x86_64', 769 ) 770 771 resultdir = wtforms.StringField( 772 "Result directory", 773 validators=[wtforms.validators.Optional()]) 774802776 super(PackageFormCustom, self).__init__(*args, **kwargs) 777 chroot_objects = models.MockChroot.query.filter(models.MockChroot.is_active).all() 778 779 chroots = [c.name for c in chroot_objects] 780 chroots.sort() 781 chroots = [(name, name) for name in chroots] 782 783 arches = set() 784 for ch in chroot_objects: 785 if ch.os_release == 'fedora': 786 arches.add(ch.arch) 787 788 self.chroot.choices = [] 789 if arches: 790 self.chroot.choices += [('fedora-latest-' + l, 'fedora-latest-' + l) for l in arches] 791 792 self.chroot.choices += chroots793 794 @property813806 form_cls = BaseBuildFormFactory(active_chroots, FlaskForm) 807 form_cls.packages = MultiCheckboxField( 808 "Packages", 809 choices=[(name, name) for name in package_names], 810 default=package_names, 811 validators=[wtforms.validators.DataRequired()]) 812 return form_cls825 826 F.memory_reqs = wtforms.IntegerField( 827 "Memory requirements", 828 validators=[ 829 wtforms.validators.Optional(), 830 wtforms.validators.NumberRange( 831 min=constants.MIN_BUILD_MEMORY, 832 max=constants.MAX_BUILD_MEMORY)], 833 default=constants.DEFAULT_BUILD_MEMORY) 834 835 F.timeout = wtforms.IntegerField( 836 "Timeout", 837 validators=[ 838 wtforms.validators.Optional(), 839 wtforms.validators.NumberRange( 840 min=constants.MIN_BUILD_TIMEOUT, 841 max=constants.MAX_BUILD_TIMEOUT)], 842 default=constants.DEFAULT_BUILD_TIMEOUT) 843 844 F.enable_net = wtforms.BooleanField(false_values=FALSE_VALUES) 845 F.background = wtforms.BooleanField(default=False, false_values=FALSE_VALUES) 846 F.project_dirname = wtforms.StringField(default=None) 847 848 # overrides BasePackageForm.package_name and is unused for building 849 F.package_name = wtforms.StringField() 850 851 # fill chroots based on project settings 852 F.chroots_list = [x.name for x in active_chroots] 853 F.chroots_list.sort() 854 F.chroots_sets = {} 855 856 package_chroots = set(F.chroots_list) 857 if package: 858 package_chroots = set([ch.name for ch in package.chroots]) 859 860 for ch in F.chroots_list: 861 default = ch in package_chroots 862 setattr(F, ch, wtforms.BooleanField(ch, default=default, false_values=FALSE_VALUES)) 863 if ch[0] in F.chroots_sets: 864 F.chroots_sets[ch[0]].append(ch) 865 else: 866 F.chroots_sets[ch[0]] = [ch] 867 return F 868 873 881 889 894 899 904817 class F(form): 818 @property 819 def selected_chroots(self): 820 selected = [] 821 for ch in self.chroots_list: 822 if getattr(self, ch).data: 823 selected.append(ch) 824 return selected913 918908 form = BaseBuildFormFactory(active_chroots, FlaskForm) 909 form.pkgs = FileField('srpm', validators=[ 910 FileRequired(), 911 SrpmValidator()]) 912 return form931922 form = BaseBuildFormFactory(active_chroots, FlaskForm) 923 form.pkgs = wtforms.TextAreaField( 924 "Pkgs", 925 validators=[ 926 wtforms.validators.DataRequired(message="URLs to packages are required"), 927 UrlListValidator(), 928 UrlSrpmListValidator()], 929 filters=[StringListFilter()]) 930 return form934 modulemd = FileField("modulemd", validators=[ 935 FileRequired(), 936 # @TODO Validate modulemd.yaml file 937 ]) 938 939 create = wtforms.BooleanField("create", default=True, false_values=FALSE_VALUES) 940 build = wtforms.BooleanField("build", default=True, false_values=FALSE_VALUES)941944 modulemd = FileField("modulemd") 945 scmurl = wtforms.StringField() 946 branch = wtforms.StringField()947950 repo_url = wtforms.StringField("repo_url", default='') 951 api_key = wtforms.StringField("api_key", default='') 952959962 963 """ 964 Validator for editing chroots in project 965 (adding packages to minimal chroot) 966 """ 967 968 buildroot_pkgs = wtforms.StringField("Packages") 969 970 repos = wtforms.TextAreaField('Repos', 971 validators=[UrlRepoListValidator(), 972 wtforms.validators.Optional()], 973 filters=[StringListFilter()]) 974 975 comps = FileField("comps_xml") 976 977 with_opts = wtforms.StringField("With options") 978 without_opts = wtforms.StringField("Without options")979 984987 comment = wtforms.TextAreaField("Comment")988991 992 @staticmethod 996 997 builder_default = False 998 admin_default = False 999 1000 if permission: 1001 if permission.copr_builder != helpers.PermissionEnum("nothing"): 1002 builder_default = True 1003 if permission.copr_admin != helpers.PermissionEnum("nothing"): 1004 admin_default = True 1005 1006 setattr(F, "copr_builder", 1007 wtforms.BooleanField( 1008 default=builder_default, 1009 false_values=FALSE_VALUES, 1010 filters=[ValueToPermissionNumberFilter()])) 1011 1012 setattr(F, "copr_admin", 1013 wtforms.BooleanField( 1014 default=admin_default, 1015 false_values=FALSE_VALUES, 1016 filters=[ValueToPermissionNumberFilter()])) 1017 1018 return F10191022 1023 """Creates a dynamic form for given set of copr permissions""" 1024 @staticmethod 1028 1029 for perm in permissions: 1030 builder_choices = helpers.PermissionEnum.choices_list() 1031 admin_choices = helpers.PermissionEnum.choices_list() 1032 1033 builder_default = perm.copr_builder 1034 admin_default = perm.copr_admin 1035 1036 setattr(F, "copr_builder_{0}".format(perm.user.id), 1037 wtforms.SelectField( 1038 choices=builder_choices, 1039 default=builder_default, 1040 coerce=int)) 1041 1042 setattr(F, "copr_admin_{0}".format(perm.user.id), 1043 wtforms.SelectField( 1044 choices=admin_choices, 1045 default=admin_default, 1046 coerce=int)) 1047 1048 return F10491052 description = wtforms.TextAreaField('Description', 1053 validators=[wtforms.validators.Optional()]) 1054 1055 instructions = wtforms.TextAreaField('Instructions', 1056 validators=[wtforms.validators.Optional()]) 1057 1058 chroots = wtforms.TextAreaField('Chroots', 1059 validators=[wtforms.validators.Optional(), ChrootsValidator()]) 1060 1061 repos = wtforms.TextAreaField('External Repositories', 1062 validators=[UrlRepoListValidator(), 1063 wtforms.validators.Optional()], 1064 filters=[StringListFilter()]) 1065 1066 disable_createrepo = wtforms.BooleanField(validators=[wtforms.validators.Optional()], false_values=FALSE_VALUES) 1067 unlisted_on_hp = wtforms.BooleanField(validators=[wtforms.validators.Optional()], false_values=FALSE_VALUES) 1068 auto_prune = wtforms.BooleanField(validators=[wtforms.validators.Optional()], false_values=FALSE_VALUES) 1069 use_bootstrap_container = wtforms.BooleanField(validators=[wtforms.validators.Optional()], false_values=FALSE_VALUES) 1070 follow_fedora_branching = wtforms.BooleanField(validators=[wtforms.validators.Optional()], false_values=FALSE_VALUES) 1071 follow_fedora_branching = wtforms.BooleanField(default=True, false_values=FALSE_VALUES) 1072 delete_after_days = wtforms.IntegerField( 1073 validators=[wtforms.validators.Optional(), 1074 wtforms.validators.NumberRange(min=-1, max=60)], 1075 filters=[(lambda x : -1 if x is None else x)]) 1076 1077 # Deprecated, use `enable_net` instead 1078 build_enable_net = wtforms.BooleanField(validators=[wtforms.validators.Optional()], false_values=FALSE_VALUES) 1079 enable_net = wtforms.BooleanField(validators=[wtforms.validators.Optional()], false_values=FALSE_VALUES) 1080 multilib = wtforms.BooleanField(validators=[wtforms.validators.Optional()], false_values=FALSE_VALUES) 1081 module_hotfixes = wtforms.BooleanField(validators=[wtforms.validators.Optional()], false_values=FALSE_VALUES)10821085 @staticmethod11081087 class F(FlaskForm): 1088 source = wtforms.StringField( 1089 "Source", 1090 default=copr.full_name) 1091 1092 owner = wtforms.SelectField( 1093 "Fork owner", 1094 choices=[(user.name, user.name)] + [(g.at_name, g.at_name) for g in groups], 1095 default=user.name, 1096 validators=[wtforms.validators.DataRequired()]) 1097 1098 name = wtforms.StringField( 1099 "Fork name", 1100 default=copr.name, 1101 validators=[wtforms.validators.DataRequired(), NameCharactersValidator()]) 1102 1103 confirm = wtforms.BooleanField( 1104 "Confirm", 1105 false_values=FALSE_VALUES, 1106 default=False)1107 return F1111 buildroot_pkgs = wtforms.StringField('Additional packages to be always present in minimal buildroot') 1112 repos = wtforms.TextAreaField('Additional repos to be used for builds in chroot', 1113 validators=[UrlRepoListValidator(), 1114 wtforms.validators.Optional()], 1115 filters=[StringListFilter()]) 1116 comps = None 1117 upload_comps = FileField("Upload comps.xml") 1118 delete_comps = wtforms.BooleanField("Delete comps.xml", false_values=FALSE_VALUES)11191122 copr_ids = wtforms.SelectMultipleField(wtforms.IntegerField("Pinned Copr ID")) 11231139 11431125 if any([i and not i.isnumeric() for i in self.copr_ids.data]): 1126 self.errors["coprs"] = ["Unexpected value selected"] 1127 return False 1128 1129 limit = app.config["PINNED_PROJECTS_LIMIT"] 1130 if len(self.copr_ids.data) > limit: 1131 self.errors["coprs"] = ["Too many pinned projects. Limit is {}!".format(limit)] 1132 return False 1133 1134 if len(list(filter(None, self.copr_ids.data))) != len(set(filter(None, self.copr_ids.data))): 1135 self.errors["coprs"] = ["You can pin a particular project only once"] 1136 return False 1137 1138 return True1146 project = wtforms.StringField("Project")1147115011591152 if not message: 1153 message = "Group with the alias '{}' already exists." 1154 self.message = message11551157 if UsersLogic.group_alias_exists(field.data): 1158 raise wtforms.ValidationError(self.message.format(field.data))1162 1163 name = wtforms.StringField( 1164 validators=[ 1165 wtforms.validators.Regexp( 1166 re.compile(r"^[\w.-]+$"), 1167 message="Name must contain only letters," 1168 "digits, underscores, dashes and dots."), 1169 GroupUniqueNameValidator() 1170 ] 1171 )11721175 builds = wtforms.FieldList(wtforms.StringField("Builds ID list")) 1176 packages = wtforms.FieldList(wtforms.StringField("Packages list")) 1177 filter = wtforms.FieldList(wtforms.StringField("Package Filter")) 1178 api = wtforms.FieldList(wtforms.StringField("Module API")) 1179 profile_names = wtforms.FieldList(wtforms.StringField("Install Profiles"), min_entries=2) 1180 profile_pkgs = wtforms.FieldList(wtforms.FieldList(wtforms.StringField("Install Profiles")), min_entries=2) 1181 118512061187 if not FlaskForm.validate(self): 1188 return False 1189 1190 # Profile names should be unique 1191 names = [x for x in self.profile_names.data if x] 1192 if len(set(names)) < len(names): 1193 self.errors["profiles"] = ["Profile names must be unique"] 1194 return False 1195 1196 # WORKAROUND 1197 # profile_pkgs are somehow sorted so if I fill profile_name in the first box and 1198 # profile_pkgs in seconds box, it is sorted and validated correctly 1199 for i in range(0, len(self.profile_names.data)): 1200 # If profile name is not set, then there should not be any packages in this profile 1201 if not flask.request.form["profile_names-{}".format(i)]: 1202 if [j for j in range(0, len(self.profile_names)) if "profile_pkgs-{}-{}".format(i, j) in flask.request.form]: 1203 self.errors["profiles"] = ["Missing profile name"] 1204 return False 1205 return True1209 owner = wtforms.StringField("Owner Name", validators=[wtforms.validators.DataRequired()]) 1210 copr = wtforms.StringField("Copr Name", validators=[wtforms.validators.DataRequired()]) 1211 name = wtforms.StringField("Name", validators=[wtforms.validators.DataRequired()]) 1212 stream = wtforms.StringField("Stream", validators=[wtforms.validators.DataRequired()]) 1213 version = wtforms.IntegerField("Version", validators=[wtforms.validators.DataRequired()]) 1214 arch = wtforms.StringField("Arch", validators=[wtforms.validators.DataRequired()])1215
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 | http://epydoc.sourceforge.net |