Skip to content

[virtual-machine] Disable instanceType validation - #1300

Merged
Timofei Larkin (lllamnyp) merged 1 commit into
mainfrom
fix/disable-instancetype-validation
Aug 4, 2025
Merged

[virtual-machine] Disable instanceType validation#1300
Timofei Larkin (lllamnyp) merged 1 commit into
mainfrom
fix/disable-instancetype-validation

Conversation

@lllamnyp

@lllamnyp Timofei Larkin (lllamnyp) commented Aug 4, 2025

Copy link
Copy Markdown
Member

What this PR does

Workaround for #1299. If a Cozystack installation provides custom instance types for virtual machines, the static validation rules prevent such instance types from being used, as they are included in the OpenAPI schema of the Cozystack API server and then once more applied in the dependent HelmRelease, offering users no easy way to remedy this in runtime.

Release note

[virtual-machine] Disable instanceType validation to enable using custom instance types.

Summary by CodeRabbit

  • New Features
    • Updated chart versions for virtual machine and VM instance applications.
  • Refactor
    • Relaxed restrictions on instance type selection, allowing any string value.
  • Chores
    • Updated version mappings for virtual machine and VM instance packages.

@coderabbitai

coderabbitai Bot commented Aug 4, 2025

Copy link
Copy Markdown
Contributor

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

The changes update version mappings and chart versions for the virtual-machine and vm-instance packages. The JSON schemas for both apps are modified by removing the enum restriction on the instanceType property, allowing any string value. Corresponding Makefile logic that dynamically generated these enums is commented out.

Changes

Cohort / File(s) Change Summary
Version Mapping Updates
packages/apps/versions_map
Updated version-to-commit mappings for virtual-machine and vm-instance; pinned previous HEAD versions to specific commits and added new versions with HEAD.
Chart Version Bumps
packages/apps/virtual-machine/Chart.yaml, packages/apps/vm-instance/Chart.yaml
Incremented chart versions for virtual-machine (to 0.12.3) and vm-instance (to 0.10.2).
Schema Generation Makefile Adjustments
packages/apps/virtual-machine/Makefile, packages/apps/vm-instance/Makefile
Commented out Makefile commands that dynamically set the instanceType enum in the JSON schemas based on instancetypes.yaml.
JSON Schema Relaxation
packages/apps/virtual-machine/values.schema.json, packages/apps/vm-instance/values.schema.json
Removed the enum restriction from the instanceType property, leaving only "type": "string" without enumerated values.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Makefile
    participant values_schema

    User->>Makefile: Run generate target
    Makefile--x values_schema: (Old) Update instanceType enum from instancetypes.yaml (now commented out)
    Makefile->>values_schema: Update other schema fields (instanceProfile enum, etc.)
    User->>values_schema: Validate config (instanceType unrestricted)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • cozystack/cozystack#776: Updates version mappings for virtual-machine and vm-instance by pinning versions and adding new entries.
  • cozystack/cozystack#430: Introduces the initial virtual-machine package and versions, which this PR modifies and builds upon.
  • cozystack/cozystack#569: Also updates version-to-commit mappings for virtual-machine and vm-instance.

Suggested labels

enhancement, size:S

Poem

🐇
No enums fence the instance type,
Versions pinned, charts ripe.
Makefiles pause their schema chase,
Flexibility now takes its place.
A rabbit’s hop in code’s embrace!
🥕✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6eb7a6 and 44fabd4.

📒 Files selected for processing (7)
  • packages/apps/versions_map (2 hunks)
  • packages/apps/virtual-machine/Chart.yaml (1 hunks)
  • packages/apps/virtual-machine/Makefile (1 hunks)
  • packages/apps/virtual-machine/values.schema.json (1 hunks)
  • packages/apps/vm-instance/Chart.yaml (1 hunks)
  • packages/apps/vm-instance/Makefile (1 hunks)
  • packages/apps/vm-instance/values.schema.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/apps/virtual-machine/Chart.yaml
  • packages/apps/vm-instance/Chart.yaml
  • packages/apps/vm-instance/values.schema.json
  • packages/apps/vm-instance/Makefile
  • packages/apps/virtual-machine/Makefile
  • packages/apps/virtual-machine/values.schema.json
  • packages/apps/versions_map
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install Cozystack
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/disable-instancetype-validation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Summary of Changes

