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

Can't register new Kubernetes schemas #12

Open
joshfrench opened this issue Aug 23, 2022 · 7 comments
Open

Can't register new Kubernetes schemas #12

joshfrench opened this issue Aug 23, 2022 · 7 comments

Comments

@joshfrench
Copy link
Contributor

joshfrench commented Aug 23, 2022

When I use the default k8s detection, diagnostics work as expected:

Screen Shot 2022-08-23 at 16 58 30

However, when I try to use a custom schema I do not get any diagnostics. I am able to select a custom schema via :Telescope yaml_schema but once attached, any existing diagnostics disappear and I can't seem to trigger them again.

Here's my minimalized setup:

Env
Nvim 0.7.2
yaml-companion 0.1.1
-- init.lua
return require('packer').startup(function()
  use 'wbthomason/packer.nvim'

  use {
    "someone-stole-my-name/yaml-companion.nvim",
    requires = {
      { "neovim/nvim-lspconfig" },
      { "nvim-lua/plenary.nvim" },
      { "nvim-telescope/telescope.nvim" },
    },
    config = function()
      require("telescope").load_extension("yaml_schema")
      local cfg = require("yaml-companion").setup({
        schemas = {
          result = {
            {
              name = "Kubernetes 1.22.5",
              uri = "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.22.5-standalone-strict/all.json",
            },
          },
        },
      })
      require("lspconfig")["yamlls"].setup(cfg)
    end,
  }
end)
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
foo: bar

Output of :lua =require("yaml-companion.config").options:

{
  builtin_matchers = {
    kubernetes = {
      enabled = true
    }
  },
  lspconfig = {
    flags = {
      debounce_text_changes = 150
    },
    on_attach = <function 1>,
    settings = {
      redhat = {
        telemetry = {
          enabled = false
        }
      },
      yaml = {
        format = {
          enable = true
        },
        hover = true,
        schemaDownload = {
          enable = true
        },
        schemaStore = {
          enable = true,
          url = "https://www.schemastore.org/api/json/catalog.json"
        },
        schemas = {
          result = {}
        },
        trace = {
          server = "debug"
        },
        validate = true
      }
    },
    single_file_support = true
  },
  schemas = {
    result = { {
        name = "Kubernetes 1.22.5",
        uri = "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.22.5-standalone-strict/all.json"
      } }
  }
}

After running :Telescope yaml_schema and selecting Kubernetes 1.22.5, output of :lua =require("yaml-companion").get_buf_schema(0):

{
  result = { {
      name = "Kubernetes 1.22.5",
      uri = "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.22.5-standalone-strict/all.json"
    } }
}

I've also tried cloning the kubernetes-json-schema repo and pointing at a local path, but that didn't change anything.

One slightly weird wrinkle: if I set up a custom schema pointing at v1.22.4 to match the builtin, diagnostics work. Downgrading past that breaks them again though, so this may be a cached artifact? ¯\_(ツ)_/¯

@joshfrench
Copy link
Contributor Author

Updating this to add some LSP logs. This is what follows after selecting the custom schema with :Telescope yaml_schemas.

"rpc.send"
{ jsonrpc = "2.0", method = "workspace/didChangeConfiguration",
    params = { settings = { redhat = { telemetry = { enabled = false } },
      yaml = { format = { enable = true }, hover = true, schemaDownload = { enable = true },
        schemaStore = { enable = true, url = "https://www.schemastore.org/api/json/catalog.json" },
        schemas = { ["https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.22.5-standalone-strict/all.json"] = "file:///Users/josh/src/joshfrench/yaml-companion.nvim/ingress.yaml",
          result = {} }, trace = { server = "debug" }, validate = true } } } }

"rpc.receive"
{ id = 4, jsonrpc = "2.0", method = "workspace/configuration",
    params = { items = { { section = "yaml" }, { section = "http" }, { section = "[yaml]" },
      { section = "editor" }, { section = "files" } } } }

"server_request: callback result"
{ result = { { format = { enable = true }, hover = true, schemaDownload = { enable = true },
    schemaStore = { enable = true, url = "https://www.schemastore.org/api/json/catalog.json" },
    schemas = { ["https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.22.5-standalone-strict/all.json"] = "file:///Users/josh/src/joshfrench/yaml-companion.nvim/ingress.yaml",
      result = {} }, trace = { server = "debug" }, validate = true }, vim.NIL, vim.NIL, vim.NIL, vim.NIL }, status = true }

"rpc.send"
{ id = 4, jsonrpc = "2.0",
    result = { { format = { enable = true }, hover = true, schemaDownload = { enable = true },
      schemaStore = { enable = true, url = "https://www.schemastore.org/api/json/catalog.json" },
      schemas = { ["https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.22.5-standalone-strict/all.json"] = "file:///Users/josh/src/joshfrench/yaml-companion.nvim/ingress.yaml",
        result = {} }, trace = { server = "debug" }, validate = true }, vim.NIL, vim.NIL, vim.NIL, vim.NIL } }

