uffizzi_core 2.0.3 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller.rb +2 -2
- data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments_controller.rb +3 -3
- data/app/errors/uffizzi_core/deployment/labels_not_found_error.rb +4 -0
- data/app/forms/uffizzi_core/api/cli/v1/compose_file/check_credentials_form.rb +2 -1
- data/app/forms/uffizzi_core/api/cli/v1/compose_file/cli_form.rb +4 -2
- data/app/forms/uffizzi_core/api/cli/v1/deployment/create_form.rb +4 -0
- data/app/forms/uffizzi_core/api/cli/v1/deployment/update_form.rb +4 -0
- data/app/forms/uffizzi_core/api/cli/v1/template/create_form.rb +4 -0
- data/app/lib/uffizzi_core/concerns/models/compose_file.rb +11 -0
- data/app/lib/uffizzi_core/concerns/models/container.rb +3 -0
- data/app/lib/uffizzi_core/concerns/models/container_host_volume_file.rb +12 -0
- data/app/lib/uffizzi_core/concerns/models/deployment.rb +14 -0
- data/app/lib/uffizzi_core/concerns/models/host_volume_file.rb +22 -0
- data/app/lib/uffizzi_core/concerns/models/project.rb +1 -0
- data/app/models/uffizzi_core/container_host_volume_file.rb +5 -0
- data/app/models/uffizzi_core/host_volume_file.rb +5 -0
- data/app/repositories/uffizzi_core/host_volume_file_repo.rb +17 -0
- data/app/serializers/uffizzi_core/controller/deploy_containers/compose_file_serializer.rb +5 -0
- data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_host_volume_file_serializer.rb +5 -0
- data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer.rb +1 -0
- data/app/serializers/uffizzi_core/controller/deploy_containers/host_volume_file_serializer.rb +9 -0
- data/app/services/uffizzi_core/compose_file/builders/container_builder_service.rb +16 -5
- data/app/services/uffizzi_core/compose_file/builders/container_config_files_builder_service.rb +27 -0
- data/app/services/uffizzi_core/compose_file/builders/container_host_volume_files_builder_service.rb +30 -0
- data/app/services/uffizzi_core/compose_file/builders/template_builder_service.rb +3 -7
- data/app/services/uffizzi_core/compose_file/dependencies_service.rb +36 -3
- data/app/services/uffizzi_core/compose_file/github_dependencies_service.rb +9 -0
- data/app/services/uffizzi_core/compose_file/host_volume_files_service.rb +40 -0
- data/app/services/uffizzi_core/compose_file/parsers/{volumes_parser_service.rb → named_volumes_parser_service.rb} +1 -1
- data/app/services/uffizzi_core/compose_file/parsers/services/volumes_parser_service.rb +14 -13
- data/app/services/uffizzi_core/compose_file/parsers/services_parser_service.rb +3 -3
- data/app/services/uffizzi_core/compose_file/template_service.rb +1 -1
- data/app/services/uffizzi_core/compose_file_service.rb +6 -3
- data/app/services/uffizzi_core/controller_service.rb +11 -0
- data/app/services/uffizzi_core/deployment_service.rb +27 -10
- data/config/locales/en.yml +2 -1
- data/db/migrate/20220901110752_create_host_volume_files.rb +23 -0
- data/db/migrate/20220901165313_create_container_host_volume_files.rb +18 -0
- data/lib/uffizzi_core/version.rb +1 -1
- data/lib/uffizzi_core.rb +2 -0
- metadata +31 -4
- data/app/services/uffizzi_core/compose_file/builders/config_files_builder_service.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1065eeedad42eb66cc223f635c61871171ab68a30bcbf529601630f4cdd75ee
|
4
|
+
data.tar.gz: 4d3a5120d1839a4bf944af27dfcbf501b5b616c909b57af247b9e528c3d4ae62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e0d2877db2d9c6931db243b3f98e47f71235acc288d47c05dd1e5a6841366f82c9ca07ce2958d3b5052869d7ca495089ac3d1da81d636dff2586dd1a21ab842
|
7
|
+
data.tar.gz: eabdf9cd8a38a86640d3f25ca0ffc735adae9191b4508c50455d9a24e7d5441c762274033737dae4066060525e7f9953af656a0465cc7418d3d5a3ec324c6f52
|
@@ -24,7 +24,7 @@ class UffizziCore::Api::Cli::V1::Projects::ComposeFilesController < UffizziCore:
|
|
24
24
|
# @parameter project_slug(required,path) [string] The project slug
|
25
25
|
# @parameter params(required,body) [object <
|
26
26
|
# compose_file: object<path: string, source: string, content: string>,
|
27
|
-
# dependencies: Array<object<path: string, source: string, content: string>>>]
|
27
|
+
# dependencies: Array<object<path: string, source: string, content: string, use_kind: string, is_file: boolean>>>]
|
28
28
|
#
|
29
29
|
# @response [ComposeFile] 201 OK
|
30
30
|
# @response 422 A compose file already exists for this project
|
@@ -72,7 +72,7 @@ class UffizziCore::Api::Cli::V1::Projects::ComposeFilesController < UffizziCore:
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def dependencies_params
|
75
|
-
params.permit(dependencies: [:
|
75
|
+
params.permit(dependencies: [:path, :source, :content, :use_kind, :is_file])
|
76
76
|
end
|
77
77
|
|
78
78
|
def create_or_update_compose_file(params)
|
@@ -40,7 +40,7 @@ class UffizziCore::Api::Cli::V1::Projects::DeploymentsController < UffizziCore::
|
|
40
40
|
# @parameter project_slug(required,path) [string] The project slug
|
41
41
|
# @parameter params(required,body) [object<
|
42
42
|
# compose_file: object<path: string, source: string, content: string>,
|
43
|
-
# dependencies: Array<object<path: string, source: string, content: string>>>]
|
43
|
+
# dependencies: Array<object<path: string, source: string, content: string, use_kind: string, is_file: boolean>>>]
|
44
44
|
#
|
45
45
|
# @response [Deployment] 201 OK
|
46
46
|
# @response [object<errors: object<state: string>>] 422 Unprocessable Entity
|
@@ -66,7 +66,7 @@ class UffizziCore::Api::Cli::V1::Projects::DeploymentsController < UffizziCore::
|
|
66
66
|
# @parameter project_slug(required,path) [string] The project slug
|
67
67
|
# @parameter params(required,body) [object<
|
68
68
|
# compose_file: object<path: string, source: string, content: string>,
|
69
|
-
# dependencies: Array<object<path: string, source: string, content: string>>>]
|
69
|
+
# dependencies: Array<object<path: string, source: string, content: string, use_kind: string, is_file: boolean>>>]
|
70
70
|
#
|
71
71
|
# @response [Deployment] 201 OK
|
72
72
|
# @response [object<errors: object<state: string>>] 422 Unprocessable Entity
|
@@ -172,7 +172,7 @@ class UffizziCore::Api::Cli::V1::Projects::DeploymentsController < UffizziCore::
|
|
172
172
|
end
|
173
173
|
|
174
174
|
def dependencies_params
|
175
|
-
params.permit(dependencies: [:
|
175
|
+
params.permit(dependencies: [:path, :source, :content, :use_kind, :is_file])
|
176
176
|
end
|
177
177
|
|
178
178
|
def metadata_params
|
@@ -12,7 +12,8 @@ class UffizziCore::Api::Cli::V1::ComposeFile::CheckCredentialsForm
|
|
12
12
|
|
13
13
|
def check_containers_credentials
|
14
14
|
compose_content = Base64.decode64(compose_file.content)
|
15
|
-
|
15
|
+
compose_payload = { compose_file: compose_file }
|
16
|
+
compose_data = UffizziCore::ComposeFileService.parse(compose_content, compose_payload)
|
16
17
|
|
17
18
|
UffizziCore::ComposeFileService.containers_credentials(compose_data, credentials)
|
18
19
|
rescue UffizziCore::ComposeFile::CredentialError => e
|
@@ -9,14 +9,16 @@ class UffizziCore::Api::Cli::V1::ComposeFile::CliForm
|
|
9
9
|
attribute :compose_repositories, Array
|
10
10
|
attribute :content, String
|
11
11
|
attribute :source_kind, Symbol
|
12
|
+
attribute :compose_file, UffizziCore::ComposeFile
|
12
13
|
|
13
14
|
validates :content, presence: true
|
14
|
-
|
15
|
+
validates :compose_file, presence: true
|
15
16
|
validate :check_compose_parsed_data, if: -> { errors[:content].empty? }
|
16
17
|
|
17
18
|
def check_compose_parsed_data
|
18
19
|
compose_content = Base64.decode64(content)
|
19
|
-
|
20
|
+
compose_payload = { compose_file: compose_file }
|
21
|
+
self.compose_data = UffizziCore::ComposeFileService.parse(compose_content, compose_payload)
|
20
22
|
rescue UffizziCore::ComposeFile::ParseError => e
|
21
23
|
errors.add(:content, e.message)
|
22
24
|
end
|
@@ -45,6 +45,10 @@ class UffizziCore::Api::Cli::V1::Deployment::CreateForm < UffizziCore::Deploymen
|
|
45
45
|
container_config_files_attributes: [
|
46
46
|
:config_file_id,
|
47
47
|
:mount_path,
|
48
|
+
],
|
49
|
+
container_host_volume_files_attributes: [
|
50
|
+
:host_volume_file_id,
|
51
|
+
:source_path,
|
48
52
|
] },
|
49
53
|
]
|
50
54
|
|
@@ -44,6 +44,10 @@ class UffizziCore::Api::Cli::V1::Deployment::UpdateForm < UffizziCore::Deploymen
|
|
44
44
|
container_config_files_attributes: [
|
45
45
|
:config_file_id,
|
46
46
|
:mount_path,
|
47
|
+
],
|
48
|
+
container_host_volume_files_attributes: [
|
49
|
+
:host_volume_file_id,
|
50
|
+
:source_path,
|
47
51
|
] },
|
48
52
|
]
|
49
53
|
|
@@ -46,6 +46,10 @@ class UffizziCore::Api::Cli::V1::Template::CreateForm < UffizziCore::Template
|
|
46
46
|
container_config_files_attributes: [
|
47
47
|
:config_file_id,
|
48
48
|
:mount_path,
|
49
|
+
],
|
50
|
+
container_host_volume_files_attributes: [
|
51
|
+
:host_volume_file_id,
|
52
|
+
:source_path,
|
49
53
|
] },
|
50
54
|
],
|
51
55
|
}
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module UffizziCore::Concerns::Models::ComposeFile
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
+
LOCAL_SOURCE = :local
|
7
|
+
|
6
8
|
included do
|
7
9
|
include UffizziCore::ComposeFileRepo
|
8
10
|
include AASM
|
@@ -15,6 +17,7 @@ module UffizziCore::Concerns::Models::ComposeFile
|
|
15
17
|
|
16
18
|
has_one :template, dependent: :destroy
|
17
19
|
has_many :config_files, dependent: :destroy
|
20
|
+
has_many :host_volume_files, dependent: :destroy
|
18
21
|
has_many :deployments, dependent: :nullify
|
19
22
|
|
20
23
|
enumerize :kind, in: [:main, :temporary], predicates: true, scope: :shallow, default: :main
|
@@ -48,6 +51,14 @@ module UffizziCore::Concerns::Models::ComposeFile
|
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
54
|
+
def local_source?
|
55
|
+
repository_id.nil? && branch.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
def source_kind
|
59
|
+
return LOCAL_SOURCE if local_source?
|
60
|
+
end
|
61
|
+
|
51
62
|
private
|
52
63
|
|
53
64
|
def main_compose_file_uniqueness
|
@@ -20,6 +20,8 @@ module UffizziCore::Concerns::Models::Container
|
|
20
20
|
has_many :activity_items, dependent: :destroy
|
21
21
|
has_many :container_config_files, dependent: :destroy
|
22
22
|
has_many :config_files, through: :container_config_files
|
23
|
+
has_many :container_host_volume_files, dependent: :destroy
|
24
|
+
has_many :host_volume_files, through: :container_host_volume_files
|
23
25
|
|
24
26
|
attribute :public, :boolean, default: false
|
25
27
|
attribute :port, :integer, default: nil
|
@@ -38,6 +40,7 @@ module UffizziCore::Concerns::Models::Container
|
|
38
40
|
|
39
41
|
accepts_nested_attributes_for :repo
|
40
42
|
accepts_nested_attributes_for :container_config_files, allow_destroy: true
|
43
|
+
accepts_nested_attributes_for :container_host_volume_files, allow_destroy: true
|
41
44
|
|
42
45
|
validates :variables, 'uffizzi_core/environment_variable_list': true, allow_nil: true
|
43
46
|
validates :secret_variables, 'uffizzi_core/environment_variable_list': true, allow_nil: true
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UffizziCore::Concerns::Models::ContainerHostVolumeFile
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
self.table_name = UffizziCore.table_names[:container_host_volume_files]
|
8
|
+
|
9
|
+
belongs_to :container
|
10
|
+
belongs_to :host_volume_file
|
11
|
+
end
|
12
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module UffizziCore::Concerns::Models::Deployment
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
+
# rubocop:disable Metrics/BlockLength
|
6
7
|
included do
|
7
8
|
include AASM
|
8
9
|
include UffizziCore::StateMachineConcern
|
@@ -72,5 +73,18 @@ module UffizziCore::Concerns::Models::Deployment
|
|
72
73
|
def preview_url
|
73
74
|
"#{subdomain}.#{Settings.app.managed_dns_zone}"
|
74
75
|
end
|
76
|
+
|
77
|
+
def from_actions?
|
78
|
+
from_github_actions? || from_gitlab_actions?
|
79
|
+
end
|
80
|
+
|
81
|
+
def from_github_actions?
|
82
|
+
metadata.dig('labels', 'github', 'repository').present?
|
83
|
+
end
|
84
|
+
|
85
|
+
def from_gitlab_actions?
|
86
|
+
metadata.dig('labels', 'gitlab', 'repo').present?
|
87
|
+
end
|
75
88
|
end
|
89
|
+
# rubocop:enable Metrics/BlockLength
|
76
90
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UffizziCore::Concerns::Models::HostVolumeFile
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
include UffizziCore::HostVolumeFileRepo
|
8
|
+
|
9
|
+
self.table_name = UffizziCore.table_names[:host_volume_files]
|
10
|
+
|
11
|
+
belongs_to :project
|
12
|
+
belongs_to :added_by, class_name: UffizziCore::User.name, foreign_key: :added_by_id, optional: true
|
13
|
+
belongs_to :compose_file, optional: true
|
14
|
+
|
15
|
+
has_many :container_host_volume_files, dependent: :destroy
|
16
|
+
|
17
|
+
validates :source, presence: true
|
18
|
+
validates :path, presence: true
|
19
|
+
validates :payload, presence: true
|
20
|
+
validates :is_file, inclusion: [true, false]
|
21
|
+
end
|
22
|
+
end
|
@@ -21,6 +21,7 @@ module UffizziCore::Concerns::Models::Project
|
|
21
21
|
has_many :credentials, through: :account
|
22
22
|
has_many :compose_files, dependent: :destroy
|
23
23
|
has_many :secrets, dependent: :destroy, as: :resource
|
24
|
+
has_many :host_volume_files, dependent: :destroy
|
24
25
|
|
25
26
|
validates :name, presence: true, uniqueness: { scope: :account, message: 'Name already exists' }
|
26
27
|
validates :slug, presence: true, uniqueness: { message: 'Project slug already taken' }
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UffizziCore::HostVolumeFileRepo
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
scope :by_deployment, ->(deployment) {
|
8
|
+
joins(:container_host_volume_files)
|
9
|
+
.where(container_host_volume_files: { container: deployment.containers })
|
10
|
+
.distinct
|
11
|
+
}
|
12
|
+
|
13
|
+
scope :by_source, ->(source) {
|
14
|
+
where(source: source)
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
@@ -25,9 +25,12 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
|
|
25
25
|
container_name)
|
26
26
|
configs_dependencies = UffizziCore::ComposeFile::GithubDependenciesService.configs_dependencies_for_container(compose_dependencies,
|
27
27
|
container_name)
|
28
|
+
host_volumes_dependencies = UffizziCore::ComposeFile::GithubDependenciesService.host_volumes_dependencies_for_container(
|
29
|
+
compose_dependencies, container_name
|
30
|
+
)
|
28
31
|
is_ingress = ingress_container?(container_name, ingress_data)
|
29
32
|
repo_attributes = repo_attributes(container_data, continuous_preview_global_data)
|
30
|
-
additional_subdomains = is_ingress ? ingress_data
|
33
|
+
additional_subdomains = is_ingress ? ingress_data.fetch(:additional_subdomains, []) : []
|
31
34
|
|
32
35
|
{
|
33
36
|
tag: tag(image_data, repo_attributes),
|
@@ -43,12 +46,13 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
|
|
43
46
|
repo_attributes: repo_attributes,
|
44
47
|
continuously_deploy: continuously_deploy(deploy_data),
|
45
48
|
receive_incoming_requests: is_ingress,
|
46
|
-
container_config_files_attributes:
|
49
|
+
container_config_files_attributes: container_config_files_attributes(configs_data, configs_dependencies),
|
47
50
|
service_name: container_name,
|
48
51
|
name: container_name,
|
49
52
|
healthcheck: healthcheck_data,
|
50
53
|
volumes: volumes_data,
|
51
54
|
additional_subdomains: additional_subdomains,
|
55
|
+
container_host_volume_files_attributes: container_host_volume_files_attributes(volumes_data, host_volumes_dependencies),
|
52
56
|
}
|
53
57
|
end
|
54
58
|
# rubocop:enable Metrics/PerceivedComplexity
|
@@ -226,10 +230,17 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
|
|
226
230
|
variables_builder.build_secret_attributes(secrets)
|
227
231
|
end
|
228
232
|
|
229
|
-
def
|
230
|
-
|
233
|
+
def container_config_files_attributes(config_files_data, dependencies)
|
234
|
+
UffizziCore::ComposeFile::Builders::ContainerConfigFilesBuilderService.build_attributes(config_files_data, dependencies, project)
|
235
|
+
end
|
236
|
+
|
237
|
+
def container_host_volume_files_attributes(volumes_data, host_volumes_dependencies)
|
238
|
+
host_volumes_data = volumes_data.select do |v|
|
239
|
+
v[:type] == UffizziCore::ComposeFile::Parsers::Services::VolumesParserService::HOST_VOLUME_TYPE
|
240
|
+
end
|
231
241
|
|
232
|
-
|
242
|
+
UffizziCore::ComposeFile::Builders::ContainerHostVolumeFilesBuilderService
|
243
|
+
.build_attributes(host_volumes_data, host_volumes_dependencies, project)
|
233
244
|
end
|
234
245
|
|
235
246
|
def docker_builder(type)
|
data/app/services/uffizzi_core/compose_file/builders/container_config_files_builder_service.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class UffizziCore::ComposeFile::Builders::ContainerConfigFilesBuilderService
|
4
|
+
class << self
|
5
|
+
def build_attributes(config_files_data, dependencies, project)
|
6
|
+
return [] if config_files_data.empty?
|
7
|
+
|
8
|
+
config_file_sources = dependencies.pluck(:source)
|
9
|
+
config_files = project.config_files.with_creation_source(UffizziCore::ConfigFile.creation_source.compose_file)
|
10
|
+
.by_source(config_file_sources)
|
11
|
+
|
12
|
+
config_files_data.map do |config_file_data|
|
13
|
+
detected_dependency = dependencies.detect { |dependency| dependency[:path] == config_file_data[:source] }
|
14
|
+
detected_config_file = config_files.detect { |config_file| config_file.source == detected_dependency[:source] }
|
15
|
+
|
16
|
+
if detected_config_file.nil?
|
17
|
+
raise UffizziCore::ComposeFile::BuildError, I18n.t('compose.config_file_not_found', name: config_file_data[:source])
|
18
|
+
end
|
19
|
+
|
20
|
+
{
|
21
|
+
mount_path: config_file_data[:target],
|
22
|
+
config_file_id: detected_config_file.id,
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/app/services/uffizzi_core/compose_file/builders/container_host_volume_files_builder_service.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class UffizziCore::ComposeFile::Builders::ContainerHostVolumeFilesBuilderService
|
4
|
+
class << self
|
5
|
+
def build_attributes(container_host_volumes_data, host_volumes_dependencies, project)
|
6
|
+
return [] if container_host_volumes_data.empty?
|
7
|
+
|
8
|
+
host_volume_files = project
|
9
|
+
.host_volume_files
|
10
|
+
.by_source(host_volumes_dependencies.pluck(:source))
|
11
|
+
|
12
|
+
container_host_volumes_data.map do |container_host_volume_data|
|
13
|
+
detected_dependency = host_volumes_dependencies.detect do |dependency|
|
14
|
+
dependency[:raw_source] == container_host_volume_data[:source]
|
15
|
+
end
|
16
|
+
detected_host_volume_file = host_volume_files.detect { |host_volume_file| host_volume_file.source == detected_dependency[:source] }
|
17
|
+
|
18
|
+
if detected_host_volume_file.nil?
|
19
|
+
raise UffizziCore::ComposeFile::BuildError,
|
20
|
+
I18n.t('compose.host_volume_file_not_found', name: container_host_volume_data[:source])
|
21
|
+
end
|
22
|
+
|
23
|
+
{
|
24
|
+
source_path: container_host_volume_data[:source],
|
25
|
+
host_volume_file_id: detected_host_volume_file.id,
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -33,13 +33,9 @@ class UffizziCore::ComposeFile::Builders::TemplateBuilderService
|
|
33
33
|
|
34
34
|
def build_containers_attributes(containers_data, ingress_data, continuous_preview_global_data, compose_dependencies)
|
35
35
|
containers_data.map do |container_data|
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
36
|
+
builder = UffizziCore::ComposeFile::Builders::ContainerBuilderService.new(credentials, project, repositories)
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
builder.build_attributes(containers_data, ingress_data, continuous_preview_global_data, compose_dependencies)
|
38
|
+
builder.build_attributes(container_data, ingress_data, continuous_preview_global_data, compose_dependencies)
|
39
|
+
end
|
44
40
|
end
|
45
41
|
end
|
@@ -3,14 +3,21 @@
|
|
3
3
|
class UffizziCore::ComposeFile::DependenciesService
|
4
4
|
ENV_FILE_TYPE = 'env_file'
|
5
5
|
CONFIG_TYPE = 'config'
|
6
|
+
VOLUME_TYPE = 'volume'
|
7
|
+
DEPENDENCY_CONFIG_USE_KIND = 'config_map'
|
8
|
+
DEPENDENCY_VOLUME_USE_KIND = 'volume'
|
6
9
|
|
7
10
|
class << self
|
8
11
|
def build_dependencies(compose_data, compose_path, dependencies_params)
|
12
|
+
config_dependencies_params = dependencies_params.select { |d| d[:use_kind] == DEPENDENCY_CONFIG_USE_KIND }
|
13
|
+
volume_dependencies_params = dependencies_params.select { |d| d[:use_kind] == DEPENDENCY_VOLUME_USE_KIND }
|
14
|
+
|
9
15
|
dependencies = compose_data[:containers].map do |container|
|
10
|
-
env_file_dependencies = build_env_files_dependencies(container, compose_path,
|
11
|
-
configs_dependencies = build_configs_dependencies(container, compose_path,
|
16
|
+
env_file_dependencies = build_env_files_dependencies(container, compose_path, config_dependencies_params)
|
17
|
+
configs_dependencies = build_configs_dependencies(container, compose_path, config_dependencies_params)
|
18
|
+
volumes_dependencies = build_volumes_dependencies(container, compose_path, volume_dependencies_params)
|
12
19
|
|
13
|
-
env_file_dependencies + configs_dependencies
|
20
|
+
env_file_dependencies + configs_dependencies + volumes_dependencies
|
14
21
|
end
|
15
22
|
|
16
23
|
dependencies.compact.flatten
|
@@ -40,6 +47,28 @@ class UffizziCore::ComposeFile::DependenciesService
|
|
40
47
|
end
|
41
48
|
end
|
42
49
|
|
50
|
+
def build_volumes_dependencies(container, compose_path, raw_dependencies)
|
51
|
+
container_volumes = container[:volumes]
|
52
|
+
return [] unless container_volumes.present?
|
53
|
+
|
54
|
+
container_volumes
|
55
|
+
.select { |c| c[:type] == UffizziCore::ComposeFile::Parsers::Services::VolumesParserService::HOST_VOLUME_TYPE }
|
56
|
+
.map do |container_volume|
|
57
|
+
detected_raw_dependency = raw_dependencies.detect { |raw_dependency| raw_dependency[:source] == container_volume[:source] }
|
58
|
+
builded_source = build_source_path(compose_path, detected_raw_dependency[:source])
|
59
|
+
|
60
|
+
{
|
61
|
+
content: detected_raw_dependency[:content],
|
62
|
+
path: detected_raw_dependency[:path],
|
63
|
+
container_name: container[:container_name],
|
64
|
+
source: builded_source,
|
65
|
+
raw_source: detected_raw_dependency[:source],
|
66
|
+
type: VOLUME_TYPE,
|
67
|
+
is_file: detected_raw_dependency[:is_file],
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
43
72
|
def base_file_params(dependency, container)
|
44
73
|
{
|
45
74
|
content: dependency[:content],
|
@@ -52,5 +81,9 @@ class UffizziCore::ComposeFile::DependenciesService
|
|
52
81
|
prepared_compose_path = Pathname.new(compose_path).basename.to_s
|
53
82
|
"#{prepared_compose_path}/#{dependency_path}"
|
54
83
|
end
|
84
|
+
|
85
|
+
def host_volume_binary_content(dependency)
|
86
|
+
Base64.decode64(dependency[:content])
|
87
|
+
end
|
55
88
|
end
|
56
89
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
class UffizziCore::ComposeFile::GithubDependenciesService
|
4
4
|
ENV_FILE_TYPE = 'env_file'
|
5
5
|
CONFIG_TYPE = 'config'
|
6
|
+
VOLUME_TYPE = 'volume'
|
6
7
|
|
7
8
|
class << self
|
8
9
|
def filename(dependency)
|
@@ -23,10 +24,18 @@ class UffizziCore::ComposeFile::GithubDependenciesService
|
|
23
24
|
configs_dependencies(dependencies).select { |dependency| dependency[:container_name] == container_name }
|
24
25
|
end
|
25
26
|
|
27
|
+
def host_volumes_dependencies_for_container(dependencies, container_name)
|
28
|
+
dependencies.select { |dependency| dependency[:type] == VOLUME_TYPE && dependency[:container_name] == container_name }
|
29
|
+
end
|
30
|
+
|
26
31
|
def configs_dependencies(dependencies)
|
27
32
|
dependencies.select { |dependency| dependency[:type] == CONFIG_TYPE }
|
28
33
|
end
|
29
34
|
|
35
|
+
def select_dependencies_by_type(dependencies, type)
|
36
|
+
dependencies.select { |dependency| dependency[:type].to_s == type.to_s }
|
37
|
+
end
|
38
|
+
|
30
39
|
def build_source_path(compose_path, dependency_path, repository_id, branch)
|
31
40
|
prepared_compose_path = Pathname.new(compose_path).basename.to_s
|
32
41
|
base_source = "#{prepared_compose_path}/#{dependency_path}"
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class UffizziCore::ComposeFile::HostVolumeFilesService
|
4
|
+
class << self
|
5
|
+
def bulk_create(compose_file_form, compose_dependencies)
|
6
|
+
volumes_dependencies = UffizziCore::ComposeFile::GithubDependenciesService
|
7
|
+
.select_dependencies_by_type(compose_dependencies, UffizziCore::ComposeFile::DependenciesService::VOLUME_TYPE)
|
8
|
+
|
9
|
+
errors = []
|
10
|
+
volumes_dependencies.each do |volume_dependency|
|
11
|
+
new_errors = create(compose_file_form, volume_dependency)
|
12
|
+
errors << new_errors if new_errors
|
13
|
+
end
|
14
|
+
|
15
|
+
errors
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(compose_file_form, volume_dependency)
|
19
|
+
source = volume_dependency[:source]
|
20
|
+
host_volume_file = compose_file_form.project.host_volume_files.find_or_initialize_by(source: source)
|
21
|
+
attributes = {
|
22
|
+
payload: UffizziCore::ComposeFile::DependenciesService.host_volume_binary_content(volume_dependency),
|
23
|
+
source: source,
|
24
|
+
path: volume_dependency[:path],
|
25
|
+
is_file: volume_dependency[:is_file],
|
26
|
+
}
|
27
|
+
|
28
|
+
host_volume_file.assign_attributes(attributes)
|
29
|
+
host_volume_file.project = compose_file_form.project
|
30
|
+
host_volume_file.added_by = compose_file_form.added_by
|
31
|
+
host_volume_file.compose_file = compose_file_form
|
32
|
+
|
33
|
+
return host_volume_file.errors if host_volume_file.invalid?
|
34
|
+
|
35
|
+
host_volume_file.save
|
36
|
+
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -8,26 +8,30 @@ class UffizziCore::ComposeFile::Parsers::Services::VolumesParserService
|
|
8
8
|
READ_WRITE_OPTION = 'rw'
|
9
9
|
|
10
10
|
class << self
|
11
|
-
def parse(volumes,
|
11
|
+
def parse(volumes, additional_data)
|
12
12
|
return [] if volumes.blank?
|
13
13
|
|
14
|
+
if volumes.is_a?(String)
|
15
|
+
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.volumes_should_be_array', volumes: volumes)
|
16
|
+
end
|
17
|
+
|
14
18
|
volumes.map do |volume|
|
15
19
|
volume_data = case volume
|
16
20
|
when String
|
17
|
-
process_short_syntax(volume,
|
21
|
+
process_short_syntax(volume, additional_data)
|
18
22
|
when Hash
|
19
|
-
process_long_syntax(volume,
|
23
|
+
process_long_syntax(volume, additional_data)
|
20
24
|
else
|
21
25
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.invalid_type', option: :volumes)
|
22
26
|
end
|
23
27
|
|
24
28
|
volume_data
|
25
|
-
end
|
29
|
+
end.uniq
|
26
30
|
end
|
27
31
|
|
28
32
|
private
|
29
33
|
|
30
|
-
def process_short_syntax(volume_data,
|
34
|
+
def process_short_syntax(volume_data, additional_data)
|
31
35
|
volume_parts = volume_data.split(':').map(&:strip)
|
32
36
|
read_only = volume_parts.last.to_s.downcase == READONLY_OPTION
|
33
37
|
part1, part2 = volume_parts
|
@@ -36,10 +40,10 @@ class UffizziCore::ComposeFile::Parsers::Services::VolumesParserService
|
|
36
40
|
|
37
41
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.volume_prop_is_required', prop_name: 'source') if source_path.blank?
|
38
42
|
|
39
|
-
build_volume_attributes(source_path, target_path, read_only,
|
43
|
+
build_volume_attributes(source_path, target_path, read_only, additional_data)
|
40
44
|
end
|
41
45
|
|
42
|
-
def process_long_syntax(volume_data,
|
46
|
+
def process_long_syntax(volume_data, additional_data)
|
43
47
|
source_path = volume_data['source'].to_s.strip
|
44
48
|
target_path = volume_data['target'].to_s.strip
|
45
49
|
read_only = volume_data['read_only'].present?
|
@@ -47,7 +51,7 @@ class UffizziCore::ComposeFile::Parsers::Services::VolumesParserService
|
|
47
51
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.volume_prop_is_required', prop_name: 'source') if source_path.blank?
|
48
52
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.volume_prop_is_required', prop_name: 'target') if target_path.blank?
|
49
53
|
|
50
|
-
build_volume_attributes(source_path, target_path, read_only,
|
54
|
+
build_volume_attributes(source_path, target_path, read_only, additional_data)
|
51
55
|
end
|
52
56
|
|
53
57
|
def build_volume_attributes(source_path, target_path, read_only, params = {})
|
@@ -70,10 +74,7 @@ class UffizziCore::ComposeFile::Parsers::Services::VolumesParserService
|
|
70
74
|
end
|
71
75
|
|
72
76
|
def build_volume_type(source_path, target_path)
|
73
|
-
if path?(source_path) && path?(target_path)
|
74
|
-
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.volume_type_not_supported', type: HOST_VOLUME_TYPE)
|
75
|
-
end
|
76
|
-
|
77
|
+
return HOST_VOLUME_TYPE if path?(source_path) && path?(target_path)
|
77
78
|
return ANONYMOUS_VOLUME_TYPE if path?(source_path) && target_path.blank?
|
78
79
|
return NAMED_VOLUME_TYPE if source_path.present? && !path?(source_path) && path?(target_path)
|
79
80
|
|
@@ -81,7 +82,7 @@ class UffizziCore::ComposeFile::Parsers::Services::VolumesParserService
|
|
81
82
|
end
|
82
83
|
|
83
84
|
def path?(path)
|
84
|
-
|
85
|
+
path.to_s.start_with?('/', './', '../')
|
85
86
|
end
|
86
87
|
|
87
88
|
def validate_named_volume(source_path, target_path, named_volumes_names, service_name)
|
@@ -70,12 +70,12 @@ class UffizziCore::ComposeFile::Parsers::ServicesParserService
|
|
70
70
|
build_parser_module.parse(value, compose_payload)
|
71
71
|
end
|
72
72
|
|
73
|
-
def parse_volumes(
|
73
|
+
def parse_volumes(volumes, additional_data)
|
74
74
|
volume_parser_module = find_volume_parser_module
|
75
75
|
|
76
|
-
return UffizziCore::ComposeFile::Parsers::Services::VolumesParserService.parse(
|
76
|
+
return UffizziCore::ComposeFile::Parsers::Services::VolumesParserService.parse(volumes, additional_data) unless volume_parser_module
|
77
77
|
|
78
|
-
volume_parser_module.parse(
|
78
|
+
volume_parser_module.parse(volumes, additional_data)
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
@@ -42,7 +42,7 @@ class UffizziCore::ComposeFile::TemplateService
|
|
42
42
|
attributes = compose_file_template_form.template_attributes
|
43
43
|
source = compose_file_template_form.source
|
44
44
|
template = compose_file_form.template
|
45
|
-
template = @project.templates.find_or_initialize_by(name: source) if
|
45
|
+
template = @project.templates.find_or_initialize_by(name: source) if template.blank?
|
46
46
|
template.assign_attributes(attributes)
|
47
47
|
template_form = template.becomes(UffizziCore::Api::Cli::V1::Template::CreateForm)
|
48
48
|
template_form.project = @project
|
@@ -21,7 +21,7 @@ class UffizziCore::ComposeFileService
|
|
21
21
|
check_config_options_format(compose_data)
|
22
22
|
configs_data = UffizziCore::ComposeFile::Parsers::ConfigsParserService.parse(compose_data['configs'])
|
23
23
|
secrets_data = UffizziCore::ComposeFile::Parsers::SecretsParserService.parse(compose_data['secrets'])
|
24
|
-
named_volume_names = UffizziCore::ComposeFile::Parsers::
|
24
|
+
named_volume_names = UffizziCore::ComposeFile::Parsers::NamedVolumesParserService.parse(compose_data['volumes'])
|
25
25
|
containers_data = UffizziCore::ComposeFile::Parsers::ServicesParserService.parse(
|
26
26
|
compose_data['services'],
|
27
27
|
configs_data,
|
@@ -132,6 +132,7 @@ class UffizziCore::ComposeFileService
|
|
132
132
|
def process_compose_file(compose_file_form, params)
|
133
133
|
cli_form = UffizziCore::Api::Cli::V1::ComposeFile::CliForm.new
|
134
134
|
cli_form.content = compose_file_form.content
|
135
|
+
cli_form.compose_file = compose_file_form.becomes(UffizziCore::ComposeFile)
|
135
136
|
return [compose_file_form, cli_form.errors] if cli_form.invalid?
|
136
137
|
|
137
138
|
dependencies = params[:dependencies].to_a
|
@@ -188,8 +189,10 @@ class UffizziCore::ComposeFileService
|
|
188
189
|
end
|
189
190
|
|
190
191
|
config_files_service = UffizziCore::ComposeFile::ConfigFilesService.new(compose_file_form)
|
191
|
-
|
192
|
-
|
192
|
+
config_file_errors = config_files_service.create_config_files(cli_form.compose_dependencies)
|
193
|
+
host_volume_file_errors = UffizziCore::ComposeFile::HostVolumeFilesService
|
194
|
+
.bulk_create(compose_file_form, cli_form.compose_dependencies)
|
195
|
+
raise ActiveRecord::Rollback if config_file_errors.present? || host_volume_file_errors.present?
|
193
196
|
|
194
197
|
project = compose_file_form.project
|
195
198
|
user = compose_file_form.added_by
|
@@ -45,14 +45,25 @@ class UffizziCore::ControllerService
|
|
45
45
|
containers = containers.map do |container|
|
46
46
|
UffizziCore::Controller::DeployContainers::ContainerSerializer.new(container).as_json(include: '**')
|
47
47
|
end
|
48
|
+
|
48
49
|
credentials = deployment.credentials.deployable.map do |credential|
|
49
50
|
UffizziCore::Controller::DeployContainers::CredentialSerializer.new(credential).as_json
|
50
51
|
end
|
51
52
|
|
53
|
+
host_volume_files = UffizziCore::HostVolumeFile.by_deployment(deployment).map do |host_volume_file|
|
54
|
+
UffizziCore::Controller::DeployContainers::HostVolumeFileSerializer.new(host_volume_file).as_json
|
55
|
+
end
|
56
|
+
|
57
|
+
compose_file = if deployment.compose_file.present?
|
58
|
+
UffizziCore::Controller::DeployContainers::ComposeFileSerializer.new(deployment.compose_file).as_json
|
59
|
+
end
|
60
|
+
|
52
61
|
body = {
|
53
62
|
containers: containers,
|
54
63
|
credentials: credentials,
|
55
64
|
deployment_url: deployment.preview_url,
|
65
|
+
compose_file: compose_file,
|
66
|
+
host_volume_files: host_volume_files,
|
56
67
|
}
|
57
68
|
|
58
69
|
if password_protection_module.present?
|
@@ -63,9 +63,9 @@ class UffizziCore::DeploymentService
|
|
63
63
|
Rails.logger.info("DEPLOYMENT_PROCESS deployment_id=#{deployment.id} start deploying into controller")
|
64
64
|
|
65
65
|
containers = deployment.active_containers
|
66
|
-
|
66
|
+
containers_with_variables = add_default_deployment_variables!(containers, deployment)
|
67
67
|
|
68
|
-
UffizziCore::ControllerService.deploy_containers(deployment,
|
68
|
+
UffizziCore::ControllerService.deploy_containers(deployment, containers_with_variables)
|
69
69
|
else
|
70
70
|
Rails.logger.info("DEPLOYMENT_PROCESS deployment_id=#{deployment.id} deployment has builds errors, stopping")
|
71
71
|
end
|
@@ -89,19 +89,18 @@ class UffizziCore::DeploymentService
|
|
89
89
|
|
90
90
|
def build_subdomain(deployment)
|
91
91
|
return build_docker_continuous_preview_subdomain(deployment) if deployment&.continuous_preview_payload&.fetch('docker', nil).present?
|
92
|
+
return build_pull_request_subdomain(deployment) if deployment.from_actions?
|
92
93
|
|
93
|
-
|
94
|
-
|
95
|
-
github_metadata&.dig('pull_request', 'number').present? && github_metadata&.dig('repository').present?
|
96
|
-
|
94
|
+
build_default_subdomain(deployment)
|
95
|
+
rescue UffizziCore::Deployment::LabelsNotFoundError
|
97
96
|
build_default_subdomain(deployment)
|
98
97
|
end
|
99
98
|
|
100
99
|
def build_pull_request_subdomain(deployment)
|
101
|
-
|
102
|
-
repo_name
|
103
|
-
|
104
|
-
subdomain = "pr-#{pull_request_number}-#{name(deployment)}-#{repo_name
|
100
|
+
repo_name, pull_request_number = pull_request_data(deployment)
|
101
|
+
raise UffizziCore::Deployment::LabelsNotFoundError if repo_name.nil? || pull_request_number.nil?
|
102
|
+
|
103
|
+
subdomain = "pr-#{pull_request_number}-#{name(deployment)}-#{repo_name.downcase}"
|
105
104
|
format_subdomain(subdomain)
|
106
105
|
end
|
107
106
|
|
@@ -291,5 +290,23 @@ class UffizziCore::DeploymentService
|
|
291
290
|
|
292
291
|
sliced_subdomain
|
293
292
|
end
|
293
|
+
|
294
|
+
def pull_request_data(deployment)
|
295
|
+
return github_pull_request_data(deployment) if deployment.from_github_actions?
|
296
|
+
|
297
|
+
gitlab_merge_request_data(deployment)
|
298
|
+
end
|
299
|
+
|
300
|
+
def github_pull_request_data(deployment)
|
301
|
+
github_data = deployment.metadata.dig('labels', 'github')
|
302
|
+
|
303
|
+
[github_data['repository'], github_data.dig('event', 'number')]
|
304
|
+
end
|
305
|
+
|
306
|
+
def gitlab_merge_request_data(deployment)
|
307
|
+
gitlab_data = deployment.metadata.dig('labels', 'gitlab')
|
308
|
+
|
309
|
+
[gitlab_data['repo'], gitlab_data.dig('merge_request', 'number')]
|
310
|
+
end
|
294
311
|
end
|
295
312
|
end
|
data/config/locales/en.yml
CHANGED
@@ -33,6 +33,7 @@ en:
|
|
33
33
|
image_build_no_specified: Service '%{value}' has neither an image nor a build context specified. At least one must be provided.
|
34
34
|
build_context_no_specified: The context option should be specified
|
35
35
|
config_file_not_found: Config file not found '%{name}'
|
36
|
+
host_volume_file_not_found: Host volume file not found '%{name}'
|
36
37
|
invalid_context: Invalid context value '%{value}'
|
37
38
|
invalid_bool_value: Invalid %{field} value '%{value}'. The value should be `true` or `false`
|
38
39
|
invalid_delete_after_postfix: The postfix of the delete_preview_after value should be `h`
|
@@ -64,10 +65,10 @@ en:
|
|
64
65
|
volume_path_is_invalid: The path '%{path}' is invalid
|
65
66
|
volume_prop_is_required: The '%{prop_name}' is a required property
|
66
67
|
volume_invalid_name: "Volumes value '%{name}' does not match any of the regexes: '^[a-zA-Z0-9._-]+$'"
|
67
|
-
volume_type_not_supported: Volumes with type '%{type}' does not supported
|
68
68
|
named_volume_not_exists: Named volume '%{source_path}:%{target_path}' is used in service '%{service_name}' but no declaration was found in the volumes section.
|
69
69
|
invalid_volume_destination: Invalid volume specification '%{spec}' destination can't be '/'
|
70
70
|
required_start_commands: "When 'test' is a list the first item must be one of: '%{available_commands}'"
|
71
|
+
volumes_should_be_array: Volumes '%{volumes}' should be an arra
|
71
72
|
secrets:
|
72
73
|
duplicates_exists: Secret with key %{secrets} already exist.
|
73
74
|
invalid_key_length: A secret key must be no longer than 256 characters.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateHostVolumeFiles < ActiveRecord::Migration[6.1]
|
4
|
+
def change
|
5
|
+
create_table :uffizzi_core_host_volume_files do |t|
|
6
|
+
t.string :source
|
7
|
+
t.string :path
|
8
|
+
t.boolean :is_file
|
9
|
+
t.binary :payload
|
10
|
+
t.bigint :added_by_id
|
11
|
+
t.timestamps
|
12
|
+
|
13
|
+
t.references :project, null: false,
|
14
|
+
foreign_key: true,
|
15
|
+
index: { name: :index_host_volume_file_on_project_id },
|
16
|
+
foreign_key: { to_table: :uffizzi_core_projects }
|
17
|
+
t.references :compose_file, null: false,
|
18
|
+
foreign_key: true,
|
19
|
+
index: { name: :index_host_volume_file_on_compose_file_id },
|
20
|
+
foreign_key: { to_table: :uffizzi_core_compose_files }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateContainerHostVolumeFiles < ActiveRecord::Migration[6.1]
|
4
|
+
def change
|
5
|
+
create_table :uffizzi_core_container_host_volume_files do |t|
|
6
|
+
t.string :source_path
|
7
|
+
t.timestamps
|
8
|
+
t.references :container, null: false,
|
9
|
+
foreign_key: true,
|
10
|
+
index: { name: :uf_core_cont_h_v_on_cont },
|
11
|
+
foreign_key: { to_table: :uffizzi_core_containers }
|
12
|
+
t.references :host_volume_file, null: false,
|
13
|
+
foreign_key: true,
|
14
|
+
index: { name: :uf_core_cont_h_v_on_h_v_file },
|
15
|
+
foreign_key: { to_table: :uffizzi_core_host_volume_files }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/uffizzi_core/version.rb
CHANGED
data/lib/uffizzi_core.rb
CHANGED
@@ -58,6 +58,8 @@ module UffizziCore
|
|
58
58
|
user_projects: :uffizzi_core_user_projects,
|
59
59
|
users: :uffizzi_core_users,
|
60
60
|
users_roles: :uffizzi_core_users_roles,
|
61
|
+
host_volume_files: :uffizzi_core_host_volume_files,
|
62
|
+
container_host_volume_files: :uffizzi_core_container_host_volume_files,
|
61
63
|
}
|
62
64
|
mattr_accessor :user_creation_sources, default: [:system, :online_registration, :google, :sso]
|
63
65
|
mattr_accessor :user_project_roles, default: [:admin, :developer, :viewer]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uffizzi_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Thurman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-10-
|
12
|
+
date: 2022-10-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aasm
|
@@ -563,6 +563,20 @@ dependencies:
|
|
563
563
|
- - ">="
|
564
564
|
- !ruby/object:Gem::Version
|
565
565
|
version: '0'
|
566
|
+
- !ruby/object:Gem::Dependency
|
567
|
+
name: hash_diff
|
568
|
+
requirement: !ruby/object:Gem::Requirement
|
569
|
+
requirements:
|
570
|
+
- - "~>"
|
571
|
+
- !ruby/object:Gem::Version
|
572
|
+
version: '1.1'
|
573
|
+
type: :development
|
574
|
+
prerelease: false
|
575
|
+
version_requirements: !ruby/object:Gem::Requirement
|
576
|
+
requirements:
|
577
|
+
- - "~>"
|
578
|
+
- !ruby/object:Gem::Version
|
579
|
+
version: '1.1'
|
566
580
|
- !ruby/object:Gem::Dependency
|
567
581
|
name: minitest
|
568
582
|
requirement: !ruby/object:Gem::Requirement
|
@@ -760,6 +774,7 @@ files:
|
|
760
774
|
- app/errors/uffizzi_core/compose_file/parse_error.rb
|
761
775
|
- app/errors/uffizzi_core/compose_file/secrets_error.rb
|
762
776
|
- app/errors/uffizzi_core/deployment/image_pull_error.rb
|
777
|
+
- app/errors/uffizzi_core/deployment/labels_not_found_error.rb
|
763
778
|
- app/errors/uffizzi_core/deployment_not_found_error.rb
|
764
779
|
- app/forms/uffizzi_core/api/cli/v1/account/credential/check_credential_form.rb
|
765
780
|
- app/forms/uffizzi_core/api/cli/v1/account/credential/create_form.rb
|
@@ -802,10 +817,12 @@ files:
|
|
802
817
|
- app/lib/uffizzi_core/concerns/models/config_file.rb
|
803
818
|
- app/lib/uffizzi_core/concerns/models/container.rb
|
804
819
|
- app/lib/uffizzi_core/concerns/models/container_config_file.rb
|
820
|
+
- app/lib/uffizzi_core/concerns/models/container_host_volume_file.rb
|
805
821
|
- app/lib/uffizzi_core/concerns/models/coupon.rb
|
806
822
|
- app/lib/uffizzi_core/concerns/models/credential.rb
|
807
823
|
- app/lib/uffizzi_core/concerns/models/deployment.rb
|
808
824
|
- app/lib/uffizzi_core/concerns/models/event.rb
|
825
|
+
- app/lib/uffizzi_core/concerns/models/host_volume_file.rb
|
809
826
|
- app/lib/uffizzi_core/concerns/models/membership.rb
|
810
827
|
- app/lib/uffizzi_core/concerns/models/payment.rb
|
811
828
|
- app/lib/uffizzi_core/concerns/models/price.rb
|
@@ -834,6 +851,7 @@ files:
|
|
834
851
|
- app/models/uffizzi_core/config_file.rb
|
835
852
|
- app/models/uffizzi_core/container.rb
|
836
853
|
- app/models/uffizzi_core/container_config_file.rb
|
854
|
+
- app/models/uffizzi_core/container_host_volume_file.rb
|
837
855
|
- app/models/uffizzi_core/continuous_preview.rb
|
838
856
|
- app/models/uffizzi_core/coupon.rb
|
839
857
|
- app/models/uffizzi_core/credential.rb
|
@@ -848,6 +866,7 @@ files:
|
|
848
866
|
- app/models/uffizzi_core/database_offering.rb
|
849
867
|
- app/models/uffizzi_core/deployment.rb
|
850
868
|
- app/models/uffizzi_core/event.rb
|
869
|
+
- app/models/uffizzi_core/host_volume_file.rb
|
851
870
|
- app/models/uffizzi_core/membership.rb
|
852
871
|
- app/models/uffizzi_core/payment.rb
|
853
872
|
- app/models/uffizzi_core/price.rb
|
@@ -887,6 +906,7 @@ files:
|
|
887
906
|
- app/repositories/uffizzi_core/credential_repo.rb
|
888
907
|
- app/repositories/uffizzi_core/deployment_repo.rb
|
889
908
|
- app/repositories/uffizzi_core/event_repo.rb
|
909
|
+
- app/repositories/uffizzi_core/host_volume_file_repo.rb
|
890
910
|
- app/repositories/uffizzi_core/membership_repo.rb
|
891
911
|
- app/repositories/uffizzi_core/price_repo.rb
|
892
912
|
- app/repositories/uffizzi_core/product_repo.rb
|
@@ -920,17 +940,21 @@ files:
|
|
920
940
|
- app/serializers/uffizzi_core/controller/apply_config_file/config_file_serializer.rb
|
921
941
|
- app/serializers/uffizzi_core/controller/create_credential/credential_serializer.rb
|
922
942
|
- app/serializers/uffizzi_core/controller/create_deployment/deployment_serializer.rb
|
943
|
+
- app/serializers/uffizzi_core/controller/deploy_containers/compose_file_serializer.rb
|
923
944
|
- app/serializers/uffizzi_core/controller/deploy_containers/container_serializer.rb
|
924
945
|
- app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_config_file_serializer.rb
|
925
946
|
- app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_config_file_serializer/config_file_serializer.rb
|
947
|
+
- app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_host_volume_file_serializer.rb
|
926
948
|
- app/serializers/uffizzi_core/controller/deploy_containers/credential_serializer.rb
|
949
|
+
- app/serializers/uffizzi_core/controller/deploy_containers/host_volume_file_serializer.rb
|
927
950
|
- app/services/uffizzi_core/account_service.rb
|
928
951
|
- app/services/uffizzi_core/activity_item_service.rb
|
929
952
|
- app/services/uffizzi_core/amazon/credential_service.rb
|
930
953
|
- app/services/uffizzi_core/amazon_service.rb
|
931
954
|
- app/services/uffizzi_core/azure/credential_service.rb
|
932
|
-
- app/services/uffizzi_core/compose_file/builders/config_files_builder_service.rb
|
933
955
|
- app/services/uffizzi_core/compose_file/builders/container_builder_service.rb
|
956
|
+
- app/services/uffizzi_core/compose_file/builders/container_config_files_builder_service.rb
|
957
|
+
- app/services/uffizzi_core/compose_file/builders/container_host_volume_files_builder_service.rb
|
934
958
|
- app/services/uffizzi_core/compose_file/builders/docker_repo_builder_service.rb
|
935
959
|
- app/services/uffizzi_core/compose_file/builders/template_builder_service.rb
|
936
960
|
- app/services/uffizzi_core/compose_file/builders/variables_builder_service.rb
|
@@ -940,9 +964,11 @@ files:
|
|
940
964
|
- app/services/uffizzi_core/compose_file/dependencies_service.rb
|
941
965
|
- app/services/uffizzi_core/compose_file/errors_service.rb
|
942
966
|
- app/services/uffizzi_core/compose_file/github_dependencies_service.rb
|
967
|
+
- app/services/uffizzi_core/compose_file/host_volume_files_service.rb
|
943
968
|
- app/services/uffizzi_core/compose_file/parsers/configs_parser_service.rb
|
944
969
|
- app/services/uffizzi_core/compose_file/parsers/continuous_preview_parser_service.rb
|
945
970
|
- app/services/uffizzi_core/compose_file/parsers/ingress_parser_service.rb
|
971
|
+
- app/services/uffizzi_core/compose_file/parsers/named_volumes_parser_service.rb
|
946
972
|
- app/services/uffizzi_core/compose_file/parsers/secrets_parser_service.rb
|
947
973
|
- app/services/uffizzi_core/compose_file/parsers/services/command_parser_service.rb
|
948
974
|
- app/services/uffizzi_core/compose_file/parsers/services/configs_parser_service.rb
|
@@ -956,7 +982,6 @@ files:
|
|
956
982
|
- app/services/uffizzi_core/compose_file/parsers/services/volumes_parser_service.rb
|
957
983
|
- app/services/uffizzi_core/compose_file/parsers/services_parser_service.rb
|
958
984
|
- app/services/uffizzi_core/compose_file/parsers/variables_parser_service.rb
|
959
|
-
- app/services/uffizzi_core/compose_file/parsers/volumes_parser_service.rb
|
960
985
|
- app/services/uffizzi_core/compose_file/template_service.rb
|
961
986
|
- app/services/uffizzi_core/compose_file_service.rb
|
962
987
|
- app/services/uffizzi_core/container_service.rb
|
@@ -1001,6 +1026,8 @@ files:
|
|
1001
1026
|
- db/migrate/20220525113412_rename_name_to_uffizzi_containers.rb
|
1002
1027
|
- db/migrate/20220704135629_add_disabled_at_to_deployments.rb
|
1003
1028
|
- db/migrate/20220805164628_add_metadata_to_deployment.rb
|
1029
|
+
- db/migrate/20220901110752_create_host_volume_files.rb
|
1030
|
+
- db/migrate/20220901165313_create_container_host_volume_files.rb
|
1004
1031
|
- db/migrate/20220927113647_add_additional_subdomains_to_containers.rb
|
1005
1032
|
- db/seeds.rb
|
1006
1033
|
- lib/tasks/uffizzi_core_tasks.rake
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class UffizziCore::ComposeFile::Builders::ConfigFilesBuilderService
|
4
|
-
attr_accessor :project
|
5
|
-
|
6
|
-
def initialize(project)
|
7
|
-
@project = project
|
8
|
-
end
|
9
|
-
|
10
|
-
def build_attributes(config_files_data, dependencies)
|
11
|
-
return [] if config_files_data.empty?
|
12
|
-
|
13
|
-
config_file_sources = dependencies.pluck(:source)
|
14
|
-
config_files = project.config_files.with_creation_source(UffizziCore::ConfigFile.creation_source.compose_file)
|
15
|
-
.by_source(config_file_sources)
|
16
|
-
|
17
|
-
config_files_data.map do |config_file_data|
|
18
|
-
detected_dependency = dependencies.detect { |dependency| dependency[:path] == config_file_data[:source] }
|
19
|
-
detected_config_file = config_files.detect { |config_file| config_file.source == detected_dependency[:source] }
|
20
|
-
|
21
|
-
if detected_config_file.nil?
|
22
|
-
raise UffizziCore::ComposeFile::BuildError, I18n.t('compose.config_file_not_found', name: config_file_data[:source])
|
23
|
-
end
|
24
|
-
|
25
|
-
{
|
26
|
-
mount_path: config_file_data[:target],
|
27
|
-
config_file_id: detected_config_file.id,
|
28
|
-
}
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|