Hello Timofei Larkin (@lllamnyp), I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request provides a critical workaround for an existing limitation in Cozystack that prevented the use of custom virtual machine instance types. By removing the static instanceType validation from the Helm chart schemas and adjusting the build process, users can now freely define and utilize their own instance types. This change impacts both the virtual-machine and vm-instance applications, ensuring greater flexibility in VM provisioning.

Highlights

  • Disable Instance Type Validation: The primary change in this PR is the removal of static validation for instanceType in the virtual-machine and vm-instance Helm charts. This addresses an issue where custom instance types could not be used due to rigid schema validation.
  • Schema Modifications: The enum constraint for the instanceType property has been removed from values.schema.json in both virtual-machine and vm-instance applications. This allows users to specify any string as an instance type, enabling the use of custom types.
  • Build Process Adjustment: The Makefile for both virtual-machine and vm-instance has been updated to comment out the step that dynamically populates the instanceType enum in the values.schema.json from kubevirt-instancetypes templates. This ensures the schema remains flexible.
  • Version Bumps: The Helm chart versions for virtual-machine (0.12.2 to 0.12.3) and vm-instance (0.10.1 to 0.10.2) have been incremented. Corresponding updates were made in the versions_map file.
  • SSH Keys Schema Improvement: A minor improvement was made to the values.schema.json for both virtual-machine and vm-instance to explicitly define the items type as string for the sshKeys array, enhancing schema clarity.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@kvaps Andrei Kvapil (kvaps) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@lllamnyp Timofei Larkin (lllamnyp) added the backport Should change be backported on previous release label Aug 4, 2025

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request disables static validation for instanceType in the virtual-machine and vm-instance Helm charts, enabling the use of custom instance types. The changes involve commenting out validation logic in Makefiles and removing the enum from values.schema.json. Additionally, the sshKeys schema is updated to specify the item type as string. Consider removing the commented-out code in the Makefiles to improve maintainability.

Comment on lines +6 to +7
# INSTANCE_TYPES=$$(yq e '.metadata.name' -o=json -r ../../system/kubevirt-instancetypes/templates/instancetypes.yaml | yq 'split(" ") | . + [""]' -o json) \
# && yq -i -o json ".properties.instanceType.enum = $${INSTANCE_TYPES}" values.schema.json

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Consider removing these commented-out lines to reduce clutter. The code can be retrieved from Git history if needed.

Comment on lines +7 to +8
#INSTANCE_TYPES=$$(yq e '.metadata.name' -o=json -r ../../system/kubevirt-instancetypes/templates/instancetypes.yaml | yq 'split(" ") | . + [""]' -o json) \
# && yq -i -o json ".properties.instanceType.enum = $${INSTANCE_TYPES}" values.schema.json

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Consider removing these commented-out lines to reduce clutter. The code can be retrieved from Git history if needed.

"default": [],
"description": "List of SSH public keys for authentication. Can be a single key or a list of keys.",
"items": {},
"items": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Adding type: string to the items property of sshKeys ensures that the schema accurately reflects the expected data type. This improves schema validation and helps prevent potential errors.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
packages/apps/virtual-machine/Makefile (1)

6-7: Commented-out enum generation may leave README/schema out of sync

Removing the instanceType enum injection fulfils the PR goal, but it also means:
values.schema.json will no longer list available instance types.
• The generated README will lose the autocomplete/details those enums provided.

Please verify that downstream tooling (UI forms, docs, validation in CI) tolerates the open string and that README expectations are updated.

packages/apps/vm-instance/Makefile (1)

7-8: Ensure documentation still renders correctly after disabling instanceType enum

Same concern as in the virtual-machine Makefile: the README generator will now emit an unconstrained string field. Double-check user guidance/docs so that operators know what values are acceptable.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ddbe32 and a6eb7a6.

