Skip to content

Commit

Permalink
Add ability to set level of failure domain as cartridge zone (#147)
Browse files Browse the repository at this point in the history
* The `--fd-as-zone` option takes the value 1..255, which indicates at what level
nesting `hosts` contains the required name `zone`

For example, when configuring:
```yaml
hosts:
  - name: region
    hosts:
      - name: datacenter
        hosts:
          - name: host
```
Team:
```shell
genin build --fd-as-zone=2
```
We get:
```yaml
hosts:
  role:
    zone: datacenter
    config:
```

---------

Co-authored-by: Alexandr Sorokin <a.sorokin@picodata.io>
  • Loading branch information
lowitea and Alexandr Sorokin authored Apr 24, 2024
1 parent fee93b6 commit f51da44
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ CMakeFiles
cmake_install.cmake
*.dylib
*.idea
*.vscode
cluster.genin.yml
inventory.yml
__pycache__
*pyc
.cache
Expand Down
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,22 @@ launched `Genin`. Now we can set up the cluster:
ansible-playbook -i inventory.yaml playbook.yaml
```

### State

---

After each execution of the `genin build` command, the cluster state will be generated.
By default, the state will be stored in the `.geninstate` directory.
For all cluster changes, Genin is based on the "latest" state and
after updating it overwrites it.

:exclamation: Loss of `.geninstate` directory or `latest` state, `genin build` command recreates
configuration with new state

:exclamation: `genin build --recreate` recreates the configuration with a new state

---

---

### Editing the cluster configuration
Expand Down Expand Up @@ -445,8 +461,33 @@ will be on the specified hosts.

You can also use a failure domain name as a value for the [`zone`](https://github.com/tarantool/ansible-cartridge/blob/master/doc/variables.md?plain=1#L90) property of the instances config. Just add the `--fd-as-zone` flag to your `build` command, for example: `genin build --fd-as-zone`.

The `--fd-as-zone` option takes the value 1..255, which indicates at what level
nesting `hosts` contains the required name `zone`

With this flag, once the instances are distributed over the target hosts according to the failure_domains algorithm, the final host name of each instance becomes its zone parameter and gets stored in the instance's config.


For example, when configuring:
```yaml
hosts:
- name: region
hosts:
- name: datacenter
hosts:
- name: host
```
Team:
```shell
genin build --fd-as-zone=2
```
We get:
```yaml
hosts:
role:
zone: datacenter
config:
```

---

#### Configuration `ansible-host`
Expand Down
40 changes: 40 additions & 0 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,22 @@ ansible-playbook -i inventory.yaml playbook.yaml

---

### Состояние

---

После каждого выполнения команды `genin build` будет сформировано состояние кластера.
По умолчанию состояние будет храниться в директории `.geninstate`.
При всех последующих обновлениях кластера `Genin` основывается на состоянии `latest` и
после обновления перезапишет его.

:exclamation: Потеря директории `.geninstate` или состояния `latest` команда `genin build` пересоздаст
конфигруацию с новым состоянием

:exclamation: `genin build --recreate` пересоздаст конфигурацию с новым состоянием

---

### Редактирование конфигурации кластера

---
Expand Down Expand Up @@ -464,11 +480,35 @@ hosts:

Есть возможность использовать финальный хост (конкретный `failure_domain`, куда распределяется инстанс) в качестве параметра [`zone`](https://github.com/tarantool/ansible-cartridge/blob/master/doc/variables.md?plain=1#L90) в ansible-конфигурации инстанса. Для этого необходимо передать флаг `--fd-as-zone` в команду `build`, например: `genin build --fd-as-zone`.

Опция `--fd-as-zone` принимает значение 1..255, которое указываение на каком уровне
вложенности `hosts` находится нужное наименование `zone`

Точное поведение `Genin` при передаче этого флага будет следующим:

0. После работы стандартного алгоритма `failure_domains`, инстансы будут распределены на некоторые хосты согласно их конфигурации;
1. Имя итогового хоста, на который был распределен инстанс, будет использовано в качестве параметра `zone` в ansible-конфигурации инстанса.

Например, при конфигурации:
```yaml
hosts:
- name: region
hosts:
- name: datacenter
hosts:
- name: host
```
Команда:
```shell
genin build --fd-as-zone=2
```
Получим:
```yaml
hosts:
role:
zone: datacenter
config:
```

---

#### Параметр `ansible-host`
Expand Down
5 changes: 4 additions & 1 deletion src/task/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ pub(super) fn read() -> ArgMatches {
fn fd_as_zone_arg() -> Arg {
Arg::new("fd-as-zone")
.long("fd-as-zone")
.action(ArgAction::SetTrue)
.action(ArgAction::Set)
.num_args(0..=1)
.default_missing_value("1")
.value_parser(clap::value_parser!(u8))
.help("Used to insert 'failure_domain' field's value of instances in their 'zone' field.")
}
4 changes: 2 additions & 2 deletions src/task/cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,8 @@ impl Cluster {
/// Note that method is intended to be called after cluster is spread
/// - that's it, when there may only be single domain name in instance's `failure_domains`.
pub fn use_failure_domain_as_zone_for_instances(mut self, args: &ArgMatches) -> Self {
if args.get_flag("fd-as-zone") {
self.hosts.use_failure_domain_as_zone();
if let Ok(Some(lvl)) = args.try_get_one::<u8>("fd-as-zone") {
self.hosts.use_failure_domain_as_zone(*lvl);
}
self
}
Expand Down
8 changes: 6 additions & 2 deletions src/task/cluster/hst/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,14 +515,18 @@ fn hosts_use_failure_domain_as_zone() {
assert_eq!(failure_domain_instance_zone(&host, "cache-2-1"), None);
assert_eq!(failure_domain_instance_zone(&host, "cache-2-2"), None);

host.use_failure_domain_as_zone();
host.use_failure_domain_as_zone(1);
assert_eq!(
failure_domain_instance_zone(&host, "cache-2-1"),
Some("dc-2")
);
assert_eq!(
failure_domain_instance_zone(&host, "cache-2-2"),
Some("server-5")
Some("dc-2")
);
assert_eq!(
failure_domain_instance_zone(&host, "stateboard-1-1"),
Some("dc-1")
);
}

Expand Down
18 changes: 15 additions & 3 deletions src/task/cluster/hst/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,14 +774,26 @@ impl HostV2 {
}

/// For every instance that has finalized failure domain, replace its zone with that domain name.
pub fn use_failure_domain_as_zone(&mut self) {
pub fn use_failure_domain_as_zone(&mut self, dc_lvl: u8) {
let lvl: u8 = 0;
let zone: Option<String> = None;
self.set_zone(lvl, dc_lvl, zone)
}

pub fn set_zone(&mut self, mut lvl: u8, dc_lvl: u8, mut zone: Option<String>) {
if dc_lvl == lvl {
zone = Some(self.name.to_string());
}

for instance in self.instances.iter_mut() {
if let FailureDomains::Finished(failure_domain) = &instance.failure_domains {
instance.config.zone = Some(failure_domain.clone());
instance.config.zone = zone.clone().or(Some(failure_domain.clone()));
}
}

lvl = lvl + 1;
for sub_host in self.hosts.iter_mut() {
sub_host.use_failure_domain_as_zone()
sub_host.set_zone(lvl, dc_lvl, zone.clone())
}
}

Expand Down

0 comments on commit f51da44

Please sign in to comment.