Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make TimeZoneProperty compatible with JCasc #4557

Merged
merged 1 commit into from Apr 11, 2020

Conversation

timja
Copy link
Member

@timja timja commented Mar 8, 2020

See jenkinsci/configuration-as-code-plugin#1309 jenkinsci/configuration-as-code-plugin#1254

Example yaml:

jenkins:
  securityRealm:
    local:
      allowsSignup: true
      enableCaptcha: false
      users:
        - description: "I am admin"
          id: "admin"
          name: "Admin"
          properties:
            - timezone:
                timeZoneName: "Europe/London"

Proposed changelog entries

  • Entry 1: configuration-as-code plugin support for configuring user timezones
  • ...

Proposed upgrade guidelines

N/A

Submitter checklist

  • JIRA issue is well described
  • Changelog entries and upgrade guidelines are appropriate for the audience affected by the change (users or developer, depending on the change). Examples
    • Fill-in the Proposed changelog entries section only if there are breaking changes or other changes which may require extra steps from users during the upgrade
  • Appropriate autotests or explanation to why this change has no tests
  • For dependency updates: links to external changelogs and, if possible, full diffs

Desired reviewers

@mention

Maintainer checklist

Before the changes are marked as ready-for-merge:

  • There are at least 2 approvals for the pull request and no outstanding requests for change
  • Conversations in the pull request are over OR it is explicit that a reviewer does not block the change
  • Changelog entries in the PR title and/or Proposed changelog entries are correct
  • Proper changelog labels are set so that the changelog can be generated automatically
  • If the change needs additional upgrade steps from users, upgrade-guide-needed label is set and there is a Proposed upgrade guidelines section in the PR title. (example)
  • If it would make sense to backport the change to LTS, a JIRA issue should exist and be labeled as lts-candidate

@@ -39,11 +39,6 @@ private TimeZoneProperty() {
this(null);
}

@Override
public void save() throws IOException {
user.save();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This caused null pointers in jcasc as there's a transient user reference set on the property that can't be set through regular databinding,

I haven't seen this save pattern on any other user property and it works fine without it

I've tested from the UI and restarted jenkins and it is all fine, (and through jcasc)

note that this class is restricted no external use so evolving it is fine
class references:
https://github.com/search?q=org%3Ajenkinsci+TimeZoneProperty&type=Code

@timja timja requested review from oleg-nenashev, jetersen and a team March 8, 2020 21:21
@timja timja added the rfe For changelog: Minor enhancement. use `major-rfe` for changes to be highlighted label Mar 8, 2020
@oleg-nenashev oleg-nenashev added the on-hold This pull request depends on another event/release, and it cannot be merged right now label Mar 12, 2020
@oleg-nenashev
Copy link
Member

I would like to review it before it is merged. Removing Saveable logic may cause data loss in some cases, and it needs careful check.

@oleg-nenashev oleg-nenashev added the needs-more-reviews Complex change, which would benefit from more eyes label Mar 12, 2020
Copy link
Member

@rsandell rsandell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it is @Restricted I'm a bit more comfortable in breaking the compatibility of removing the interface implementation.

@timja
Copy link
Member Author

timja commented Apr 10, 2020

Ping @oleg-nenashev could you do your review please?

@oleg-nenashev
Copy link
Member

on it, sorry

Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saveable was added in e5ae081 - first commit in #4113 by @silent-snowman . There are some other user properties which are saveable (e.g. PaneStatusProperties), but the majority of properties do not have such interface.

For me there are only 2 use-cases to have the UserProperty Saveable :

  • There is extra UI / REST API / CLI command which updates the property and saves it
  • There are SaveableListeners watching for events

None of that applies to the TimeZoneProperty, I was unable to find any external usages which would actually depend on the object being saveable. Hence I approve it.

@oleg-nenashev oleg-nenashev removed needs-more-reviews Complex change, which would benefit from more eyes on-hold This pull request depends on another event/release, and it cannot be merged right now labels Apr 10, 2020
@timja timja added the ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback label Apr 10, 2020
@timja
Copy link
Member Author

timja commented Apr 10, 2020

Thanks for the reviews all,

Let's merge this tomorrow if no negative feedback

@oleg-nenashev oleg-nenashev merged commit 60cb47f into jenkinsci:master Apr 11, 2020
@Y0lan
Copy link

Y0lan commented May 13, 2020

java.lang.NullPointerException
	at hudson.model.MyViewsProperty.save(MyViewsProperty.java:138)
	at hudson.BulkChange.commit(BulkChange.java:98)
	at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:271)
	at io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator.configure(DataBoundConfigurator.java:83)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.lambda$doConfigure$16668e2$1(HeteroDescribableConfigurator.java:277)
	at io.vavr.CheckedFunction0.lambda$unchecked$52349c75$1(CheckedFunction0.java:247)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.doConfigure(HeteroDescribableConfigurator.java:277)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.lambda$null$2(HeteroDescribableConfigurator.java:86)
	at io.vavr.control.Option.map(Option.java:392)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.lambda$configure$3(HeteroDescribableConfigurator.java:86)
	at io.vavr.Tuple2.apply(Tuple2.java:238)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.configure(HeteroDescribableConfigurator.java:83)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.configure(HeteroDescribableConfigurator.java:55)
	at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:345)
	at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:276)
	at io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator.configure(DataBoundConfigurator.java:83)
	at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:345)
	at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:276)
	at io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator.configure(DataBoundConfigurator.java:83)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.lambda$doConfigure$16668e2$1(HeteroDescribableConfigurator.java:277)
	at io.vavr.CheckedFunction0.lambda$unchecked$52349c75$1(CheckedFunction0.java:247)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.doConfigure(HeteroDescribableConfigurator.java:277)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.lambda$null$2(HeteroDescribableConfigurator.java:86)
	at io.vavr.control.Option.map(Option.java:392)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.lambda$configure$3(HeteroDescribableConfigurator.java:86)
	at io.vavr.Tuple2.apply(Tuple2.java:238)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.configure(HeteroDescribableConfigurator.java:83)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.check(HeteroDescribableConfigurator.java:92)
	at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.check(HeteroDescribableConfigurator.java:55)
	at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:352)
	at io.jenkins.plugins.casc.BaseConfigurator.check(BaseConfigurator.java:287)
	at io.jenkins.plugins.casc.ConfigurationAsCode.lambda$checkWith$7(ConfigurationAsCode.java:752)
	at io.jenkins.plugins.casc.ConfigurationAsCode.invokeWith(ConfigurationAsCode.java:702)
	at io.jenkins.plugins.casc.ConfigurationAsCode.checkWith(ConfigurationAsCode.java:752)
	at io.jenkins.plugins.casc.ConfigurationAsCode.configureWith(ConfigurationAsCode.java:737)
	at io.jenkins.plugins.casc.ConfigurationAsCode.configureWith(ConfigurationAsCode.java:617)
	at io.jenkins.plugins.casc.ConfigurationAsCode.configure(ConfigurationAsCode.java:300)
	at io.jenkins.plugins.casc.ConfigurationAsCode.init(ConfigurationAsCode.java:292)