📒 Files selected for processing (7)
  • packages/apps/versions_map (2 hunks)
  • packages/apps/virtual-machine/Chart.yaml (1 hunks)
  • packages/apps/virtual-machine/Makefile (1 hunks)
  • packages/apps/virtual-machine/values.schema.json (2 hunks)
  • packages/apps/vm-instance/Chart.yaml (1 hunks)
  • packages/apps/vm-instance/Makefile (1 hunks)
  • packages/apps/vm-instance/values.schema.json (2 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: NickVolynkin
PR: cozystack/cozystack#1216
File: packages/apps/virtual-machine/values.yaml:0-0
Timestamp: 2025-07-26T18:12:05.641Z
Learning: In the cozystack repository, for the virtual-machine app's resources.sockets parameter, the value is intentionally kept as a string in values.yaml despite being documented as {int} type, because the string-to-integer parsing happens elsewhere in the system pipeline rather than at the YAML validation level.
Learnt from: NickVolynkin
PR: cozystack/cozystack#1196
File: packages/apps/http-cache/Makefile:24-27
Timestamp: 2025-07-14T16:23:12.803Z
Learning: In the cozystack repository, the `readme-generator` tool removes enum contents from values.schema.json files during its operation. Therefore, when using readme-generator in Makefiles, any enum values need to be injected back into the schema using yq commands after readme-generator has run, not before.
Learnt from: lllamnyp
PR: cozystack/cozystack#1233
File: packages/system/hetzner-robotlb/charts/robotlb/templates/deployment.yaml:33-35
Timestamp: 2025-07-23T09:15:09.658Z
Learning: The `./charts/robotlb/` directory in the hetzner-robotlb package contains vendored code, and the team generally avoids modifying vendored code to maintain clean separation from upstream dependencies.
📚 Learning: the `./charts/robotlb/` directory in the hetzner-robotlb package contains vendored code, and the tea...
Learnt from: lllamnyp
PR: cozystack/cozystack#1233
File: packages/system/hetzner-robotlb/charts/robotlb/templates/deployment.yaml:33-35
Timestamp: 2025-07-23T09:15:09.658Z
Learning: The `./charts/robotlb/` directory in the hetzner-robotlb package contains vendored code, and the team generally avoids modifying vendored code to maintain clean separation from upstream dependencies.

Applied to files:

  • packages/apps/virtual-machine/Chart.yaml
  • packages/apps/vm-instance/Chart.yaml
📚 Learning: in the cozystack repository, the `readme-generator` tool removes enum contents from values.schema.js...
Learnt from: NickVolynkin
PR: cozystack/cozystack#1196
File: packages/apps/http-cache/Makefile:24-27
Timestamp: 2025-07-14T16:23:12.803Z
Learning: In the cozystack repository, the `readme-generator` tool removes enum contents from values.schema.json files during its operation. Therefore, when using readme-generator in Makefiles, any enum values need to be injected back into the schema using yq commands after readme-generator has run, not before.

Applied to files:

  • packages/apps/virtual-machine/Makefile
  • packages/apps/vm-instance/Makefile
📚 Learning: in packages/apps/versions_map, using head for certain versions (like ferretdb 1.0.0) is intentional ...
Learnt from: kvaps
PR: cozystack/cozystack#1206
File: packages/apps/versions_map:30-31
Timestamp: 2025-07-16T13:17:07.580Z
Learning: In packages/apps/versions_map, using HEAD for certain versions (like ferretdb 1.0.0) is intentional and part of the core logic, not an oversight that needs to be fixed for reproducibility.

Applied to files:

  • packages/apps/versions_map
📚 Learning: in the cozystack repository, for the virtual-machine app's resources.sockets parameter, the value is...
Learnt from: NickVolynkin
PR: cozystack/cozystack#1216
File: packages/apps/virtual-machine/values.yaml:0-0
Timestamp: 2025-07-26T18:12:05.641Z
Learning: In the cozystack repository, for the virtual-machine app's resources.sockets parameter, the value is intentionally kept as a string in values.yaml despite being documented as {int} type, because the string-to-integer parsing happens elsewhere in the system pipeline rather than at the YAML validation level.

Applied to files:

  • packages/apps/virtual-machine/values.schema.json
  • packages/apps/vm-instance/values.schema.json
🪛 GitHub Actions: Pre-Commit Checks
packages/apps/virtual-machine/values.schema.json

[error] 123-131: Make generate step failed: The file was modified by the hook, indicating schema changes in the 'sshKeys.items' property from type 'string' to an empty object.

packages/apps/vm-instance/values.schema.json

[error] 131-139: Make generate step failed: The file was modified by the hook, indicating schema changes in the 'sshKeys.items' property from type 'string' to an empty object.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (5)
packages/apps/virtual-machine/Chart.yaml (1)

20-20: Chart version bump LGTM

Patch-level increment to 0.12.3 is consistent with a backwards-compatible schema relaxation. No further issues noticed.

packages/apps/vm-instance/Chart.yaml (1)

20-20: Chart version bump LGTM

Version 0.10.2 correctly reflects the minor schema change while keeping semantic compatibility.

packages/apps/versions_map (1)

177-178: Version pinning looks correct—confirm commit hashes

Pinning former HEAD versions (0.12.2 / 0.10.1) to 8ddbe32e and advancing HEAD is the expected pattern. Please verify that 8ddbe32e indeed corresponds to the last commit before this PR landed to avoid reproducibility gaps.

Also applies to: 197-198

packages/apps/vm-instance/values.schema.json (1)

101-105: Enum removal weakens validation – consider a minimal safeguard

Dropping the enum entirely achieves the goal of allowing custom types, but it also accepts empty strings or obviously invalid identifiers. Adding a lightweight constraint such as

"minLength": 1

inside the same object would still permit arbitrary custom values while preventing empty/accidental input.

packages/apps/virtual-machine/values.schema.json (1)

93-97: Same validation relaxation as vm-instance – ensure runtime handles unknown types

With the enum removed, any string (e.g. typos) reaches the controller. Double-check that downstream components fail fast or surface clear errors when an invalid instance type is requested, otherwise user experience may degrade.

Comment on lines 123 to 127
"sshKeys": {
"default": [],
"description": "List of SSH public keys for authentication. Can be a single key or a list of keys.",
"items": {},
"items": {
"type": "string"
},
"type": "array"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

CI failure identical to vm-instance – fix generation drift

sshKeys.items was changed to "type": "string" but the pre-commit hook expects {}. Align the generator or regenerate the schema as noted in the sibling file.

🧰 Tools
🪛 GitHub Actions: Pre-Commit Checks

[error] 123-131: Make generate step failed: The file was modified by the hook, indicating schema changes in the 'sshKeys.items' property from type 'string' to an empty object.

🤖 Prompt for AI Agents
In packages/apps/virtual-machine/values.schema.json around lines 123 to 129, the
sshKeys.items property is set to "type": "string" but the pre-commit hook
expects an empty object {}. To fix this, update sshKeys.items to be an empty
object {} to match the expected schema format or regenerate the schema file
using the same process as the sibling vm-instance file to avoid generation
drift.

Comment on lines 131 to 135
"sshKeys": {
"default": [],
"description": "List of SSH public keys for authentication. Can be a single key or a list of keys.",
"items": {},
"items": {
"type": "string"
},
"type": "array"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Pre-commit pipeline is red – generated schema disagrees on sshKeys.items

CI shows Make generate step failed: The file was modified by the hook, meaning the generator reverted "items": {"type": "string"} back to {}.
Either:

  1. Re-run make generate to commit the generator’s output, or
  2. Update the generation logic (Makefile/yq step) so that it preserves the explicit string type.

Until this mismatch is fixed the PR cannot merge.

🧰 Tools
🪛 GitHub Actions: Pre-Commit Checks

[error] 131-139: Make generate step failed: The file was modified by the hook, indicating schema changes in the 'sshKeys.items' property from type 'string' to an empty object.

🤖 Prompt for AI Agents
In packages/apps/vm-instance/values.schema.json around lines 131 to 137, the
pre-commit pipeline fails because the generated schema disagrees on the
definition of sshKeys.items, which should explicitly specify "type": "string"
but the generator reverts it to an empty object. To fix this, either re-run the
make generate command to update and commit the generated schema output
reflecting this change, or modify the generation logic in the Makefile or yq
step to ensure it preserves the explicit "type": "string" for sshKeys.items.
This will align the committed schema with the generator output and allow the PR
to pass CI.

Workaround for #1299. If a Cozystack installation provides custom
instance types for virtual machines, the static validation rules prevent
such instance types from being used, as they are included in the OpenAPI
schema of the Cozystack API server and then once more applied in the
dependent HelmRelease, offering users no easy way to remedy this in
runtime.

[virtual-machine] Disable instanceType validation to enable using custom
instance types.

Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
@lllamnyp
Timofei Larkin (lllamnyp) force-pushed the fix/disable-instancetype-validation branch from a6eb7a6 to 44fabd4 Compare August 4, 2025 12:16
@lllamnyp
Timofei Larkin (lllamnyp) merged commit 98f8626 into main Aug 4, 2025
19 of 20 checks passed
@lllamnyp
Timofei Larkin (lllamnyp) deleted the fix/disable-instancetype-validation branch August 4, 2025 12:45
@github-actions

github-actions Bot commented Aug 4, 2025

Copy link
Copy Markdown

Successfully created backport PR for release-0.33:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport Should change be backported on previous release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants