rubber 2.8.0 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b790684866800f608ac2a7e8c46be7b69eaff208
4
- data.tar.gz: 5eeebc027c8b19071df95dd125bdeda47ee2a124
3
+ metadata.gz: 74952b3078921c178e794dd97dbfde331e459626
4
+ data.tar.gz: 64a2230b873c17bf2d296267f04b4ede7df42cc3
5
5
  SHA512:
6
- metadata.gz: 1a460123e60720d4e04cc9c1d1868e594c9a231cfc0f5ba51b6e1f4793586d283626f3b57685df992505a346d6dd54e9c756897bdbd6a8d41f00d2c96de8872c
7
- data.tar.gz: 6ad1acc813073a33f9547dd8aa25927046645f9e1f8b74e6d13c5f439fbe9b2672b8c35758699cb185fe8fa661fd07fb31115d4287c70ac74fdedf06bc9f074f
6
+ metadata.gz: cadef25f61d49602b586cedfe50f20a7c67ec83ac5f6d6b7a21ea63e58eb27edb9a5d45d4e8a483eab874589c8c7391898361a41d7196912ec3a8801e29eceda
7
+ data.tar.gz: fce48417a6a09e1e12ede3487f24cf70f3b5e6feb0a3da2c33d5a152390f9a2aa2915956bae282d754e9de2b0e84be34eaeefbf29b55876215457b9ae4d51856
data/CHANGELOG CHANGED
@@ -1,3 +1,16 @@
1
+ 2.8.1 (05/01/2014)
2
+
3
+ Bug Fixes:
4
+ =========
5
+
6
+ [core] Detect alternate location of secret file when it is moved into the /config/rubber dir on remote servers. <9bd12ad>
7
+ [core] Make sure add-apt-repository is available on Ubuntu > 12.04. <36c423d>
8
+ [core] Fixed compatibility with Vagrant 1.5.x. <55416f8>
9
+ [selenium_grid_hub] Replaced hard-coded app user with app_user variable. <afc7e9c>
10
+ [selenium_grid_hub] Fixed dynamic MaxPermSize. <abd46cd>
11
+ [web_tools] Underscores aren't valid in hostname, so convert to hyphens like we do everywhere else. <bbe0b81>
12
+
13
+
1
14
  2.8.0 (03/30/2014)
2
15
 
3
16
  New Features:
@@ -52,6 +52,14 @@ module Rubber
52
52
  bound = bind()
53
53
  @config_secret = bound.rubber_secret
54
54
  if @config_secret
55
+
56
+ # The config_secret value should point to a file outside of the project directory. When run locally, rubber
57
+ # will be able to read this file directly. In order to support deploys without having to commit this file,
58
+ # rubber will SCP the file up as part of the deploy. In that case, the file can be found in config_root and
59
+ # will have the same base name. If the file doesn't exist locally, we'll assume it's a deployed location
60
+ # and read the file from config_root.
61
+ @config_secret = "#{@config_root}/#{File.basename(@config_secret)}" unless File.exist?(@config_secret)
62
+
55
63
  obfuscation_key = bound.rubber_secret_key
56
64
  if obfuscation_key
57
65
  require 'rubber/encryption'
@@ -396,7 +396,8 @@ namespace :rubber do
396
396
  DESC
397
397
  task :install_core_packages do
398
398
  core_packages = [
399
- 'python-software-properties', # Needed for add-apt-repository, which we use for adding PPAs.
399
+ 'python-software-properties', # Needed for add-apt-repository (<= Ubuntu 12.04), which we use for adding PPAs.
400
+ 'software-properties-common', # Needed for add-apt-repository (> Ubuntu 12.04), which we use for adding PPAs.
400
401
  'bc', # Needed for comparing version numbers in bash, which we do for various setup functions.
401
402
  'update-notifier-common', # Needed for notifying us when a package upgrade requires a reboot.
402
403
  'scsitools' # Needed to rescan SCSI channels for any added devices.
@@ -39,9 +39,9 @@ module VagrantPlugins
39
39
  script = "RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} ALIAS=#{machine.name} ROLES='#{config.roles}' EXTERNAL_IP=#{private_ip} INTERNAL_IP=#{private_ip} RUBBER_SSH_KEY=#{rubber_ssh_keys} #{internal_cap_command} rubber:create -S initial_ssh_user=#{ssh_info[:username]}"
40
40
  else
41
41
  script = <<-ENDSCRIPT
42
- unset GEM_HOME;
43
- unset GEM_PATH;
44
- PATH=#{ENV['PATH'].split(':')[1..-1].join(':')} RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} ALIAS=#{machine.name} ROLES='#{config.roles}' EXTERNAL_IP=#{private_ip} INTERNAL_IP=#{private_ip} RUBBER_SSH_KEY=#{rubber_ssh_keys} bash -c '#{rvm_prefix} bundle exec cap rubber:create -S initial_ssh_user=#{ssh_info[:username]}'
42
+ #{clear_vagrant_environment}
43
+
44
+ RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} ALIAS=#{machine.name} ROLES='#{config.roles}' EXTERNAL_IP=#{private_ip} INTERNAL_IP=#{private_ip} RUBBER_SSH_KEY=#{rubber_ssh_keys} bash -c '#{rvm_prefix} bundle exec cap rubber:create -S initial_ssh_user=#{ssh_info[:username]}'
45
45
  ENDSCRIPT