Caused: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at hudson.init.TaskMethodFinder.invoke(TaskMethodFinder.java:104)
Caused: java.lang.Error
	at hudson.init.TaskMethodFinder.invoke(TaskMethodFinder.java:110)
	at hudson.init.TaskMethodFinder$TaskImpl.run(TaskMethodFinder.java:175)
	at org.jvnet.hudson.reactor.Reactor.runTask(Reactor.java:296)
	at jenkins.model.Jenkins$5.runTask(Jenkins.java:1133)
	at org.jvnet.hudson.reactor.Reactor$2.run(Reactor.java:214)
	at org.jvnet.hudson.reactor.Reactor$Node.run(Reactor.java:117)
	at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused: org.jvnet.hudson.reactor.ReactorException
	at org.jvnet.hudson.reactor.Reactor.execute(Reactor.java:282)
	at jenkins.InitReactorRunner.run(InitReactorRunner.java:50)
	at jenkins.model.Jenkins.executeReactor(Jenkins.java:1166)
	at jenkins.model.Jenkins.<init>(Jenkins.java:966)
	at hudson.model.Hudson.<init>(Hudson.java:85)
	at hudson.model.Hudson.<init>(Hudson.java:81)
	at hudson.WebAppMain$3.run(WebAppMain.java:233)
Caused: hudson.util.HudsonFailedToLoad
	at hudson.WebAppMain$3.run(WebAppMain.java:250)

jenkins:
  agentProtocols:
  - "JNLP4-connect"
  - "Ping"
  authorizationStrategy:
    loggedInUsersCanDoAnything:
      allowAnonymousRead: false
  crumbIssuer:
    standard:
      excludeClientIPFromCrumb: false
  disableRememberMe: false
  markupFormatter: "plainText"
  mode: NORMAL
  myViewsTabBar: "standard"
  numExecutors: 2
  projectNamingStrategy: "standard"
  quietPeriod: 5
  remotingSecurity:
    enabled: true
  scmCheckoutRetryCount: 0
  securityRealm:
    local:
      allowsSignup: false
      enableCaptcha: false
      users:
      - id: "yolan"
        name: "yolan"
        properties:
        - "apiToken"
        - "myView"
        - preferredProvider:
            providerId: "default"
        - "timezone"
        - mailer:
            emailAddress: "hello@yolan.dev"
  slaveAgentPort: 50000
  updateCenter:
    sites:
    - id: "default"
      url: "https://updates.jenkins.io/update-center.json"
  views:
  - all:
      name: "all"
  viewsTabBar: "standard"
security:
  apiToken:
    creationOfLegacyTokenEnabled: false
    tokenGenerationOnCreationEnabled: false
    usageStatisticsEnabled: true
  globalJobDslSecurityConfiguration:
    useScriptSecurity: false
  sSHD:
    port: -1
