84beb53b79
When deploying with podman, we need to create directories if they don't
exist before trying to mount them later when containers are starting.
Otherwise, podman fails with this kind of error:
error checking path \"/etc/iscsi\": stat /etc/iscsi: no such file or directory"
Related-Bug: #1811713
Change-Id: I7dbdc7f3646dda99c8014b4c8ca2edd48778b392
(cherry picked from commit 24f5a255c9
)
579 lines
23 KiB
YAML
579 lines
23 KiB
YAML
heat_template_version: queens
|
|
|
|
description: >
|
|
OpenStack containerized Swift Storage services.
|
|
|
|
parameters:
|
|
DockerSwiftProxyImage:
|
|
description: image
|
|
type: string
|
|
DockerSwiftAccountImage:
|
|
description: image
|
|
type: string
|
|
DockerSwiftContainerImage:
|
|
description: image
|
|
type: string
|
|
DockerSwiftObjectImage:
|
|
description: image
|
|
type: string
|
|
DockerSwiftConfigImage:
|
|
description: The container image to use for the swift config_volume
|
|
type: string
|
|
EndpointMap:
|
|
default: {}
|
|
description: Mapping of service endpoint -> protocol. Typically set
|
|
via parameter_defaults in the resource registry.
|
|
type: json
|
|
DefaultPasswords:
|
|
default: {}
|
|
type: json
|
|
RoleName:
|
|
default: ''
|
|
description: Role name on which the service is applied
|
|
type: string
|
|
RoleParameters:
|
|
default: {}
|
|
description: Parameters specific to the role
|
|
type: json
|
|
ServiceData:
|
|
default: {}
|
|
description: Dictionary packing service data
|
|
type: json
|
|
ServiceNetMap:
|
|
default: {}
|
|
description: Mapping of service_name -> network name. Typically set
|
|
via parameter_defaults in the resource registry. This
|
|
mapping overrides those in ServiceNetMapDefaults.
|
|
type: json
|
|
SwiftRawDisks:
|
|
default: {}
|
|
description: 'A hash of additional raw devices to use as Swift backend (eg. {sdb: {}})'
|
|
type: json
|
|
SwiftUseLocalDir:
|
|
default: true
|
|
description: 'Use a local directory for Swift storage services when building rings'
|
|
type: boolean
|
|
UpgradeRemoveUnusedPackages:
|
|
default: false
|
|
description: Remove package if the service is being disabled during upgrade
|
|
type: boolean
|
|
|
|
resources:
|
|
|
|
ContainersCommon:
|
|
type: ./containers-common.yaml
|
|
|
|
SwiftStorageBase:
|
|
type: ../../puppet/services/swift-storage.yaml
|
|
properties:
|
|
EndpointMap: {get_param: EndpointMap}
|
|
ServiceData: {get_param: ServiceData}
|
|
ServiceNetMap: {get_param: ServiceNetMap}
|
|
DefaultPasswords: {get_param: DefaultPasswords}
|
|
RoleName: {get_param: RoleName}
|
|
RoleParameters: {get_param: RoleParameters}
|
|
|
|
outputs:
|
|
role_data:
|
|
description: Role data for the swift storage services.
|
|
value:
|
|
service_name: {get_attr: [SwiftStorageBase, role_data, service_name]}
|
|
config_settings:
|
|
map_merge:
|
|
- {get_attr: [SwiftStorageBase, role_data, config_settings]}
|
|
# FIXME (cschwede): re-enable this once checks works inside containers
|
|
- swift::storage::all::mount_check: false
|
|
logging_source: {get_attr: [SwiftStorageBase, role_data, logging_source]}
|
|
logging_groups: {get_attr: [SwiftStorageBase, role_data, logging_groups]}
|
|
service_config_settings: {get_attr: [SwiftStorageBase, role_data, service_config_settings]}
|
|
# BEGIN DOCKER SETTINGS
|
|
puppet_config:
|
|
config_volume: swift
|
|
puppet_tags: swift_config,swift_container_config,swift_container_sync_realms_config,swift_account_config,swift_object_config,swift_object_expirer_config,rsync::server
|
|
step_config:
|
|
list_join:
|
|
- "\n"
|
|
- - {get_attr: [SwiftStorageBase, role_data, step_config]}
|
|
- "class xinetd() {}"
|
|
config_image: {get_param: DockerSwiftConfigImage}
|
|
kolla_config:
|
|
/var/lib/kolla/config_files/swift_account_auditor.json:
|
|
command: /usr/bin/swift-account-auditor /etc/swift/account-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_account_reaper.json:
|
|
command: /usr/bin/swift-account-reaper /etc/swift/account-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_account_replicator.json:
|
|
command: /usr/bin/swift-account-replicator /etc/swift/account-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_account_server.json:
|
|
command: /usr/bin/swift-account-server /etc/swift/account-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_container_auditor.json:
|
|
command: /usr/bin/swift-container-auditor /etc/swift/container-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_container_replicator.json:
|
|
command: /usr/bin/swift-container-replicator /etc/swift/container-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_container_updater.json:
|
|
command: /usr/bin/swift-container-updater /etc/swift/container-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_container_server.json:
|
|
command: /usr/bin/swift-container-server /etc/swift/container-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_object_auditor.json:
|
|
command: /usr/bin/swift-object-auditor /etc/swift/object-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_object_expirer.json:
|
|
command: /usr/bin/swift-object-expirer /etc/swift/object-expirer.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_object_replicator.json:
|
|
command: /usr/bin/swift-object-replicator /etc/swift/object-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_object_updater.json:
|
|
command: /usr/bin/swift-object-updater /etc/swift/object-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
/var/lib/kolla/config_files/swift_object_server.json:
|
|
command: /usr/bin/swift-object-server /etc/swift/object-server.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
permissions:
|
|
- path: /var/cache/swift
|
|
owner: swift:swift
|
|
recurse: true
|
|
/var/lib/kolla/config_files/swift_rsync.json:
|
|
command: /usr/bin/rsync --daemon --no-detach --config=/etc/rsyncd.conf
|
|
config_files:
|
|
- source: "/var/lib/kolla/config_files/src/*"
|
|
dest: "/"
|
|
merge: true
|
|
preserve_properties: true
|
|
docker_config:
|
|
step_3:
|
|
# The puppet config sets this up but we don't have a way to mount the named
|
|
# volume during the configuration stage. We just need to create this
|
|
# directory and make sure it's owned by swift.
|
|
swift_setup_srv:
|
|
image: &swift_account_image {get_param: DockerSwiftAccountImage}
|
|
user: root
|
|
command: ['chown', '-R', 'swift:', '/srv/node']
|
|
volumes:
|
|
- /srv/node:/srv/node
|
|
# FIXME (cschwede): remove this once the pid file setting is disabled
|
|
swift_rsync_fix:
|
|
image: {get_param: DockerSwiftObjectImage}
|
|
net: host
|
|
user: root
|
|
detach: false
|
|
command: ['/bin/bash', '-c', 'sed -i "/pid file/d" /var/lib/kolla/config_files/src/etc/rsyncd.conf']
|
|
volumes:
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:rw
|
|
step_4:
|
|
swift_account_auditor:
|
|
image: *swift_account_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_account_auditor.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: &kolla_env
|
|
- KOLLA_CONFIG_STRATEGY=COPY_ALWAYS
|
|
swift_account_reaper:
|
|
image: *swift_account_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_account_reaper.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_account_replicator:
|
|
image: *swift_account_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_account_replicator.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_account_server:
|
|
image: *swift_account_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
healthcheck:
|
|
test: /openstack/healthcheck
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_account_server.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_container_auditor:
|
|
image: &swift_container_image {get_param: DockerSwiftContainerImage}
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_container_auditor.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_container_replicator:
|
|
image: *swift_container_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_container_replicator.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_container_updater:
|
|
image: *swift_container_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_container_updater.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_container_server:
|
|
image: *swift_container_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
healthcheck:
|
|
test: /openstack/healthcheck
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_container_server.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_object_auditor:
|
|
image: &swift_object_image {get_param: DockerSwiftObjectImage}
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_object_auditor.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_object_expirer:
|
|
image: &swift_proxy_image {get_param: DockerSwiftProxyImage}
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_object_expirer.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_object_replicator:
|
|
image: *swift_object_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_object_replicator.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_object_updater:
|
|
image: *swift_object_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_object_updater.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_object_server:
|
|
image: *swift_object_image
|
|
net: host
|
|
user: swift
|
|
restart: always
|
|
healthcheck:
|
|
test: /openstack/healthcheck
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_object_server.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
- /var/cache/swift:/var/cache/swift
|
|
environment: *kolla_env
|
|
swift_rsync:
|
|
image: *swift_object_image
|
|
net: host
|
|
user: root
|
|
restart: always
|
|
privileged: true
|
|
volumes:
|
|
list_concat:
|
|
- {get_attr: [ContainersCommon, volumes]}
|
|
-
|
|
- /var/lib/kolla/config_files/swift_rsync.json:/var/lib/kolla/config_files/config.json:ro
|
|
- /var/lib/config-data/puppet-generated/swift/:/var/lib/kolla/config_files/src:ro
|
|
- /srv/node:/srv/node
|
|
- /dev:/dev
|
|
# /var/cache/swift not needed in this container
|
|
environment: *kolla_env
|
|
|
|
host_prep_tasks:
|
|
- name: create persistent directories
|
|
file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
with_items:
|
|
- /srv/node
|
|
- /var/cache/swift
|
|
- /var/log/swift
|
|
- /var/log/containers
|
|
- name: Set swift_use_local_disks fact
|
|
set_fact:
|
|
swift_use_local_disks: {get_param: SwiftUseLocalDir}
|
|
- name: Create Swift d1 directory if needed
|
|
file:
|
|
path: "/srv/node/d1"
|
|
state: directory
|
|
when: swift_use_local_disks
|
|
- name: Create swift logging symlink
|
|
file:
|
|
src: /var/log/swift
|
|
dest: /var/log/containers/swift
|
|
state: link
|
|
- name: swift logs readme
|
|
copy:
|
|
dest: /var/log/swift/readme.txt
|
|
content: |
|
|
Log files from swift containers can be found under
|
|
/var/log/containers/swift and /var/log/containers/httpd/swift-*.
|
|
ignore_errors: true
|
|
- name: Set fact for SwiftRawDisks
|
|
set_fact:
|
|
swift_raw_disks: {get_param: SwiftRawDisks}
|
|
- name: Format SwiftRawDisks
|
|
filesystem:
|
|
fstype: xfs
|
|
dev: "{{ swift_raw_disks[item]['base_dir']|default('/dev') }}/{{ item }}"
|
|
opts: -f -i size=1024
|
|
with_items: "{{ swift_raw_disks }}"
|
|
when: swift_raw_disks
|
|
- name: Mount devices defined in SwiftRawDisks
|
|
mount:
|
|
name: /srv/node/{{ item }}
|
|
src: "{{ swift_raw_disks[item]['base_dir']|default('/dev') }}/{{ item }}"
|
|
fstype: xfs
|
|
opts: noatime
|
|
state: mounted
|
|
with_items: "{{ swift_raw_disks }}"
|
|
when: swift_raw_disks
|
|
upgrade_tasks:
|
|
- when: step|int == 0
|
|
tags: common
|
|
block:
|
|
- name: Check if swift storage services are deployed
|
|
command: systemctl is-enabled --quiet "{{ item }}"
|
|
register: swift_services_enabled_result
|
|
ignore_errors: true
|
|
with_items:
|
|
- openstack-swift-account-auditor
|
|
- openstack-swift-account-reaper
|
|
- openstack-swift-account-replicator
|
|
- openstack-swift-account
|
|
- openstack-swift-container-auditor
|
|
- openstack-swift-container-replicator
|
|
- openstack-swift-container-updater
|
|
- openstack-swift-container
|
|
- openstack-swift-object-auditor
|
|
- openstack-swift-object-replicator
|
|
- openstack-swift-object-updater
|
|
- openstack-swift-object
|
|
- name: Set fact swift_services_enabled
|
|
set_fact:
|
|
swift_services_enabled: "{{ swift_services_enabled_result }}"
|
|
- when: step|int == 2
|
|
block:
|
|
- name: Stop and disable swift storage services
|
|
service: name={{ item.item }} state=stopped enabled=no
|
|
with_items: "{{ swift_services_enabled.results }}"
|
|
when: item.rc == 0
|
|
- when: step|int == 3
|
|
block:
|
|
- name: Set fact for removal of openstack-swift-container,object,account package
|
|
set_fact:
|
|
remove_swift_package: {get_param: UpgradeRemoveUnusedPackages}
|
|
- name: Remove openstack-swift-container,object,account packages if operator requests it
|
|
yum: name={{ item }} state=removed
|
|
ignore_errors: True
|
|
when: remove_swift_package|bool
|
|
with_items:
|
|
- openstack-swift-container
|
|
- openstack-swift-object
|
|
- openstack-swift-account
|
|
- name: Remove rsync service from xinetd
|
|
file: state=absent path=/etc/xinetd.d/rsync
|
|
register: rsync_service_removed
|
|
- name: Restart xinetd service after rsync removal
|
|
service: name=xinetd state=restarted
|
|
when: rsync_service_removed|changed
|
|
update_tasks:
|
|
- name: Ensure rsyncd pid file is absent
|
|
file:
|
|
path: /var/run/rsyncd.pid
|
|
state: absent
|
|
fast_forward_upgrade_tasks:
|
|
- name: Check if swift storage services are deployed
|
|
command: systemctl is-enabled --quiet "{{ item }}"
|
|
with_items:
|
|
- openstack-swift-account-auditor
|
|
- openstack-swift-account-reaper
|
|
- openstack-swift-account-replicator
|
|
- openstack-swift-account
|
|
- openstack-swift-container-auditor
|
|
- openstack-swift-container-replicator
|
|
- openstack-swift-container-updater
|
|
- openstack-swift-container
|
|
- openstack-swift-object-auditor
|
|
- openstack-swift-object-replicator
|
|
- openstack-swift-object-updater
|
|
- openstack-swift-object
|
|
ignore_errors: True
|
|
register: swift_services_enabled_result
|
|
when:
|
|
- step|int == 0
|
|
- release == 'ocata'
|
|
- name: Set fact swift_services_enabled
|
|
set_fact:
|
|
swift_services_enabled: "{{ swift_services_enabled_result }}"
|
|
when:
|
|
- step|int == 0
|
|
- release == 'ocata'
|
|
- name: Stop swift storage services
|
|
service: name={{ item.item }} state=stopped enabled=no
|
|
with_items: "{{ swift_services_enabled.results }}"
|
|
when:
|
|
- step|int == 1
|
|
- release == 'ocata'
|
|
- item.rc == 0
|