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

Hooks for Data Center #103

Draft
wants to merge 52 commits into
base: master
Choose a base branch
from

Conversation

dagguh
Copy link
Contributor

@dagguh dagguh commented Feb 26, 2021

It's a preview of how to inject hooks to an entire cluster. It includes wiring up the database via hooks. The old MySqlDatabase silently relied on a distant StandaloneNodeFormula to:

  • install the JDBC connector
  • edit a preexisting dbconfig.xml

Now, as a hook, it can do all of that on its own. Moreover, other databases can be hooked in too.

It's a draft, because it depends on #102 and it doesn't have a DC test yet. The DC test will very likely introduce a DataCenterFormula, like from aws-infrastructure, but generalized. Perhaps I'll be able to split the database and DC features into separate PRs.

@dagguh dagguh requested a review from a team as a code owner February 26, 2021 15:57
@dagguh dagguh marked this pull request as draft March 12, 2021 10:50
@dagguh dagguh mentioned this pull request Apr 2, 2021
@dagguh
Copy link
Contributor Author

dagguh commented Apr 2, 2021

Currently Jira starts and MySQL starts, but Jira doesn't have connectivity to MySQL. It's because it doesn't know its IP. The ssh-ubuntu Docker code is based on testcontainers, which don't offer peer container IPs. The getTestHostIpAddress throws explicitly. I'll try to bump testcontainers or harvest the lower-level Docker code from virtual-users.

@dagguh
Copy link
Contributor Author

dagguh commented Apr 2, 2021

To make it work I'll have to distinguish public and private IPs. A Docker network is equivalent to an AWS VPC, so the TcpHost API changes make general sense. However, notion of private/public ports doesn't generalize, such mapping is only relevant in Dockers, so that should go away from the API. The FromPort and ToPort in AWS::EC2::SecurityGroup model a range of ports, not a mapping.

@dagguh dagguh force-pushed the issue/JPERF-273-transplant-ssh-jira-nodes-fix-aws-dc branch from a630413 to 4b9cba4 Compare April 23, 2021 17:05
}

fun webdriver(): List<String> = listOf(
"selenium-support",
"selenium-chrome-driver"
).map { module ->
"org.seleniumhq.selenium:$module:3.11.0"
"org.seleniumhq.selenium:$module:[3.11.0, 3.999.999]"
Copy link
Contributor

Choose a reason for hiding this comment

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

If there is a reason why it's not

Suggested change
"org.seleniumhq.selenium:$module:[3.11.0, 3.999.999]"
"org.seleniumhq.selenium:$module:[3.11.0, 4.0.0)"

then IMHO it should be noted in a comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch. They polluted their release channel with unstable versions like 4.0.0-alpha-1

  • put 3.999.999 rationale in the comment

Comment on lines +51 to +53
fun serveTest(): Ssh {
return serveSsh("ssh")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand this method. Why shouldn't it be inlined?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, inlining is ok

  • inline serveTest

dagguh and others added 22 commits May 7, 2021 16:49
Add `DockerPostgresServer` as a hook too.
Include overall Data Center plan with hook timings.
Plans should be reusable with different ways of getting a `TcpHost`:
* new via Docker
* new via AWS
* existing machines

This commit injects an `Infrastructure` SPI to reuse a plan with
different infra, but to prove the concept, it has to fit the current
CloudFormation stack in aws-infrastructure / 2-nodes-dc*.yaml
The API smells a little, because a big one-shot CFN stack is split into
multiple fine-grained methods.

Alternative API could be: `fun plan(host: TcpHost) : JiraNodePlan`

Other matters to resolve:
* loadbalancer (plan?) API
* getting results out of DC instance and node hooks
@dagguh dagguh force-pushed the issue/JPERF-273-transplant-ssh-jira-nodes-fix-aws-dc branch from 875719b to 52e96e4 Compare May 21, 2021 11:27
@dagguh
Copy link
Contributor Author

dagguh commented May 21, 2021

Today I fixed docker-in-docker both in WSL and in GitHub Actions. I fixed assertions. The only red test now is RestUpgrade timeout flake on GHA.
TODO:

  • add a Report that would print the appropriate log
  • expose the downloaded Reports as GHA artifacts

@dagguh dagguh force-pushed the issue/JPERF-273-transplant-ssh-jira-nodes-fix-aws-dc branch 3 times, most recently from cdbc664 to d7f6039 Compare June 25, 2021 15:50
@dagguh dagguh force-pushed the issue/JPERF-273-transplant-ssh-jira-nodes-fix-aws-dc branch from d7f6039 to 3b7ac69 Compare June 25, 2021 16:55
@dagguh dagguh force-pushed the issue/JPERF-273-transplant-ssh-jira-nodes-fix-aws-dc branch from 3b7ac69 to 27b9bc4 Compare June 25, 2021 18:16
dagguh added 8 commits July 2, 2021 17:44
Some architectural answers:
* `JiraInstancePlan`, `JiraNodePlan`, `JiraInstallation`, `JiraStart`,
    are all lightweight plans without any resources
* `HttpNode`, `InstalledJira`, `StartedJira`, `JiraInstance`
   are all resources without any plans
* plans are independent from each other and don't talk,
    even through resources

Open questions:
* same as previous commit: who controls the ports?
    `ParallelInstallation` has run into trouble when it ignored the
     factual `HttpNode` it received
import com.atlassian.performance.tools.infrastructure.api.jira.report.Reports
import com.atlassian.performance.tools.ssh.api.SshConnection

class DatabaseIpConfig(
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about a pattern of naming things more as what they represent in code rather than what they symolise? Naming is obviously very important because it's highly connected to how we model the system.

Maybe this class should be named DatabaseIpConfigurator instead? IMHO it doesn't represent the config, because if it would then I'd expect it to return some data. Configurator is someone/something that doesn't tell us what the config is, but it's capable of configuring which this class seem to be doing. It's like an expert who is not telling us how did he do something, yet there could be a manual that tells us how thing should be done.

Copy link
Contributor Author

@dagguh dagguh Feb 1, 2022

Choose a reason for hiding this comment

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

It does represent the config, it has the data:

 private val databaseIp: String

It could hold more data when such need is discovered.
It's also a post-install hook, which applies the data.
It does not represent the config file.

Copy link
Contributor

Choose a reason for hiding this comment

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

It consumes the data and doesn't expose it.

Don't you think that if the data would need to be exposed it should be made as part of different class with different responsibility? I see configurator and configuration as 2 different things that should be separated. I may want to reuse configuration, yet do the process of configuration (configurator implementation) differently in some cases - in such case I'd like to reimplement configurator and not the configuration.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, so lets imagine if there's a new way of applying a database IP: via YAML. Then we could add a new YamlDatabaseIpConfig alternative. It's a naming/semantics conflict, DatabaseIpConfig is no longer the canonical DTO. Or we could modify it to choose between XML and YAML modification transparently. But such impl might be impossible, so separating the behavior from the data gives us more options.

I kinda see the point.

I hoped to hide details from the caller. Now we'd have to call it DatabaseXmlConfigIpSedReplacer "just in case" someone produces an alternative impl, differing in any aspect. That's a yikes name, too enterprisey. I have this tendency to try to speak the language of the user. What does the user need? Maybe we could defer the "just in case" refactoring and pay the price when it actually happens? 😁

We gotta choose the lesser evil: user-unfriendly names or a potential deprecation cycle.

Copy link
Contributor

@pczuj pczuj Feb 1, 2022

Choose a reason for hiding this comment

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

Naming seems to be always hard especially when balancing between correctness and readability.

Yes this class should be called DatabaseXmlConfigIpSedReplacer, however this shows how it has too many responsibilities:

  • It knows where the db config is
  • It knows that the db config is in XML format and that it has single <url> node inside
  • It knows the XML format
  • It knows the <url> format
  • It knows how to use sed (it even assumes it's available)

I believe the whole functionality was already somewhere in the JPT code (didn't I actually write it?), so I would be fine with leaving it in this granularity (and sed usage hack). Skipping some details and naming it DatabaseIpReplacer IMHO is good enough. With such name we could allow to override DbConfigXmlLocator, XmlValueReplacer, UrlParser, etc. in later changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed. The code already existed. The PR extracted these operations into a hookable API. It's the first step of decomposing DataCenterFormula and friends. Next waves of decomposition can follow afterwards.

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

Successfully merging this pull request may close these issues.

2 participants