unclassified:
  ansiColorBuildWrapper:
    colorMaps:
    - black: "#000000"
      blackB: "#4C4C4C"
      blue: "#1E90FF"
      blueB: "#4682B4"
      cyan: "#00CDCD"
      cyanB: "#00FFFF"
      green: "#00CD00"
      greenB: "#00FF00"
      magenta: "#CD00CD"
      magentaB: "#FF00FF"
      name: "xterm"
      red: "#CD0000"
      redB: "#FF0000"
      white: "#E5E5E5"
      whiteB: "#FFFFFF"
      yellow: "#CDCD00"
      yellowB: "#FFFF00"
    - black: "#000000"
      blackB: "#555555"
      blue: "#0000AA"
      blueB: "#5555FF"
      cyan: "#00AAAA"
      cyanB: "#55FFFF"
      defaultBackground: 0
      defaultForeground: 7
      green: "#00AA00"
      greenB: "#55FF55"
      magenta: "#AA00AA"
      magentaB: "#FF55FF"
      name: "vga"
      red: "#AA0000"
      redB: "#FF5555"
      white: "#AAAAAA"
      whiteB: "#FFFFFF"
      yellow: "#AA5500"
      yellowB: "#FFFF55"
    - black: "black"
      blackB: "black"
      blue: "blue"
      blueB: "blue"
      cyan: "cyan"
      cyanB: "cyan"
      green: "green"
      greenB: "green"
      magenta: "magenta"
      magentaB: "magenta"
      name: "css"
      red: "red"
      redB: "red"
      white: "white"
      whiteB: "white"
      yellow: "yellow"
      yellowB: "yellow"
    - black: "#2E3436"
      blackB: "#2E3436"
      blue: "#3465A4"
      blueB: "#3465A4"
      cyan: "#06989A"
      cyanB: "#06989A"
      defaultBackground: 0
      defaultForeground: 7
      green: "#4E9A06"
      greenB: "#4E9A06"
      magenta: "#75507B"
      magentaB: "#75507B"
      name: "gnome-terminal"
      red: "#CC0000"
      redB: "#CC0000"
      white: "#D3D7CF"
      whiteB: "#D3D7CF"
      yellow: "#C4A000"
      yellowB: "#C4A000"
  buildDiscarders:
    configuredBuildDiscarders:
    - "jobBuildDiscarder"
  buildMonitorView:
    permissionToCollectAnonymousUsageStatistics: true
  buildStepOperation:
    enabled: false
  defaultFolderConfiguration:
    healthMetrics:
    - worstChildHealthMetric:
        recursive: true
  extendedEmailPublisher:
    adminRequiredForTemplateTesting: false
    allowUnregisteredEnabled: false
    charset: "UTF-8"
    debugMode: false
    defaultBody: |-
      $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS:

      Check console output at $BUILD_URL to view the results.
    defaultSubject: "$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!"
    maxAttachmentSize: -1
    maxAttachmentSizeMb: 0
    precedenceBulk: false
    useSsl: false
    watchingEnabled: false
  gitHubConfiguration:
    apiRateLimitChecker: ThrottleForNormalize
  gitHubPluginConfig:
    hookUrl: "http://localhost:8080/github-webhook/"
  gitSCM:
    createAccountBasedOnEmail: false
    showEntireCommitSummaryInChanges: false
    useExistingAccountWithSameEmail: false
  location:
    adminAddress: "address not configured yet <nobody@nowhere>"
    url: "http://localhost:8080/"
  mailer:
    charset: "UTF-8"
    useSsl: false
    useTls: false
  pollSCM:
    pollingThreadCount: 10
  timestamperConfig:
    allPipelines: false
    elapsedTimeFormat: "'<b>'HH:mm:ss.S'</b> '"
    systemTimeFormat: "'<b>'HH:mm:ss'</b> '"
tool:
  git:
    installations:
    - home: "git"
      name: "Default"

@timja
Copy link
Member Author

timja commented May 13, 2020

  securityRealm:
    local:
      allowsSignup: false
      enableCaptcha: false
      users:
      - id: "yolan"
        name: "yolan"
        properties:
        - "apiToken"
        - "myView"
        - preferredProvider:
            providerId: "default"
        - "timezone"
        - mailer:
            emailAddress: "hello@yolan.dev"

remove "myView", you'll likely also want to remove "apiToken" and I'm not sure if "timeZone" will work when empty like that (it may)

@daniel-beck
Copy link
Member

@Y0lan Please ask for help in chat or on the users mailing list, or report bugs in the issue tracker.

@jakehelme
Copy link

  securityRealm:
    local:
      allowsSignup: false
      enableCaptcha: false
      users:
      - id: "yolan"
        name: "yolan"
        properties:
        - "apiToken"
        - "myView"
        - preferredProvider:
            providerId: "default"
        - "timezone"
        - mailer:
            emailAddress: "hello@yolan.dev"

remove "myView", you'll likely also want to remove "apiToken" and I'm not sure if "timeZone" will work when empty like that (it may)

I was having a similar issue and removing "myView", "apiToken" and "timeZone" made things start working.

@jenkinsci jenkinsci locked as off-topic and limited conversation to collaborators Oct 14, 2020
@timja timja deleted the timezone-property branch May 7, 2021 11:53
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback rfe For changelog: Minor enhancement. use `major-rfe` for changes to be highlighted
Projects
None yet
9 participants