46
46
  end
47
47
 
@@ -53,9 +53,9 @@ module VagrantPlugins
53
53
  script = "RUN_FROM_VAGRANT=true FORCE=true RUBBER_ENV=#{config.rubber_env} ALIAS=#{machine.name} #{internal_cap_command} rubber:destroy"
54
54
  else
55
55
  script = <<-ENDSCRIPT
56
- unset GEM_HOME;
57
- unset GEM_PATH;
58
- PATH=#{ENV['PATH'].split(':')[1..-1].join(':')} RUN_FROM_VAGRANT=true FORCE=true RUBBER_ENV=#{config.rubber_env} ALIAS=#{machine.name} bash -c '#{rvm_prefix} bundle exec cap rubber:destroy'
56
+ #{clear_vagrant_environment}
57
+
58
+ RUN_FROM_VAGRANT=true FORCE=true RUBBER_ENV=#{config.rubber_env} ALIAS=#{machine.name} bash -c '#{rvm_prefix} bundle exec cap rubber:destroy'
59
59
  ENDSCRIPT
60
60
  end
61
61
 
@@ -67,9 +67,9 @@ module VagrantPlugins
67
67
  script = "RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{rubber_ssh_keys} ALIAS=#{machine.name} EXTERNAL_IP=#{private_ip} INTERNAL_IP=#{private_ip} #{internal_cap_command} rubber:refresh -S initial_ssh_user=#{ssh_info[:username]}"
68
68
  else
69
69
  script = <<-ENDSCRIPT
70
- unset GEM_HOME;
71
- unset GEM_PATH;
72
- PATH=#{ENV['PATH'].split(':')[1..-1].join(':')} RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{rubber_ssh_keys} ALIAS=#{machine.name} EXTERNAL_IP=#{private_ip} INTERNAL_IP=#{private_ip} bash -c '#{rvm_prefix} bundle exec cap rubber:refresh -S initial_ssh_user=#{ssh_info[:username]}'
70
+ #{clear_vagrant_environment}
71
+
72
+ RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{rubber_ssh_keys} ALIAS=#{machine.name} EXTERNAL_IP=#{private_ip} INTERNAL_IP=#{private_ip} bash -c '#{rvm_prefix} bundle exec cap rubber:refresh -S initial_ssh_user=#{ssh_info[:username]}'
73
73
  ENDSCRIPT
74
74
  end
75
75
 
@@ -81,9 +81,9 @@ module VagrantPlugins
81
81
  script = "RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{rubber_ssh_keys} FILTER=#{machine.name} #{internal_cap_command} rubber:bootstrap"
82
82
  else
83
83
  script = <<-ENDSCRIPT
84
- unset GEM_HOME;
85
- unset GEM_PATH;
86
- PATH=#{ENV['PATH'].split(':')[1..-1].join(':')} RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{rubber_ssh_keys} FILTER=#{machine.name} bash -c '#{rvm_prefix} bundle exec cap rubber:bootstrap'
84
+ #{clear_vagrant_environment}
85
+
86
+ RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{rubber_ssh_keys} FILTER=#{machine.name} bash -c '#{rvm_prefix} bundle exec cap rubber:bootstrap'
87
87
  ENDSCRIPT
88
88
  end
89
89
 
@@ -95,9 +95,9 @@ module VagrantPlugins
95
95
  script = "RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{rubber_ssh_keys} FILTER=#{machine.name} #{internal_cap_command} deploy:migrations"
96
96
  else
97
97
  script = <<-ENDSCRIPT
98
- unset GEM_HOME;
99
- unset GEM_PATH;
100
- PATH=#{ENV['PATH'].split(':')[1..-1].join(':')} RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{rubber_ssh_keys} FILTER=#{machine.name} bash -c '#{rvm_prefix} bundle exec cap deploy:migrations'
98
+ #{clear_vagrant_environment}
99
+
100
+ RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{rubber_ssh_keys} FILTER=#{machine.name} bash -c '#{rvm_prefix} bundle exec cap deploy:migrations'
101
101
  ENDSCRIPT
102
102
  end
103
103
 
@@ -111,6 +111,21 @@ module VagrantPlugins
111
111
  def rvm_prefix
112
112
  config.rvm_ruby_version ? "rvm #{config.rvm_ruby_version} do" : ''
113
113
  end
114
+
115
+ def clear_vagrant_environment
116
+ <<-ENDSCRIPT
117
+ unset GEM_HOME;
118
+ unset GEM_PATH;
119
+ unset RUBYOPT;
120
+ unset GEMRC;
121
+ unset BUNDLE_GEMFILE;
122
+ unset BUNDLE_BIN_PATH;
123
+ unset RUBYLIB;
124
+ unset BUNDLE_APP_CONFIG;
125
+
126
+ export PATH=#{ENV['PATH'].split(':').reject { |entry| entry =~ /vagrant/i }.join(':')};
127
+ ENDSCRIPT
128
+ end
114
129
  end
115
130
  end
116
131
  end
@@ -1,3 +1,3 @@
1
1
  module Rubber
2
- VERSION = '2.8.0'.freeze
2
+ VERSION = '2.8.1'.freeze
3
3
  end
@@ -19,7 +19,7 @@ server
19
19
  proxy_host = rubber_instances.for_role(settings.role).first.full_name rescue nil
20
20
  next unless proxy_host
21
21
 
22
- host = "#{name}-#{rubber_env.full_host}"
22
+ host = "#{name.gsub('_', '-')}-#{rubber_env.full_host}"
23
23
  host_and_port = "#{host}:#{rubber_env.web_tools_ssl_port}"
24
24
 
25
25
  # don't use settings.path here - mapping the host/port is sufficient,
@@ -19,7 +19,7 @@ server
19
19
  proxy_host = rubber_instances.for_role(settings.role).first.full_name rescue nil
20
20
  next unless proxy_host
21
21
 
22
- host = "#{name}-#{rubber_env.full_host}"
22
+ host = "#{name.gsub('_', '-')}-#{rubber_env.full_host}"oc
23
23
  host_and_port = "#{host}:#{rubber_env.web_tools_ssl_port}"
24
24
 
25
25
  # don't use settings.path here - mapping the host/port is sufficient,
@@ -14,12 +14,12 @@ namespace :rubber do
14
14
  # Create the log directory if necessary.
15
15
  if [[ ! -d #{rubber_env.selenium_grid_hub_log_dir} ]]; then
16
16
  mkdir -p #{rubber_env.selenium_grid_hub_log_dir}
17
- chown app:app #{rubber_env.selenium_grid_hub_log_dir}
17
+ chown #{rubber_env.app_user}:#{rubber_env.app_user} #{rubber_env.selenium_grid_hub_log_dir}
18
18
  fi
19
19
 
20
20
  if [[ ! -d #{rubber_env.selenium_grid_hub_dir} ]]; then
21
21
  mkdir -p #{rubber_env.selenium_grid_hub_dir}
22
- chown app:app #{rubber_env.selenium_grid_hub_dir}
22
+ chown #{rubber_env.app_user}:#{rubber_env.app_user} #{rubber_env.selenium_grid_hub_dir}
23
23
  fi
24
24
 
25
25
  # Fetch the Selenium Grid 2 JARs.
@@ -5,7 +5,7 @@
5
5
  args = []
6
6
  args << '-Xms256m'
7
7
  args << "-Xmx#{rubber_env.selenium_grid_hub_max_heap_in_mb}m"
8
- args << '-XX:MaxPermSize=#{rubber_env.selenium_grid_hub_permgen_in_mb}m'
8
+ args << "-XX:MaxPermSize=#{rubber_env.selenium_grid_hub_permgen_in_mb}m"
9
9
  args << '-server'
10
10
  args << '-Xdebug'
11
11
  args << '-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005'
metadata CHANGED
@@ -1,184 +1,184 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.0
4
+ version: 2.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Conway
8
8
  - Kevin Menard
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-31 00:00:00.000000000 Z
12
+ date: 2014-05-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
16
- requirement: !ruby/object:Gem::Requirement
16
+ version_requirements: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ~>
19
19
  - !ruby/object:Gem::Version
20
20
  version: '2.12'
21
- type: :runtime
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
21
+ requirement: !ruby/object:Gem::Requirement
24
22
  requirements:
25
- - - "~>"
23
+ - - ~>
26
24
  - !ruby/object:Gem::Version
27
25
  version: '2.12'
26
+ prerelease: false
27
+ type: :runtime
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: net-ssh
30
- requirement: !ruby/object:Gem::Requirement
30
+ version_requirements: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ~>
33
33
  - !ruby/object:Gem::Version
34
34
  version: '2.6'
35
- type: :runtime
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
35
+ requirement: !ruby/object:Gem::Requirement
38
36
  requirements:
39
- - - "~>"
37
+ - - ~>
40
38
  - !ruby/object:Gem::Version
41
39
  version: '2.6'
40
+ prerelease: false
41
+ type: :runtime
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: thor
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
44
49
  requirement: !ruby/object:Gem::Requirement
45
50
  requirements:
46
- - - ">="
51
+ - - '>='
47
52
  - !ruby/object:Gem::Version
48
53
  version: '0'
49
- type: :runtime
50
54
  prerelease: false
55
+ type: :runtime
56
+ - !ruby/object:Gem::Dependency
57
+ name: clamp
51
58
  version_requirements: !ruby/object:Gem::Requirement
52
59
  requirements:
53
- - - ">="
60
+ - - '>='
54
61
  - !ruby/object:Gem::Version
55
62
  version: '0'
56
- - !ruby/object:Gem::Dependency
57
- name: clamp
58
63
  requirement: !ruby/object:Gem::Requirement
59
64
  requirements:
60
- - - ">="
65
+ - - '>='
61
66
  - !ruby/object:Gem::Version
62
67
  version: '0'
63
- type: :runtime
64
68
  prerelease: false
69
+ type: :runtime
70
+ - !ruby/object:Gem::Dependency
71
+ name: open4
65
72
  version_requirements: !ruby/object:Gem::Requirement
66
73
  requirements:
67
- - - ">="
74
+ - - '>='
68
75
  - !ruby/object:Gem::Version
69
76
  version: '0'
70
- - !ruby/object:Gem::Dependency
71
- name: open4
72
77
  requirement: !ruby/object:Gem::Requirement
73
78
  requirements:
74
- - - ">="
79
+ - - '>='
75
80
  - !ruby/object:Gem::Version
76
81
  version: '0'
77
- type: :runtime
78
82
  prerelease: false
83
+ type: :runtime
84
+ - !ruby/object:Gem::Dependency
85
+ name: fog
79
86
  version_requirements: !ruby/object:Gem::Requirement
80
87
  requirements:
81
- - - ">="
88
+ - - ~>
82
89
  - !ruby/object:Gem::Version
83
- version: '0'
84
- - !ruby/object:Gem::Dependency
85
- name: fog
90
+ version: '1.6'
86
91
  requirement: !ruby/object:Gem::Requirement
87
92
  requirements:
88
- - - "~>"
93
+ - - ~>
89
94
  - !ruby/object:Gem::Version
90
95
  version: '1.6'
91
- type: :runtime
92
96
  prerelease: false
97
+ type: :runtime
98
+ - !ruby/object:Gem::Dependency
99
+ name: json
93
100
  version_requirements: !ruby/object:Gem::Requirement
94
101
  requirements:
95
- - - "~>"
102
+ - - '>='
96
103
  - !ruby/object:Gem::Version
97
- version: '1.6'
98
- - !ruby/object:Gem::Dependency
99
- name: json
104
+ version: '0'
100
105
  requirement: !ruby/object:Gem::Requirement
101
106
  requirements:
102
- - - ">="
107
+ - - '>='
103
108
  - !ruby/object:Gem::Version
104
109
  version: '0'
105
- type: :runtime
106
110
  prerelease: false
111
+ type: :runtime
112
+ - !ruby/object:Gem::Dependency
113
+ name: rake
107
114
  version_requirements: !ruby/object:Gem::Requirement
108
115
  requirements:
109
- - - ">="
116
+ - - '>='
110
117
  - !ruby/object:Gem::Version
111
118
  version: '0'
112
- - !ruby/object:Gem::Dependency
113
- name: rake
114
119
  requirement: !ruby/object:Gem::Requirement
115
120
  requirements:
116
- - - ">="
121
+ - - '>='
117
122
  - !ruby/object:Gem::Version
118
123
  version: '0'
119
- type: :development
120
124
  prerelease: false
125
+ type: :development
126
+ - !ruby/object:Gem::Dependency
127
+ name: test-unit
121
128
  version_requirements: !ruby/object:Gem::Requirement
122
129
  requirements:
123
- - - ">="
130
+ - - '>='
124
131
  - !ruby/object:Gem::Version
125
132
  version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: test-unit
128
133
  requirement: !ruby/object:Gem::Requirement
129
134
  requirements:
130
- - - ">="
135
+ - - '>='
131
136
  - !ruby/object:Gem::Version
132
137
  version: '0'
133
- type: :development
134
138
  prerelease: false
139
+ type: :development
140
+ - !ruby/object:Gem::Dependency
141
+ name: shoulda-context
135
142
  version_requirements: !ruby/object:Gem::Requirement
136
143
  requirements:
137
- - - ">="
144
+ - - '>='
138
145
  - !ruby/object:Gem::Version
139
146
  version: '0'
140
- - !ruby/object:Gem::Dependency
141
- name: shoulda-context
142
147
  requirement: !ruby/object:Gem::Requirement
143
148
  requirements:
144
- - - ">="
149
+ - - '>='
145
150
  - !ruby/object:Gem::Version
146
151
  version: '0'
147
- type: :development
148
152
  prerelease: false
153
+ type: :development
154
+ - !ruby/object:Gem::Dependency
155
+ name: mocha
149
156
  version_requirements: !ruby/object:Gem::Requirement
150
157
  requirements:
151
- - - ">="
158
+ - - '>='
152
159
  - !ruby/object:Gem::Version
153
160
  version: '0'
154
- - !ruby/object:Gem::Dependency
155
- name: mocha
156
161
  requirement: !ruby/object:Gem::Requirement
157
162
  requirements:
158
- - - ">="
163
+ - - '>='
159
164
  - !ruby/object:Gem::Version
160
165
  version: '0'
161
- type: :development
162
166
  prerelease: false
167
+ type: :development
168
+ - !ruby/object:Gem::Dependency
169
+ name: awesome_print
163
170
  version_requirements: !ruby/object:Gem::Requirement
164
171
  requirements:
165
- - - ">="
172
+ - - '>='
166
173
  - !ruby/object:Gem::Version
167
174
  version: '0'
168
- - !ruby/object:Gem::Dependency
169
- name: awesome_print
170
175
  requirement: !ruby/object:Gem::Requirement
171
176
  requirements:
172
- - - ">="
177
+ - - '>='
173
178
  - !ruby/object:Gem::Version
174
179
  version: '0'
175
- type: :development
176
180
  prerelease: false
177
- version_requirements: !ruby/object:Gem::Requirement
178
- requirements:
179
- - - ">="
180
- - !ruby/object:Gem::Version
181
- version: '0'
181
+ type: :development
182
182
  description: |2
183
183
  The rubber plugin enables relatively complex multi-instance deployments of RubyOnRails applications to
184
184
  Amazon's Elastic Compute Cloud (EC2). Like capistrano, rubber is role based, so you can define a set
@@ -194,8 +194,8 @@ executables:
194
194
  extensions: []
195
195
  extra_rdoc_files: []
196
196
  files:
197
- - ".gitignore"
198
- - ".travis.yml"
197
+ - .gitignore
198
+ - .travis.yml
199
199
  - CHANGELOG
200
200
  - Gemfile
201
201
  - Gemfile.1.8.7
@@ -695,25 +695,24 @@ files:
695
695
  homepage: https://github.com/rubber/rubber
696
696
  licenses: []
697
697
  metadata: {}
698
- post_install_message:
698
+ post_install_message:
699
699
  rdoc_options: []
700
700
  require_paths:
701
701
  - lib
702
702
  required_ruby_version: !ruby/object:Gem::Requirement
703
703
  requirements:
704
- - - ">="
704
+ - - '>='
705
705
  - !ruby/object:Gem::Version
706
706
  version: '0'
707
707
  required_rubygems_version: !ruby/object:Gem::Requirement
708
708
  requirements:
709
- - - ">="
709
+ - - '>='
710
710
  - !ruby/object:Gem::Version
711
711
  version: '0'
712
712
  requirements: []
713
713
  rubyforge_project: rubber
714
- rubygems_version: 2.2.2
715
- signing_key:
714
+ rubygems_version: 2.1.9
715
+ signing_key:
716
716
  specification_version: 4
717
- summary: A capistrano plugin for managing multi-instance deployments to the cloud
718
- (ec2)
717
+ summary: A capistrano plugin for managing multi-instance deployments to the cloud (ec2)
719
718
  test_files: []