"rpc.receive"
{ jsonrpc = "2.0", method = "yaml/schema/store/initialized", params = vim.empty_dict() }

"rpc.receive"
{ jsonrpc = "2.0", method = "textDocument/publishDiagnostics",
    params = { diagnostics = {}, uri = "file:///Users/josh/src/joshfrench/yaml-companion.nvim/ingress.yaml" } }

It looks like the client is correctly sending workspace/didChangeConfiguration, but the server doesn't think there are any diagnostics to report (and never does, no matter what I do to the file.) If I choose a built-in schema instead, things work as expected.

At this point I'm not sure if the issue is here or in yaml-language-server.

@someone-stole-my-name
Copy link
Owner

This is most likely an issue in yaml-language-server as you say, let's try to isolate the issue and report the bug upstream 🙏

@joshfrench
Copy link
Contributor Author

Possibly related? redhat-developer/yaml-language-server#60

@someone-stole-my-name
Copy link
Owner

Diagnostics break even just changing the default version in version.lua from 1.22.4 to 1.22.5. Oddly enough, all schema files are the same if you remove the version from the files (sed -i 's/v1.22.X//g' *).

@Shinzu
Copy link

Shinzu commented Dec 30, 2022

I have the same problem,after some digging i believe this is due to a hard coded version in yaml-language-server itself:

https://github.com/redhat-developer/yaml-language-server/blob/main/src/languageservice/utils/schemaUrls.ts#L8

as workaround i "patched" the node files in the location where mason install the server:

cd ~/.local/share/nvim/mason/packages/yaml-language-server/node_modules/yaml-language-server
grep -r -l 1.22.4 | xargs sed -i 's/1.22.4/1.22.17/g'

you have to add the schema then in the config:

...
  schemas = {
    result = {
      {
        name = "Kubernetes 1.22.17",
        uri = "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.22.17-standalone-strict/all.json",
      },
    },
  },
...

afterwards the validation and completion works for me, if i choose the added schema with Telescope yaml_schema

image

@someone-stole-my-name
Copy link
Owner

someone-stole-my-name commented Jan 2, 2023

The hack seems to work, thanks for looking into it.

For a more future-proof hack that works with any version, you can change the conditions on line 339 and 343 of src/languageserver/handlers/settingsHandlers.ts to something like:

        if (fileMatch.constructor === Array && uri.search(/kubernetes-json-schema/)) {
            fileMatch.forEach((url) => {
                this.yamlSettings.specificValidatorPaths.push(url);
            });
        }
        else if (uri.search(/kubernetes-json-schema/)) {
            this.yamlSettings.specificValidatorPaths.push(fileMatch);
        }

I haven't looked into why they have those conditions just for Kubernetes, but it works.

@mosheavni
Copy link
Contributor

The hack seems to work, thanks for looking into it.

For a more future-proof hack that works with any version, you can change the conditions on line 339 and 343 of src/languageserver/handlers/settingsHandlers.ts to something like:

        if (fileMatch.constructor === Array && uri.search(/kubernetes-json-schema/)) {
            fileMatch.forEach((url) => {
                this.yamlSettings.specificValidatorPaths.push(url);
            });
        }
        else if (uri.search(/kubernetes-json-schema/)) {
            this.yamlSettings.specificValidatorPaths.push(fileMatch);
        }

I haven't looked into why they have those conditions just for Kubernetes, but it works.

hey @someone-stole-my-name
I patched yaml-language-server with your changes but it seems that specifically on Kubernetes, there are no completions if you did not configure kubernetes = '/*.yaml' on your lsp config:

  local yaml_cfg = require('yaml-companion').setup {
    builtin_matchers = {
      -- Detects Kubernetes files based on content
      kubernetes = { enabled = true },
    },
    schemas = {
      {
        name = 'Kubernetes 1.27.12',
        uri = 'https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.27.12-standalone-strict/all.json',
      },
      {
        name = 'Kubernetes 1.26.14',
        uri = 'https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.26.14-standalone-strict/all.json',
      },
    },
    lspconfig = {
      on_attach = default_on_attach,
      capabilities = capabilities,
      cmd = { 'node', vim.fn.expand '~/Repos/yaml-language-server/out/server/src/server.js', '--stdio' },
      settings = {
        yaml = {
          -- if these lines are commented out, there are no completions
          -- schemas = {
          --   kubernetes = '/*',
          -- },
        },
      },
    },
  }
  require('lspconfig')['yamlls'].setup(yaml_cfg)

however, if I comment in those lines, I cannot get completion on any other schema since it's recognized as kubernetes.
what am I doing wrong?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants