C0 code coverage information
Generated on Tue Oct 21 01:05:25 +0100 2008 with rcov <IP_ADDRESS>
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # Associations are used in order to specify relationships between model classes
2 # that reflect relations between tables in the database using foreign keys.
3 #
4 # Each kind of association adds a number of methods to the model class which
5 # are specialized according to the association type and optional parameters
6 # given in the definition. Example:
7 #
8 # class Project < Sequel::Model
9 # many_to_one :portfolio
10 # one_to_many :milestones
11 # end
12 #
13 # The project class now has the following instance methods:
14 # * portfolio - Returns the associated portfolio.
15 # * portfolio=(obj) - Sets the associated portfolio to the object,
16 # but the change is not persisted until you save the record.
17 # * portfolio_dataset - Returns a dataset that would return the associated
18 # portfolio, only useful in fairly specific circumstances.
19 # * milestones - Returns an array of associated milestones
20 # * add_milestone(obj) - Associates the passed milestone with this object.
21 # * remove_milestone(obj) - Removes the association with the passed milestone.
22 # * remove_all_milestones - Removes associations with all associated milestones.
23 # * milestones_dataset - Returns a dataset that would return the associated
24 # milestones, allowing for further filtering/limiting/etc.
25 #
26 # If you want to override the behavior of the add_/remove_/remove_all_ methods,
27 # there are private instance methods created that a prepended with an
28 # underscore (e.g. _add_milestone). The private instance methods can be
29 # easily overridden, but you shouldn't override the public instance methods,
30 # as they deal with how associations are cached.
31 #
32 # By default the classes for the associations are inferred from the association
33 # name, so for example the Project#portfolio will return an instance of
34 # Portfolio, and Project#milestones will return an array of Milestone
35 # instances, in similar fashion to how ActiveRecord infers class names.
36 #
37 # Association definitions are also reflected by the class, e.g.:
38 #
39 # Project.associations
40 # => [:portfolio, :milestones]
41 # Project.association_reflection(:portfolio)
42 # => {:type => :many_to_one, :name => :portfolio, :class_name => "Portfolio"}
43 #
44 # Associations can be defined by either using the associate method, or by
45 # calling one of the three methods: many_to_one, one_to_many, many_to_many.
46 # Sequel::Model also provides aliases for these methods that conform to
47 # ActiveRecord conventions: belongs_to, has_many, has_and_belongs_to_many.
48 # For example, the following three statements are equivalent:
49 #
50 # associate :one_to_many, :attributes
51 # one_to_many :attributes
52 # has_many :attributes
53 module Sequel::Model::Associations
54 # Array of all association reflections for this model class
55 def all_association_reflections
56 association_reflections.values
57 end
58
59 # Associates a related model with the current model. The following types are
60 # supported:
61 #
62 # * :many_to_one - Foreign key in current model's table points to
63 # associated model's primary key. Each associated model object can
64 # be associated with more than one current model objects. Each current
65 # model object can be associated with only one associated model object.
66 # Similar to ActiveRecord's belongs_to.
67 # * :one_to_many - Foreign key in associated model's table points to this
68 # model's primary key. Each current model object can be associated with
69 # more than one associated model objects. Each associated model object
70 # can be associated with only one current model object.
71 # Similar to ActiveRecord's has_many.
72 # * :many_to_many - A join table is used that has a foreign key that points
73 # to this model's primary key and a foreign key that points to the
74 # associated model's primary key. Each current model object can be
75 # associated with many associated model objects, and each associated
76 # model object can be associated with many current model objects.
77 # Similar to ActiveRecord's has_and_belongs_to_many.
78 #
79 # A one to one relationship can be set up with a many_to_one association
80 # on the table with the foreign key, and a one_to_many association with the
81 # :one_to_one option specified on the table without the foreign key. The
82 # two associations will operate similarly, except that the many_to_one
83 # association setter doesn't update the database until you call save manually.
84 #
85 # The following options can be supplied:
86 # * *ALL types*:
87 # - :after_add - Symbol, Proc, or array of both/either specifying a callback to call
88 # after a new item is added to the association.
89 # - :after_load - Symbol, Proc, or array of both/either specifying a callback to call
90 # after the associated record(s) have been retrieved from the database. Not called
91 # when eager loading (see the :eager_loader option to accomplish it when eager loading).
92 # - :after_remove - Symbol, Proc, or array of both/either specifying a callback to call
93 # after an item is removed from the association.
94 # - :allow_eager - If set to false, you cannot load the association eagerly
95 # via eager or eager_graph
96 # - :before_add - Symbol, Proc, or array of both/either specifying a callback to call
97 # before a new item is added to the association.
98 # - :before_remove - Symbol, Proc, or array of both/either specifying a callback to call
99 # before an item is removed from the association.
100 # - :class - The associated class or its name. If not
101 # given, uses the association's name, which is camelized (and
102 # singularized unless the type is :many_to_one)
103 # - :dataset - A proc that is instance_evaled to get the base dataset
104 # to use for the _dataset method (before the other options are applied).
105 # - :eager - The associations to eagerly load via EagerLoading#eager when loading the associated object(s).
106 # For many_to_one associations, this is ignored unless this association is
107 # being eagerly loaded, as it doesn't save queries unless multiple objects
108 # can be loaded at once.
109 # - :eager_block - If given, use the block instead of the default block when
110 # eagerly loading. To not use a block when eager loading (when one is used normally),
111 # set to nil.
112 # - :eager_graph - The associations to eagerly load via EagerLoading#eager_graph when loading the associated object(s).
113 # For many_to_one associations, this is ignored unless this association is
114 # being eagerly loaded, as it doesn't save queries unless multiple objects
115 # can be loaded at once.
116 # - :eager_loader - A proc to use to implement eager loading, overriding the default. Takes three arguments,
117 # a key hash (used solely to enhance performance), an array of records,
118 # and a hash of dependent associations. The associated records should
119 # be queried from the database and the associations cache for each
120 # record should be populated for this to work correctly.
121 # - :extend - A module or array of modules to extend the dataset with.
122 # - :graph_block - The block to pass to join_table when eagerly loading
123 # the association via eager_graph.
124 # - :graph_conditions - The additional conditions to use on the SQL join when eagerly loading
125 # the association via eager_graph. Should be a hash or an array of all two pairs.
126 # - :graph_join_type - The type of SQL join to use when eagerly loading the association via
127 # eager_graph. Defaults to :left_outer.
128 # - :graph_only_conditions - The conditions to use on the SQL join when eagerly loading
129 # the association via eager_graph, instead of the default conditions specified by the
130 # foreign/primary keys. This option causes the :graph_conditions option to be ignored.
131 # - :graph_select - A column or array of columns to select from the associated table
132 # when eagerly loading the association via eager_graph. Defaults to all
133 # columns in the associated table.
134 # - :limit - Limit the number of records to the provided value. Use
135 # an array with two arguments for the value to specify a limit and offset.
136 # - :order - the column(s) by which to order the association dataset. Can be a
137 # singular column or an array.
138 # - :read_only - Do not add a setter method (for many_to_one or one_to_many with :one_to_one),
139 # or add_/remove_/remove_all_ methods (for one_to_many, many_to_many)
140 # - :reciprocal - the symbol name of the reciprocal association,
141 # if it exists. By default, sequel will try to determine it by looking at the
142 # associated model's assocations for a association that matches
143 # the current association's key(s). Set to nil to not use a reciprocal.
144 # - :select - the attributes to select. Defaults to the associated class's
145 # table_name.*, which means it doesn't include the attributes from the
146 # join table in a many_to_many association. If you want to include the join table attributes, you can
147 # use this option, but beware that the join table attributes can clash with
148 # attributes from the model table, so you should alias any attributes that have
149 # the same name in both the join table and the associated table.
150 # * :many_to_one:
151 # - :key - foreign_key in current model's table that references
152 # associated model's primary key, as a symbol. Defaults to :"#{name}_id".
153 # * :one_to_many:
154 # - :key - foreign key in associated model's table that references
155 # current model's primary key, as a symbol. Defaults to
156 # :"#{self.name.underscore}_id".
157 # - :one_to_one: Create a getter and setter similar to those of many_to_one
158 # associations. The getter returns a singular matching record, or raises an
159 # error if multiple records match. The setter updates the record given and removes
160 # associations with all other records. When this option is used, the other
161 # association methods usually added are either removed or made private,
162 # so using this is similar to using many_to_one, in terms of the methods
163 # it adds, the main difference is that the foreign key is in the associated
164 # table instead of the current table.
165 # * :many_to_many:
166 # - :join_table - name of table that includes the foreign keys to both
167 # the current model and the associated model, as a symbol. Defaults to the name
168 # of current model and name of associated model, pluralized,
169 # underscored, sorted, and joined with '_'.
170 # - :left_key - foreign key in join table that points to current model's
171 # primary key, as a symbol. Defaults to :"#{self.name.underscore}_id".
172 # - :right_key - foreign key in join table that points to associated
173 # model's primary key, as a symbol. Defaults to Defaults to :"#{name.to_s.singularize}_id".
174 # - :graph_join_table_block - The block to pass to join_table for
175 # the join table when eagerly loading the association via eager_graph.
176 # - :graph_join_table_conditions - The additional conditions to use on the SQL join for
177 # the join table when eagerly loading the association via eager_graph. Should be a hash
178 # or an array of all two pairs.
179 # - :graph_join_type - The type of SQL join to use for the join table when eagerly
180 # loading the association via eager_graph. Defaults to the :graph_join_type option or
181 # :left_outer.
182 # - :graph_join_table_only_conditions - The conditions to use on the SQL join for the join
183 # table when eagerly loading the association via eager_graph, instead of the default
184 # conditions specified by the foreign/primary keys. This option causes the
185 # :graph_join_table_conditions option to be ignored.
186 def associate(type, name, opts = {}, &block)
187 raise(Error, 'invalid association type') unless AssociationReflection::ASSOCIATION_TYPES.include?(type)
188 raise(Error, 'Model.associate name argument must be a symbol') unless Symbol === name
189
190 # merge early so we don't modify opts
191 opts = opts.merge(:type => type, :name => name, :block => block, :cache => true, :model => self)
192 opts = AssociationReflection.new.merge!(opts)
193 opts[:eager_block] = block unless opts.include?(:eager_block)
194 opts[:graph_join_type] ||= :left_outer
195 opts[:graph_conditions] = opts[:graph_conditions] ? opts[:graph_conditions].to_a : []
196 opts[:graph_select] = Array(opts[:graph_select]) if opts[:graph_select]
197 [:before_add, :before_remove, :after_add, :after_remove, :after_load, :extend].each do |cb_type|
198 opts[cb_type] = Array(opts[cb_type])
199 end
200
201 # find class
202 case opts[:class]
203 when String, Symbol
204 # Delete :class to allow late binding
205 opts[:class_name] ||= opts.delete(:class).to_s
206 when Class
207 opts[:class_name] ||= opts[:class].name
208 end
209
210 send(:"def_#{type}", opts)
211
212 # don't add to association_reflections until we are sure there are no errors
213 association_reflections[name] = opts
214 end
215
216 # The association reflection hash for the association of the given name.
217 def association_reflection(name)
218 association_reflections[name]
219 end
220
221 # Array of association name symbols
222 def associations
223 association_reflections.keys
224 end
225
226 # Shortcut for adding a one_to_many association, see associate
227 def one_to_many(*args, &block)
228 associate(:one_to_many, *args, &block)
229 end
230 alias_method :has_many, :one_to_many
231
232 # Shortcut for adding a many_to_one association, see associate
233 def many_to_one(*args, &block)
234 associate(:many_to_one, *args, &block)
235 end
236 alias_method :belongs_to, :many_to_one
237
238 # Shortcut for adding a many_to_many association, see associate
239 def many_to_many(*args, &block)
240 associate(:many_to_many, *args, &block)
241 end
242 alias_method :has_and_belongs_to_many, :many_to_many
243
244 private
245
246 # Hash storing the association reflections. Keys are association name
247 # symbols, values are association reflection hashes.
248 def association_reflections
249 @association_reflections ||= {}
250 end
251
252 # Add the add_ instance method
253 def def_add_method(opts)
254 class_def(opts.add_method){|o| add_associated_object(opts, o)}
255 end
256
257 # Adds association methods to the model for *_to_many associations.
258 def def_association_dataset_methods(opts)
259 # If a block is given, define a helper method for it, because it takes
260 # an argument. This is unnecessary in Ruby 1.9, as that has instance_exec.
261 if opts[:block]
262 class_def(opts.dataset_helper_method, &opts[:block])
263 private opts.dataset_helper_method
264 end
265 class_def(opts._dataset_method, &opts[:dataset])
266 private opts._dataset_method
267 class_def(opts.dataset_method){_dataset(opts)}
268 class_def(opts.association_method){|*reload| load_associated_objects(opts, reload[0])}
269 end
270
271 # Adds many_to_many association instance methods
272 def def_many_to_many(opts)
273 name = opts[:name]
274 model = self
275 left = (opts[:left_key] ||= opts.default_left_key)
276 right = (opts[:right_key] ||= opts.default_right_key)
277 opts[:class_name] ||= name.to_s.singularize.camelize
278 join_table = (opts[:join_table] ||= opts.default_join_table)
279 left_key_alias = opts[:left_key_alias] ||= :x_foreign_key_x
280 left_key_select = opts[:left_key_select] ||= left.qualify(join_table).as(opts[:left_key_alias])
281 opts[:graph_join_table_conditions] = opts[:graph_join_table_conditions] ? opts[:graph_join_table_conditions].to_a : []
282 opts[:graph_join_table_join_type] ||= opts[:graph_join_type]
283 opts[:dataset] ||= proc{opts.associated_class.inner_join(join_table, [[right, opts.associated_primary_key], [left, pk]])}
284 database = db
285
286 opts[:eager_loader] ||= proc do |key_hash, records, associations|
287 h = key_hash[model.primary_key]
288 records.each{|object| object.associations[name] = []}
289 model.eager_loading_dataset(opts, opts.associated_class.inner_join(join_table, [[right, opts.associated_primary_key], [left, h.keys]]), Array(opts.select) + Array(left_key_select), associations).all do |assoc_record|
290 next unless objects = h[assoc_record.values.delete(left_key_alias)]
291 objects.each{|object| object.associations[name].push(assoc_record)}
292 end
293 end
294
295 def_association_dataset_methods(opts)
296
297 return if opts[:read_only]
298
299 class_def(opts._add_method) do |o|
300 database.dataset.from(join_table).insert(left=>pk, right=>o.pk)
301 end
302 class_def(opts._remove_method) do |o|
303 database.dataset.from(join_table).filter([[left, pk], [right, o.pk]]).delete
304 end
305 class_def(opts._remove_all_method) do
306 database.dataset.from(join_table).filter(left=>pk).delete
307 end
308 private opts._add_method, opts._remove_method, opts._remove_all_method
309
310 def_add_method(opts)
311 def_remove_methods(opts)
312 end
313
314 # Adds many_to_one association instance methods
315 def def_many_to_one(opts)
316 name = opts[:name]
317 model = self
318 opts[:key] = opts.default_right_key unless opts.include?(:key)
319 key = opts[:key]
320 opts[:class_name] ||= name.to_s.camelize
321 opts[:dataset] ||= proc do
322 klass = opts.associated_class
323 klass.filter(opts.associated_primary_key.qualify(klass.table_name)=>send(key))
324 end
325 opts[:eager_loader] ||= proc do |key_hash, records, associations|
326 h = key_hash[key]
327 keys = h.keys
328 # Skip eager loading if no objects have a foreign key for this association
329 unless keys.empty?
330 # Default the cached association to nil, so any object that doesn't have it
331 # populated will have cached the negative lookup.
332 records.each{|object| object.associations[name] = nil}
333 model.eager_loading_dataset(opts, opts.associated_class.filter(opts.associated_primary_key.qualify(opts.associated_class.table_name)=>keys), opts.select, associations).all do |assoc_record|
334 next unless objects = h[assoc_record.pk]
335 objects.each{|object| object.associations[name] = assoc_record}
336 end
337 end
338 end
339
340 def_association_dataset_methods(opts)
341
342 return if opts[:read_only]
343
344 class_def(opts._setter_method){|o| send(:"#{key}=", (o.pk if o))}
345 private opts._setter_method
346
347 class_def(opts.setter_method) do |o|
348 raise(Sequel::Error, 'model object does not have a primary key') if o && !o.pk
349 old_val = send(opts.association_method)
350 return o if old_val == o
351 return if old_val and run_association_callbacks(opts, :before_remove, old_val) == false
352 return if o and run_association_callbacks(opts, :before_add, o) == false
353 send(opts._setter_method, o)
354 @associations[name] = o
355 remove_reciprocal_object(opts, old_val) if old_val
356 add_reciprocal_object(opts, o) if o
357 run_association_callbacks(opts, :after_add, o) if o
358 run_association_callbacks(opts, :after_remove, old_val) if old_val
359 o
360 end
361 end
362
363 # Adds one_to_many association instance methods
364 def def_one_to_many(opts)
365 name = opts[:name]
366 model = self
367 key = (opts[:key] ||= opts.default_left_key)
368 opts[:class_name] ||= name.to_s.singularize.camelize
369 opts[:dataset] ||= proc do
370 klass = opts.associated_class
371 klass.filter(key.qualify(klass.table_name) => pk)
372 end
373 opts[:eager_loader] ||= proc do |key_hash, records, associations|
374 h = key_hash[model.primary_key]
375 records.each{|object| object.associations[name] = []}
376 reciprocal = opts.reciprocal
377 model.eager_loading_dataset(opts, opts.associated_class.filter(key.qualify(opts.associated_class.table_name)=>h.keys), opts.select, associations).all do |assoc_record|
378 next unless objects = h[assoc_record[key]]
379 objects.each do |object|
380 object.associations[name].push(assoc_record)
381 assoc_record.associations[reciprocal] = object if reciprocal
382 end
383 end
384 end
385
386 def_association_dataset_methods(opts)
387
388 unless opts[:read_only]
389 class_def(opts._add_method) do |o|
390 o.send(:"#{key}=", pk)
391 o.save || raise(Sequel::Error, "invalid associated object, cannot save")
392 end
393 private opts._add_method
394 def_add_method(opts)
395
396 unless opts[:one_to_one]
397 class_def(opts._remove_method) do |o|
398 o.send(:"#{key}=", nil)
399 o.save || raise(Sequel::Error, "invalid associated object, cannot save")
400 end
401 class_def(opts._remove_all_method) do
402 opts.associated_class.filter(key=>pk).update(key=>nil)
403 end
404 private opts._remove_method, opts._remove_all_method
405 def_remove_methods(opts)
406 end
407 end
408 if opts[:one_to_one]
409 private opts.association_method, opts.dataset_method
410 n = name.to_s.singularize.to_sym
411 raise(Sequel::Error, "one_to_many association names should still be plural even when using the :one_to_one option") if n == name
412 class_def(n) do |*o|
413 objs = send(name, *o)
414 raise(Sequel::Error, "multiple values found for a one-to-one relationship") if objs.length > 1
415 objs.first
416 end
417 unless opts[:read_only]
418 private opts.add_method
419 class_def(:"#{n}=") do |o|
420 klass = opts.associated_class
421 model.db.transaction do
422 send(opts.add_method, o)
423 klass.filter(Sequel::SQL::BooleanExpression.new(:AND, {key=>pk}, ~{klass.primary_key=>o.pk}.sql_expr)).update(key=>nil)
424 end
425 end
426 end
427 end
428 end
429
430 # Add the remove_ and remove_all instance methods
431 def def_remove_methods(opts)
432 class_def(opts.remove_method){|o| remove_associated_object(opts, o)}
433 class_def(opts.remove_all_method){remove_all_associated_objects(opts)}
434 end
435 end
Generated using the rcov code coverage analysis tool for Ruby
version <IP_ADDRESS>.


The fumes of bleach and dried dye is heavy in the atmosphere. In the distance you hear voices, maybe not all of the workers are gone, therefore you decide to stay hidden and wait. When you are sure you are left alone you go upstairs using a metallic ladder. All the offices are on the 2nd floor, silent and dark, only a dim light enters through the windows signifying the end of the day.
• Search those rooms thoroughly.
You notice a flash light's light - probably the guard - and you know it's time to get out of there. • I need to clear a bit the situation, some people need to answer a few questions.


Before Change
def layer_op(self, subject_id, data):
metric_name = self.__class__.__name__
metric_value = self.metric(data["inferred"], data["output"])
results_dict = ResultsDictionary()
results_dict[("subject_id",)] = [{"subject_id":subject_id,
metric_name:metric_value}]
return results_dict
def metric(self, reg, ref):
Computes a scalar value for the metric
After Change
def layer_op(self, subject_id, data):
metric_name = self.__class__.__name__
metric_value = self.metric(data["inferred"], data["output"])
pdf = pd.DataFrame.from_records([{"subject_id":subject_id,
metric_name:metric_value}],
("subject_id",))
return ResultsDictionary(pdf)
def metric(self, reg, ref):
Computes a scalar value for the metric


Indexing in ArrayFire is a powerful but easy to abuse feature of the af::array class. This feature allows you to reference or copy subsections of a larger array and perform operations on only a subset of elements.
Indexing in ArrayFire can be performed using the parenthesis operator or one of the member functions of the af::array class. These functions allow you to reference one or a range of elements from the original array.
Here we will demonstrate some of the ways you can use indexing in ArrayFire and discuss ways to minimize the memory and performance impact of these operations.
Lets start by creating a new 4x4 matrix of floating point numbers:
ArrayFire is column-major so the resulting A array will look like this:
\[ \begin{bmatrix} 0 & 4 & 8 & 12 \\ 1 & 5 & 9 & 13 \\ 2 & 6 & 10 & 14 \\ 3 & 7 & 11 & 15 \end{bmatrix} \]
This is a two dimensional array so we can access the first element of this matrix by passing 0,0
into the parenthesis operator of the af::array.
\[ A(2, 3) = [ 14 ] \]
We can also access the array using linear indexing by passing in one value. Here we are accessing the fifth element of the array.
\[ A(5) = [ 5 ] \]
Indexing with negative values will access from the end of the array. For example, the value negative one and negative two(-2) will return the last and second to last element of the array, respectively. ArrayFire provides the end
alias for this which also allows you to index the last element of the array.
You can access regions of the array via the af::seq and af::span objects. The span objects allows you to select the entire set of elements across a particular dimension/axis of an array. For example, we can select the third column of the array by passing span as the first argument and 2 as the second argument to the parenthesis operator.
\[ A(span, 2) = \begin{bmatrix} 8 \\ 9 \\ 10 \\ 11 \end{bmatrix} \]
You can read that as saying that you want all values across the first dimension, but only from index 2 of the second dimension.
You can access the second row by passing (1, span) to the array
\[ A(1, span) = [ 1, 5, 9, 13 ] \]
You can use the af::seq (short for sequence) object to define a range when indexing. For example, if you want to get the first two columns, you can access the array by passing af::span for the first argument and af::seq(2) as the second argument.
\[ A(span, seq(2)) = \begin{bmatrix} 0 & 4 \\ 1 & 5 \\ 2 & 6 \\ 3 & 7 \end{bmatrix} \]
There are three constructors for af::seq.
The last constructor that can help create non-continuous ranges. For example, you can select the second and forth(last) rows by passing (seq(1, end, 2), span) to the indexing operator.
\[ A(seq(1, end, 2), span) = \begin{bmatrix} 1 & 5 & 9 & 13 \\ 3 & 7 & 11 & 15 \end{bmatrix} \]
You can also index using other af::array objects. ArrayFire performs a Cartesian product of the input arrays.
\[ A = \begin{bmatrix} 0 & 4 & 8 & 12 \\ 1 & 5 & 9 & 13 \\ 2 & 6 & 10 & 14 \\ 3 & 7 & 11 & 15 \end{bmatrix} \\ A( \begin{bmatrix} 2 \\ 1 \\ 3 \end{bmatrix} , \begin{bmatrix} 3 \\ 1 \\ 2 \end{bmatrix} ) = \begin{bmatrix} (2,3) & (2,1) & (2,2) \\ (1,3) & (1,1) & (1,2) \\ (3,3) & (3,1) & (3,2) \end{bmatrix} = \begin{bmatrix} 14 & 6 & 10 \\ 13 & 5 & 9 \\ 15 & 7 & 11 \end{bmatrix} \]
If you want to index an af::array using coordinate arrays, you can do that using the af::approx1 and af::approx2 functions.
\[ approx2(A, \begin{bmatrix} 2 \\ 1 \\ 3 \end{bmatrix} , \begin{bmatrix} 3 \\ 1 \\ 2 \end{bmatrix} ) = \begin{bmatrix} (2,3) \\ (1,1) \\ (3,2) \end{bmatrix} = \begin{bmatrix} 14 \\ 5 \\ 11 \end{bmatrix} \]
Boolean(b8) arrays can be used to index into another array. In this type of indexing the non-zero values will be selected by the boolean operation. If we want to select all values less than 5, we can pass a boolean expression into the parenthesis operator.
\[ out = \begin{bmatrix} 0 \\ 1 \\ 2 \\ 3 \\ 4 \end{bmatrix} \]
All ArrayFire indexing functions return af::array(technically its an array_proxy class) objects. These objects may be new arrays or they may reference the original array depending on the type of indexing that was performed on them.
The following code snippet shows some examples of indexing that will allocate new memory.
Notice that even though the copy3 array is referencing continuous memory in the original array, a new array is created because we used an array to index into the af::array.
An assignment on an af::array will replace the array with the result of the expression on the right hand side of the equal(=) operator. This means that the type and shape of the result can be different from the array on the left had side of the equal operator. Assignments will not update the array that was previously referenced through an indexing operation. Here is an example:
The ref
array is created by indexing into the data array. The initialized ref
array points to the data array and does not allocate memory when it is created. After the matmul call, the ref
array will not be pointing to the data array. The matmul call will not update the values of the data array.
You can update the contents of an af::array by assigning with the operator parenthesis. For example, if you wanted to change the third column of the A
array you can do that by assigning to A(span, 2)
.
\[ ref = \begin{bmatrix} 8 \\ 9 \\ 10 \\ 11 \end{bmatrix} A = \begin{bmatrix} 0 & 4 & 3.14 & 12 \\ 1 & 5 & 3.14 & 13 \\ 2 & 6 & 3.14 & 14 \\ 3 & 7 & 3.14 & 15 \end{bmatrix} \]
This will update only the array being modified. If there are arrays that are referring to this array because of an indexing operation, those values will remain unchanged.
Allocation will only be performed if there are other arrays referencing the data at the point of assignment. In the previous example, an allocation will be performed when assigning to the A
array because the ref
array is pointing to the original data. Here is another example demonstrating when an allocation will occur:
In this example, no allocation will take place because when the ref
object is created, it is pointing to A
's data. Once it goes out of scope, no data points to A
, therefore when the assignment takes place, the data is modified in place instead of being copied to a new address.
You can also assign to arrays using another af::arrays as an indexing array. This works in a similar way to the other types of assignment but care must be taken to assure that the indexes are unique. Non-unique indexes will result in a race condition which will cause non-deterministic values.
\[ idx = \begin{bmatrix} 4 \\ 3 \\ 4 \\ 0 \end{bmatrix} vals = \begin{bmatrix} 9 \\ 8 \\ 7 \\ 6 \end{bmatrix} \\ A = \begin{bmatrix} 6 & 9\ or\ 7 & 8 & 12 \\ 1 & 5 & 9 & 13 \\ 2 & 6 & 10 & 14 \\ 8 & 7 & 11 & 15 \end{bmatrix} \]
There are several member functions which allow you to index into an af::array. These functions have similar functionality but may be easier to parse for some.
See Assignment & Indexing operation on arrays for the full listing.
You can set values in an array:
Use one array to reference into another.


Recent Works
Project Komodo: Open-Source, Higher Education-Focused Social VR Platform
November 2019 - Ongoing.
About the Project
For the IDEA Lab Developer Studio at Grainger Engineering Library, I helped create and maintain an open-source, multiplayer, WebXR VR platform designed for education.
More about Project Komodo Modules >>
Award, Paper, and Presentations
ALA RUSA Best Emerging Technology Application (BETA Award)
2021 Winner
With Elisandro Cabada, William H. Mischo, David Tamayo, and Robert Wallace.
Research Paper
Tamayo, David. (2021). Using web-based authoring tools to overcome the third barrier to classroom technological integration: design thinking. 10.13140/RG.2.2.16154.57287.
Immersive Learning Research Network 2020 (iLRN)
Immersive Learning Showcase
Presented with the Komodo Team
Screenshot featured by Kent Bye
Beyond Zoom by Dartmouth + UPenn
Bell, J. (n.d.). Beyond Zoom: XR For Teaching and Research in the COVID-19 Era Session 3. YouTube. Retrieved March 25, 2022, from https://www.youtube.com/watch?v=FtbTtj-5Sds?t=600s (10m 0s)
Presented with Elisandro Cabada
Coalition for Networked Information
Spring 2021 Virtual Membership Meeting
Project Komodo: Catalyzing Browser-Based Virtual Reality Teaching and Learning in the Library (Vimeo) Presented by Elisandro Cabada and William H. Mischo
University of Illinois “Forever Leading” Newsletter
Virtual reality provides new tool for fashion design class
Daily Illini Article
Finn, A. (2022, March 24). UI advancements change the purpose of virtual reality. The Daily Illini. Retrieved March 25, 2022, from https://dailyillini.com/life_and_culture-stories/2022/03/09/virtual-reality-uiuc/
ALA RUSA Podcast
(Guest on upcoming podcast episode as of 3/25/22)
With Elisandro Cabada
My Contributions
The four best descriptions of my work are software project management, software testing, virtual reality development, and web development. My role never cleanly fit into any of these categories, and I’d switch hats as the team needed. I’m comfortable continuing to do so, but I enjoy hands-on making — writing features, fixing bugs, refactoring code, designing interfaces, making 3D models — the most.
For software project management, I co-designed features that would become part of our core product or forks of the core product, with two instructors and one PhD student. I would share the results of our brainstorming, user story mapping, status updates, and discussion with the team, and also lead Scrum ceremonies to order and update the work, all using online tools like Miro and GitHub. I co-presented the project at conferences and as part of a podcast, contributed to our own grant applications, created training and instructions for using the platform in a classroom, and continued to explain the project from technical and non-technical perspectives to any potential partners. As a result, two instructors were able to use our product across three semesters, with an average session time of 90 minutes, with up to eight students per session, and we were able to contribute some support to ongoing PhD research.
For software testing, I helped our project status evolve from experimental prototype to classroom product by introducing and regularly updating WebXR VR manual test plans, web automated testing, internal VR test sessions, and a public VR test session, with everything done remotely. We worked with the Oculus Quest 1 & 2 and the Rift S. I created templates for issues and pull requests modeled off of typical DevOps processes, and helped adapt the Git branching strategy to fit a shifting team makeup. I subscribed to the idea of refactoring as we’d implement new features or fix existing ones. As a result of my work, we specified many tests, caught many edge cases, refactored many lines of code, and had no unrecoverable classroom sessions.
For virtual reality and 3D development, I modeled, textured, and lit two new virtual environments, two existing virtual environments, 3D UI elements, and 3D models for the classroom activities. I remixed an existing model to make our avatar. (It’s not fully inclusive by nature, but I’m proud of its simple likeability in place of any future, customizable avatar system.) My strongest feature contributions included a 3D/VR menu redesign, a VR height calibration feature, and an interface for our SocketIO-based relay client. I pair-programmed larger features including Tilt Brush Toolkit integration, support for multiple third-party 3D model runtime import tools, and 6DOF-controller based scaling gestures (both for objects and the world). Sometimes I’d contribute to prototyping features. I drove the project in a direction of more visual and interactive consistency, higher-fidelity 6DOF-controller interactions, and higher polish.
For web development, my strongest contributions included fixing bugs on our SocketIO relay server, refactoring the server into modules, creating an admin monitoring page for the relay server, and using ThreeJS to create a utility that could turn uploaded images into rectangular prisms in the GLB (v2) format. I became adept enough to independently maintain our Linux server. I wrote and presented a guide for deploying our platform on any Linux server (or AWS EC2). Through frequent interface and architecture sketches, I helped team members design and implement features. Our platform grew more robust in our admin panel features and our experimental immersive capture system under my guidance.
I had some experience with team supervision, but while I deeply appreciated my team members (and what we were able to accomplish), I am not seeking management opportunities at this time. If you’re curious, I researched accessibility, privacy, and security training resources; provided training for course assistance, virtual reality development, and web development; and helped coordinate studio resources, schedules, all-hands meetings, and one-on-one meetings. Our team makeup shifted with each semester, so I periodically revised our processes to fit the people.
Collaborators
I highlighted my best accomplishments above, by I owe a lot of gratitude for people who taught or inspired me on this project.
Thanks to the many fantastic team members and fellow staff I got to work with:
Yifan Bao • Xianzhuo (Patrick) Cao • Yi-Shiuan Ho • Jiayu (Jonathan) Lin • Mihir Joshi • Welisa Lewis • Nishi Mehta • Dennis Piehl • Xiaohan Yin • Wendy Zhu
I appreciate the vision, attention to detail, and risk-taking innovation I saw firsthand from our instructor and researcher partners: PhD candidate James Planey, Dr. Andre Schleife, and Professor Chiara Vincenzi.
Thanks to David Tamayo for innovating in the project and sharing tons of knowledge, to William Mischo for unwavering support in the face of many challenges, to Elisandro Cabada for being the number one champion of the project, and to Robert Wallace for architecting the platform and practically mentoring me on software development.
Technologies, Tools, and Processes
Development Technologies
General
Bash • Docker • Git • Linux • SFTP • SSH
Web Platform
CSS • Express • Glitch • HTML • JS • MochaJS • MySQL • Nginx • NodeJS • NPM • Python • REST API • SocketIO • ShouldJS • SSL Certificates • Traefik • Twilio • VueJS • Vuetify
WebXR VR Client
Blender • C# • JSLib • OpenUPM • SocketIO • Tilt Brush Toolkit • Unity (WebGL) • WebXR VR
WebXR VR Browsers
Google Chrome • Mozilla Firefox • Mozilla Firefox Reality (Quest) • Mozilla Firefox Reality (Viveport) • Oculus Browser
WebXR VR Devices
Oculus Quest 1 • Oculus Rift S
Other Development Technologies
AWS S3 • ESLint • Localtunnel • Roslynator • unity-webxr-export (De-Panther)
Tools
Gather • Gitflow • GitHub Issues • GitHub Pull Requests • GitLab • Miro • Teamflow • Teams
Other Tools
Icosa Gallery • OBS • Ovito • Tilt Brush (Open Brush) • Vectr • VMD
Processes
CI/CD • DevOps • Gantt Charts


|
Finite Geometry Notes
|
|
Construction
principle [1]:
number right --> everything right Given a small, highly symmetrical geometry with n points, look for the same number of points arranged into a highly symmetrical spatial object. Try to merge the two structures such that the symmetries of the spatial object translate into symmetries of the geometry. |
|
Construction
principle [2]:
Given a subset geometry on... n points, try to translate automorphisms
of symmetrical arrangements of n points in the plane or in space into
"good" models of the geometry which exhibit as many of these
automorphisms as possible. subset geometries |
|
|
|
Construction
principle [3]:
Try to extend "good" models of subgeometries of a given geometry to a
"good" model of the full geometry. subgeometry --> full geometry |
|
|
|
Construction
principle [4]:
Try to find models of subgeometries of a given geometry "right in the
middle" of a good model of the geometry. geometry --> subgeometry |
|
Commentary
by S. H. Cullinane:
See The Diamond Theorem, Diamond Theory, and Solomon's Cube. The proofs underlying properties described in these notes involve extending symmetries of centrally located 2x2 or 2x2x2 subgeometries to their larger 4x4 or 4x4x4 supergeometries. |
References [by Polster]
[1] A. Beutelspacher.
[2] A. Beutelspacher. A defense of the honour of an unjustly
neglected little geometry or a combinatorial approach to the projective
plane of order five. J. Geom.
[3] D.R. Hughes and F.C. Piper. Design
Theory. Cambridge University Press, 1985.
[4] R.H. Jeurissen. Special sets of lines in PG(3,2). Linear Algebra Appl.
[5] S.E. Payne. Finite generalized
quadrangles: a survey.
Proceedings of the International Conference on Projective Planes (Washington State Univ.,
Pullman, Wash., 1973), pp. 219-261. Washington State Univ. Press,
Pullman,
Wash., 1973.
[6] S.E. Payne and J.A. Thas. Finite
generalized quadrangles,
Research Notes in Math. 110.
Pitman, Boston, 1984.
[7] B. Polster. A geometrical
picture book. Universitext series, Springer-Verlag, to appear.
Page created December 2, 2004.


"LEGION "a regiment of the Roman army, the number of men composing which differed at different times. It originally consisted of three thousand men, but in the time of Christ consisted of six thousand, exclusive of horsemen, who were in number a tenth of the foot-men. The word is used(Matthew 26:53; Mark 5:9) to express simply a great multitude.
"LEGION "a regiment of the Roman army, the number of men composing which differed at different times. It originally consisted of three thousand men, but in the time of Christ consisted of six thousand, exclusive of horsemen, who were in number a tenth of the foot-men. The word is used(Matthew 26:53; Mark 5:9) to express simply a great multitude.


|
DotNetBrowser
1.16
|
Classes | |
| class | BrowserEventArgs |
| The base class for classes providing event information for all Browser events. More... | |
| class | ConsoleEventArgs |
| Provides event information for event that indicates that the message was added to the console. More... | |
| class | DisposeEventArgs |
| Provides event information for event that indicates that browser instance disposed. More... | |
| class | DownloadEventArgs |
| Provides event information for event that indicates that download is updated. More... | |
| class | DragDropEventArgs |
| Provides event information that indicates that DragDrop event has started. More... | |
| class | FailLoadingEventArgs |
| Provides event information for event that indicates that frame loading process has been failed. More... | |
| class | FinishLoadingEventArgs |
| Provides event information for event that indicates that frame loading process has been finished. More... | |
| class | FrameLoadEventArgs |
| Provides event information for event that indicates that frame with a document is loaded. More... | |
| class | GestureEventArgs |
| Provides event information that indicates that user has made a gesture interaction GestureType with device SourceDevice. More... | |
| class | HandledGestureEventArgs |
| Allows to handle an event that indicates that user has made a gesture interaction GestureType with device SourceDevice. More... | |
| class | LoadEventArgs |
| Provides event information for event that indicates that main frame with a document is loaded. More... | |
| class | NotificationEventArgs |
| Provides event information for event that browser performed some notification action. More... | |
| class | OnRedrawEventArgs |
| Provides event information for event that indicates that content of loaded web page in the browser view has been rendered as image. More... | |
| class | OnRepaintEventArgs |
| Provides event information for event that indicates that content of loaded web page in the browser view has been repainted. More... | |
| class | PrintJobEventArgs |
| Provides event information for event that indicate printing job status More... | |
| class | ProvisionalLoadingArgs |
| Provides event information for event that indicates that provisional load for a specified frame was successfully committed. More... | |
| class | RenderEventArgs |
| Provides event information for event that indicates that the render process is gone or created. More... | |
| class | ScriptContextEventArgs |
| Provides event information for event that indicates that JavaScript context has been created or destroyed More... | |
| class | SpellCheckCompletedEventArgs |
| Provides event information for event that indicates that the spell check process is completed. More... | |
| class | SpellCheckResult |
| Contains information about specific mistake in the examined text. More... | |
| class | StartLoadingArgs |
| Provides event information for event that indicates that frame loading process has been started. More... | |
| class | StatusEventArgs |
| Provides event information for event that indicates that the status has been changed. More... | |
| class | TitleEventArgs |
| Provides event information for event that indicates that the title of a document in main frame has been changed. More... | |
| class | ZoomEventArgs |
| Arguments fpr an event that indicates that zoom level for a specific URL has been changed. More... | |
Functions | |
| delegate void | ConsoleMessageHandler (object sender, ConsoleEventArgs e) |
| Represents the method that will handle event that indicates that the message was added to the console. More... | |
| delegate void | DisposeEventHandler (object sender, DisposeEventArgs e) |
| Represents the method that will handle event that indicates that browser instance disposed. More... | |
| delegate void | DownloadEventHandler (object sender, DownloadEventArgs e) |
| Represents the method that will handle event that indicates when download updates its state. More... | |
| delegate void | DragDropHandler (object sender, DragDropEventArgs e) |
| Represents the method that will handle event that indicates that DragDrop event has started. More... | |
| delegate void | FailLoadingFrameHandler (object sender, FailLoadingEventArgs e) |
| Represents the method that will handle event that indicates that frame loading process has been failed. More... | |
| delegate void | FinishLoadingFrameHandler (object sender, FinishLoadingEventArgs e) |
| Represents the method that will handle event that indicates that frame loading process has been finished. More... | |
| delegate void | DocumentLoadedInFrameHandler (object sender, FrameLoadEventArgs e) |
| Represents the method that will handle event that indicates that frame with a document is loaded. More... | |
| delegate void | GestureEventHandler (object sender, GestureEventArgs e) |
| Represents the method that will handle event that indicates that user has made a gesture interaction GestureType with device SourceDevice. More... | |
| delegate void | HandledGestureEventHandler (object sender, HandledGestureEventArgs e) |
| Represents the method that will handle event that indicates that user has made a gesture interaction GestureType with device SourceDevice and provides an ability to discard performed interaction. More... | |
| delegate void | DocumentLoadedInMainFrameHandler (object sender, LoadEventArgs e) |
| Represents the method that will handle event that indicates that main frame with a document is loaded. More... | |
| delegate void | NotificationOnCloseHandler (NotificationEventArgs e) |
| Represents the method that will handle event is being invoked when browser informs that notification should be closed. Notification can be closed in different ways: 1. Using the Notification.Close() method. 2. From JavaScript via Notification.close() JS function. More... | |
| delegate void | OnRedrawEventHandler (object sender, OnRedrawEventArgs e) |
| Represents the method that will handle event that indicates when content of loaded web page in the browser view has been rendered as image. More... | |
| delegate void | OnRepaintEventHandler (object sender, OnRepaintEventArgs e) |
| Represents the method that will handle event that indicates when content of loaded web page in the browser view has been repainted. More... | |
| delegate void | PrintJobEventHandler (object sender, PrintJobEventArgs e) |
| Represents the method that will handle event that indicates when printing job updates its state. More... | |
| delegate void | ProvisionalLoadingFrameHandler (object sender, ProvisionalLoadingArgs e) |
| Represents the method that will handle event that indicates that provisional load for a specified frame was successfully committed. More... | |
| delegate void | RenderCreatedHandler (object sender, RenderEventArgs e) |
| Represents the method that will handle event that indicates that the render process is gone or created. More... | |
| delegate void | ScriptContextCreatedHandler (object sender, ScriptContextEventArgs e) |
| Represents the method that will handle event that indicates that JavaScript context has been created. More... | |
| delegate void | ScriptContextDestroyedHandler (object sender, ScriptContextEventArgs e) |
| Represents the method that will handle event that indicates that JavaScript context has been destroyed. More... | |
| delegate void | SpellCheckCompletedHandler (object sender, SpellCheckCompletedEventArgs e) |
| Represents the method that will handle event that indicates that the spell check process is completed. More... | |
| delegate void | StartLoadingFrameHandler (object sender, StartLoadingArgs e) |
| Represents the method that will handle event that indicates that frame loading process has been started. More... | |
| delegate void | StatusEventHandler (object sender, StatusEventArgs e) |
| Represents the method that will handle event that indicates that the status has been changed. More... | |
| delegate void | TitleChangedHandler (object sender, TitleEventArgs e) |
| Represents the method that will handle event that indicates that the title of a document in main frame has been changed. More... | |
| delegate void | ZoomChangedHandler (object sender, ZoomEventArgs e) |
| Represents the method that will handle event that indicates that the zoom of a document in main frame has been changed. More... | |
|
strong |
The list of network errors.
| Enumerator | |
|---|---|
| UNDEFINED |
Undefined |
| IO_PENDING |
An asynchronous IO operation is not yet complete. This usually does not indicate a fatal error. Typically this error will be generated as a notification to wait for some external notification that the IO operation finally completed. |
| FAILED |
A generic failure occurred. |
| ABORTED |
An operation was aborted ( due to user action). |
| INVALID_ARGUMENT |
An argument to the function is incorrect. |
| INVALID_HANDLE |
The handle or file descriptor is invalid. |
| FILE_NOT_FOUND |
The file or directory cannot be found. |
| TIMED_OUT |
An operation timed out. |
| FILE_TOO_BIG |
The file is too large. |
| UNEXPECTED |
An unexpected error. This may be caused by a programming mistake or an invalid assumption. |
| ACCESS_DENIED |
Permission to access a resource, other than the network, was denied. |
| NOT_IMPLEMENTED |
The operation failed because of unimplemented functionality. |
| INSUFFICIENT_RESOURCES |
There were not enough resources to complete the operation. |
| OUT_OF_MEMORY |
Memory allocation failed. |
| UPLOAD_FILE_CHANGED |
The file upload failed because the file's modification time was different from the expectation. |
| SOCKET_NOT_CONNECTED |
The socket is not connected. |
| FILE_EXISTS |
The file already exists. |
| FILE_PATH_TOO_LONG |
The path or file name is too long. |
| FILE_NO_SPACE |
Not enough room left on the disk. |
| FILE_VIRUS_INFECTED |
The file has a virus. |
| BLOCKED_BY_CLIENT |
The client chose to block the request. |
| NETWORK_CHANGED |
The network changed. |
| BLOCKED_BY_ADMINISTRATOR |
The request was blocked by the URL blacklist configured by the domain administrator. |
| SOCKET_IS_CONNECTED |
The socket is already connected. |
| CONNECTION_CLOSED |
A connection was closed = corresponding to a TCP FIN. |
| CONNECTION_RESET |
A connection was reset = corresponding to a TCP RST. |
| CONNECTION_REFUSED |
A connection attempt was refused. |
| CONNECTION_ABORTED |
A connection timed out as a result of not receiving an ACK for data sent. This can include a FIN packet that did not get ACK'd. |
| CONNECTION_FAILED |
A connection attempt failed. |
| NAME_NOT_RESOLVED |
The host name could not be resolved. |
| INTERNET_DISCONNECTED |
The Internet connection has been lost. |
| SSL_PROTOCOL_ERROR |
An SSL protocol error occurred. |
| ADDRESS_INVALID |
The IP address or port number is invalid = e.g., cannot connect to the IP address 0 or the port 0. |
| ADDRESS_UNREACHABLE |
The IP address is unreachable. This usually means that there is no route to the specified host or network. |
| SSL_CLIENT_AUTH_CERT_NEEDED |
The server requested a client certificate for SSL client authentication. |
| TUNNEL_CONNECTION_FAILED |
A tunnel connection through the proxy could not be established. |
| NO_SSL_VERSIONS_ENABLED |
No SSL protocol versions are enabled. |
| SSL_VERSION_OR_CIPHER_MISMATCH |
The client and server don't support a common SSL protocol version or cipher suite. |
| SSL_RENEGOTIATION_REQUESTED |
The server requested a renegotiation = rehandshake,. |
| PROXY_AUTH_UNSUPPORTED |
The proxy requested authentication = for tunnel establishment, with an unsupported method. |
| CERT_ERROR_IN_SSL_RENEGOTIATION |
During SSL renegotiation = rehandshake,, the server sent a certificate with an error. Note: this error is not in the -2xx range so that it won't be handled as a certificate error. |
| BAD_SSL_CLIENT_AUTH_CERT |
The SSL handshake failed because of a bad or missing client certificate. |
| CONNECTION_TIMED_OUT |
A connection attempt timed out. |
| HOST_RESOLVER_QUEUE_TOO_LARGE |
There are too many pending DNS resolves, so a request in the queue was aborted. |
| SOCKS_CONNECTION_FAILED |
Failed establishing a connection to the SOCKS proxy server for a target host. |
| SOCKS_CONNECTION_HOST_UNREACHABLE |
The SOCKS proxy server failed establishing connection to the target host because that host is unreachable. |
| NPN_NEGOTIATION_FAILED |
The request to negotiate an alternate protocol failed. |
| SSL_NO_RENEGOTIATION |
The peer sent an SSL no_renegotiation alert message. |
| WINSOCK_UNEXPECTED_WRITTEN_BYTES |
Winsock sometimes reports more data written than passed. This is probably due to a broken LSP. |
| SSL_DECOMPRESSION_FAILURE_ALERT |
An SSL peer sent us a fatal decompression_failure alert. This typically occurs when a peer selects DEFLATE compression in the mistaken belief that it supports it. |
| SSL_BAD_RECORD_MAC_ALERT |
An SSL peer sent us a fatal bad_record_mac alert. This has been observed from servers with buggy DEFLATE support. |
| PROXY_AUTH_REQUESTED |
The proxy requested authentication = for tunnel establishment. |
| SSL_UNSAFE_NEGOTIATION |
A known TLS strict server didn't offer the renegotiation extension. |
| SSL_WEAK_SERVER_EPHEMERAL_DH_KEY |
The SSL server attempted to use a weak ephemeral Diffie-Hellman key. |
| PROXY_CONNECTION_FAILED |
Could not create a connection to the proxy server. An error occurred either in resolving its name, or in connecting a socket to it. Note that this does NOT include failures during the actual "CONNECT" method of an HTTP proxy. |
| MANDATORY_PROXY_CONFIGURATION_FAILED |
A mandatory proxy configuration could not be used. Currently this means that a mandatory PAC script could not be fetched, parsed or executed. |
| PRECONNECT_MAX_SOCKET_LIMIT |
We've hit the max socket limit for the socket pool while preconnecting. We don't bother trying to preconnect more sockets. |
| SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED |
The permission to use the SSL client certificate's private key was denied. |
| SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY |
The SSL client certificate has no private key. |
| PROXY_CERTIFICATE_INVALID |
The certificate presented by the HTTPS Proxy was invalid. |
| NAME_RESOLUTION_FAILED |
An error occurred when trying to do a name resolution = DNS,. |
| NETWORK_ACCESS_DENIED |
Permission to access the network was denied. This is used to distinguish errors that were most likely caused by a firewall from other access denied errors. See also ERR_ACCESS_DENIED. |
| TEMPORARILY_THROTTLED |
The request throttler module cancelled this request to avoid DDOS. |
| HTTPS_PROXY_TUNNEL_RESPONSE |
A request to create an SSL tunnel connection through the HTTPS proxy received a non-200 = OK, and non-407 = Proxy Auth, response. The response body might include a description of why the request failed. |
| SSL_CLIENT_AUTH_SIGNATURE_FAILED |
We were unable to sign the CertificateVerify data of an SSL client auth handshake with the client certificate's private key. Possible causes for this include the user implicitly or explicitly denying access to the private key, the private key may not be valid for signing, the key may be relying on a cached handle which is no longer valid, or the CSP won't allow arbitrary data to be signed. |
| MSG_TOO_BIG |
The message was too large for the transport. = for example a UDP message which exceeds size threshold,. |
| SPDY_SESSION_ALREADY_EXISTS |
A SPDY session already exists, and should be used instead of this connection. |
| WS_PROTOCOL_ERROR |
Websocket protocol error. Indicates that we are terminating the connection due to a malformed frame or other protocol violation. |
| PROTOCOL_SWITCHED |
Connection was aborted for switching to another protocol. WebSocket abort SocketStream connection when alternate protocol is found. |
| ADDRESS_IN_USE |
Returned when attempting to bind an address that is already in use. |
| SSL_HANDSHAKE_NOT_COMPLETED |
An operation failed because the SSL handshake has not completed. |
| SSL_BAD_PEER_PUBLIC_KEY |
SSL peer's public key is invalid. |
| SSL_PINNED_KEY_NOT_IN_CERT_CHAIN |
The certificate didn't match the built-in public key pins for the host name. The pins are set in net/http/transport_security_state.cc and require that one of a set of public keys exist on the path from the leaf to the root. |
| CLIENT_AUTH_CERT_TYPE_UNSUPPORTED |
Server request for client certificate did not contain any types we support. |
| ORIGIN_BOUND_CERT_GENERATION_TYPE_MISMATCH |
Server requested one type of cert, then requested a different type while the first was still being generated. |
| CERT_COMMON_NAME_INVALID |
The server responded with a certificate whose common name did not match the host name. This could mean:
|
| CERT_DATE_INVALID |
The server responded with a certificate that, by our clock, appears to either not yet be valid or to have expired. This could mean:
|
| CERT_AUTHORITY_INVALID |
The server responded with a certificate that is signed by an authority we don't trust. The could mean:
|
| CERT_CONTAINS_ERRORS |
The server responded with a certificate that contains errors. This error is not recoverable. MSDN describes this error as follows: "The SSL certificate contains errors." NOTE: It's unclear how this differs from ERR_CERT_INVALID. For consistency, use that code instead of this one from now on. |
| CERT_NO_REVOCATION_MECHANISM |
The certificate has no mechanism for determining if it is revoked. In effect, this certificate cannot be revoked. |
| CERT_UNABLE_TO_CHECK_REVOCATION |
Revocation information for the security certificate for this site is not available. This could mean:
|
| CERT_REVOKED |
The server responded with a certificate has been revoked. We have the capability to ignore this error, but it is probably not the thing to do. |
| CERT_INVALID |
The server responded with a certificate that is invalid. This error is not recoverable. MSDN describes this error as follows: "The SSL certificate is invalid." |
| CERT_WEAK_SIGNATURE_ALGORITHM |
The server responded with a certificate that is signed using a weak signature algorithm. |
| CERT_NON_UNIQUE_NAME |
The host name specified in the certificate is not unique. |
| CERT_WEAK_KEY |
The server responded with a certificate that contains a weak key = e.g. a too-small RSA key. |
| CERT_END |
The value immediately past the last certificate error code. |
| INVALID_URL |
The URL is invalid. |
| DISALLOWED_URL_SCHEME |
The scheme of the URL is disallowed. |
| UNKNOWN_URL_SCHEME |
The scheme of the URL is unknown. |
| TOO_MANY_REDIRECTS |
Attempting to load an URL resulted in too many redirects. |
| UNSAFE_REDIRECT |
Attempting to load an URL resulted in an unsafe redirect = e.g., a redirect to file:// is considered unsafe. |
| UNSAFE_PORT |
Attempting to load an URL with an unsafe port number. These are port numbers that correspond to services, which are not robust to spurious input that may be constructed as a result of an allowed web construct = e.g., HTTP looks a lot like SMTP, so form submission to port 25 is denied,. |
| INVALID_RESPONSE |
The server's response was invalid. |
| INVALID_CHUNKED_ENCODING |
Error in chunked transfer encoding. |
| METHOD_NOT_SUPPORTED |
The server did not support the request method. |
| UNEXPECTED_PROXY_AUTH |
The response was 407 = Proxy Authentication Required,, yet we did not send the request to a proxy. |
| EMPTY_RESPONSE |
The server closed the connection without sending any data. |
| RESPONSE_HEADERS_TOO_BIG |
The headers section of the response is too large. |
| PAC_STATUS_NOT_OK |
The PAC requested by HTTP did not have a valid status code = non-200. |
| PAC_SCRIPT_FAILED |
The evaluation of the PAC script failed. |
| REQUEST_RANGE_NOT_SATISFIABLE |
The response was 416 = Requested range not satisfiable, and the server cannot satisfy the range requested. |
| MALFORMED_IDENTITY |
The identity used for authentication is invalid. |
| CONTENT_DECODING_FAILED |
Content decoding of the response body failed. |
| NETWORK_IO_SUSPENDED |
An operation could not be completed because all network IO is suspended. |
| SYN_REPLY_NOT_RECEIVED |
FLIP data received without receiving a SYN_REPLY on the stream. |
| ENCODING_CONVERSION_FAILED |
Converting the response to target encoding failed. |
| UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT |
The server sent an FTP directory listing in a format we do not understand. |
| INVALID_SPDY_STREAM |
Attempted use of an unknown SPDY stream id. |
| NO_SUPPORTED_PROXIES |
There are no supported proxies in the provided list. |
| SPDY_PROTOCOL_ERROR |
There is a SPDY protocol error. |
| INVALID_AUTH_CREDENTIALS |
Credentials could not be established during HTTP Authentication. |
| UNSUPPORTED_AUTH_SCHEME |
An HTTP Authentication scheme was tried which is not supported on this machine. |
| ENCODING_DETECTION_FAILED |
Detecting the encoding of the response failed. |
| MISSING_AUTH_CREDENTIALS |
= GSSAPI, No Kerberos credentials were available during HTTP Authentication. |
| UNEXPECTED_SECURITY_LIBRARY_STATUS |
An unexpected, but documented, SSPI or GSSAPI status code was returned. |
| MISCONFIGURED_AUTH_ENVIRONMENT |
The environment was not set up correctly for authentication = for example, no KDC could be found or the principal is unknown. |
| UNDOCUMENTED_SECURITY_LIBRARY_STATUS |
An undocumented SSPI or GSSAPI status code was returned. |
| RESPONSE_BODY_TOO_BIG_TO_DRAIN |
The HTTP response was too big to drain. |
| RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH |
The HTTP response contained multiple distinct Content-Length headers. |
| INCOMPLETE_SPDY_HEADERS |
SPDY Headers have been received, but not all of them - status or version headers are missing, so we're expecting additional frames to complete them. |
| PAC_NOT_IN_DHCP |
No PAC URL configuration could be retrieved from DHCP. This can indicate either a failure to retrieve the DHCP configuration, or that there was no PAC URL configured in DHCP. |
| RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION |
The HTTP response contained multiple Content-Disposition headers. |
| RESPONSE_HEADERS_MULTIPLE_LOCATION |
The HTTP response contained multiple Location headers. |
| SPDY_SERVER_REFUSED_STREAM |
SPDY server refused the stream. Client should retry. This should never be a user-visible error. |
| SPDY_PING_FAILED |
SPDY server didn't respond to the PING message. |
| PIPELINE_EVICTION |
The request couldn't be completed on an HTTP pipeline. Client should retry. |
| CONTENT_LENGTH_MISMATCH |
The HTTP response body transferred fewer bytes than were advertised by the Content-Length header when the connection is closed. |
| INCOMPLETE_CHUNKED_ENCODING |
The HTTP response body is transferred with Chunked-Encoding, but the terminating zero-length chunk was never sent when the connection is closed. |
| QUIC_PROTOCOL_ERROR |
There is a QUIC protocol error. |
| HEADERS_TRUNCATED |
The HTTP headers were truncated by an EOF. |
| CACHE_MISS |
The cache does not have the requested entry. |
| CACHE_READ_FAILURE |
Unable to read from the disk cache. |
| CACHE_WRITE_FAILURE |
Unable to write to the disk cache. |
| CACHE_OPERATION_NOT_SUPPORTED |
The operation is not supported for this entry. |
| CACHE_OPEN_FAILURE |
The disk cache is unable to open this entry. |
| CACHE_CREATE_FAILURE |
The disk cache is unable to create this entry. |
| CACHE_RACE |
Multiple transactions are racing to create disk cache entries. This is an internal error returned from the HttpCache to the HttpCacheTransaction that tells the transaction to restart the entry-creation logic because the state of the cache has changed. |
| CACHE_CHECKSUM_READ_FAILURE |
The cache was unable to read a checksum record on an entry. This can be returned from attempts to read from the cache. It is an internal error, returned by the SimpleCache backend, but not by any URLRequest methods or members. |
| CACHE_CHECKSUM_MISMATCH |
The cache found an entry with an invalid checksum. This can be returned from attempts to read from the cache. It is an internal error, returned by the SimpleCache backend, but not by any URLRequest methods or members. |
| INSECURE_RESPONSE |
The server's response was insecure = e.g. there was a cert error,. |
| NO_PRIVATE_KEY_FOR_CERT |
The server responded to a <keygen> with a generated client cert that we don't have the matching private key for. |
| ADD_USER_CERT_FAILED |
An error adding to the OS certificate database = e.g. OS X Keychain,. |
| FTP_FAILED |
A generic error for failed FTP control connection command. If possible, please use or add a more specific error code. |
| FTP_SERVICE_UNAVAILABLE |
The server cannot fulfill the request at this point. This is a temporary error. FTP response code 421. |
| FTP_TRANSFER_ABORTED |
The server has aborted the transfer. FTP response code 426. |
| FTP_FILE_BUSY |
The file is busy, or some other temporary error condition on opening the file. FTP response code 450. |
| FTP_SYNTAX_ERROR |
Server rejected our command because of syntax errors. FTP response codes 500, 501. |
| FTP_COMMAND_NOT_SUPPORTED |
Server does not support the command we issued. FTP response codes 502, 504. |
| FTP_BAD_COMMAND_SEQUENCE |
Server rejected our command because we didn't issue the commands in right order. FTP response code 503. |
| PKCS12_IMPORT_BAD_PASSWORD |
PKCS #12 import failed due to incorrect password. |
| PKCS12_IMPORT_FAILED |
PKCS #12 import failed due to other error. |
| IMPORT_CA_CERT_NOT_CA |
CA import failed - not a CA cert. |
| IMPORT_CERT_ALREADY_EXISTS |
Import failed - certificate already exists in database. Note it's a little weird this is an error but reimporting a PKCS12 is ok = no-op,. That's how Mozilla does it, though. |
| IMPORT_CA_CERT_FAILED |
CA import failed due to some other error. |
| IMPORT_SERVER_CERT_FAILED |
Server certificate import failed due to some internal error. |
| PKCS12_IMPORT_INVALID_MAC |
PKCS #12 import failed due to invalid MAC. |
| PKCS12_IMPORT_INVALID_FILE |
PKCS #12 import failed due to invalid/corrupt file. |
| PKCS12_IMPORT_UNSUPPORTED |
PKCS #12 import failed due to unsupported features. |
| KEY_GENERATION_FAILED |
Key generation failed. |
| ORIGIN_BOUND_CERT_GENERATION_FAILED |
Server-bound certificate generation failed. |
| PRIVATE_KEY_EXPORT_FAILED |
Failure to export private key. |
| DNS_MALFORMED_RESPONSE |
DNS resolver received a malformed response. |
| DNS_SERVER_REQUIRES_TCP |
DNS server requires TCP |
| DNS_SERVER_FAILED |
DNS server failed. This error is returned for all of the following error conditions: 1 - Format error - The name server was unable to interpret the query. 2 - Server failure - The name server was unable to process this query due to a problem with the name server. 4 - Not Implemented - The name server does not support the requested kind of query. 5 - Refused - The name server refuses to perform the specified operation for policy reasons. |
| DNS_TIMED_OUT |
DNS transaction timed out. |
| DNS_CACHE_MISS |
The entry was not found in cache, for cache-only lookups. |
| DNS_SEARCH_EMPTY |
Suffix search list rules prevent resolution of the given host name. |
| DNS_SORT_ERROR |
Failed to sort addresses according to RFC3484. |
| delegate void DotNetBrowser.Events.ConsoleMessageHandler | ( | object | sender, |
| ConsoleEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that the message was added to the console.
| sender | The source of the event. |
| e | The event data ConsoleEventArgs. |
| delegate void DotNetBrowser.Events.DisposeEventHandler | ( | object | sender, |
| DisposeEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that browser instance disposed.
| sender | The source of the event. |
| e | The event data DisposeEventArgs. |
| delegate void DotNetBrowser.Events.DocumentLoadedInFrameHandler | ( | object | sender, |
| FrameLoadEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that frame with a document is loaded.
| sender | The source of the event. |
| e | The event data StartLoadingArgs. |
| delegate void DotNetBrowser.Events.DocumentLoadedInMainFrameHandler | ( | object | sender, |
| LoadEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that main frame with a document is loaded.
| sender | The source of the event. |
| e | The event data StartLoadingArgs. |
| delegate void DotNetBrowser.Events.DownloadEventHandler | ( | object | sender, |
| DownloadEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates when download updates its state.
| sender | The source of the event. |
| e | The event data DownloadEventArgs. |
| delegate void DotNetBrowser.Events.DragDropHandler | ( | object | sender, |
| DragDropEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that DragDrop event has started.
| sender | The source of the event. |
| e | The event data DragDropEventArgs. |
| delegate void DotNetBrowser.Events.FailLoadingFrameHandler | ( | object | sender, |
| FailLoadingEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that frame loading process has been failed.
| sender | The source of the event. |
| e | The event data FailLoadingEventArgs. |
| delegate void DotNetBrowser.Events.FinishLoadingFrameHandler | ( | object | sender, |
| FinishLoadingEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that frame loading process has been finished.
| sender | The source of the event. |
| e | The event data FinishLoadingEventArgs. |
| delegate void DotNetBrowser.Events.GestureEventHandler | ( | object | sender, |
| GestureEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that user has made a gesture interaction GestureType with device SourceDevice.
| sender | The source of the event. |
| e | The event data GestureEventArgs. |
| delegate void DotNetBrowser.Events.HandledGestureEventHandler | ( | object | sender, |
| HandledGestureEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that user has made a gesture interaction GestureType with device SourceDevice and provides an ability to discard performed interaction.
| sender | The source of the event. |
| e | The event data GestureEventArgs. |
| delegate void DotNetBrowser.Events.NotificationOnCloseHandler | ( | NotificationEventArgs | e | ) |
Represents the method that will handle event is being invoked when browser informs that notification should be closed. Notification can be closed in different ways: 1. Using the Notification.Close() method. 2. From JavaScript via Notification.close() JS function.
| e | The event data NotificationEventArgs. |
| delegate void DotNetBrowser.Events.OnRedrawEventHandler | ( | object | sender, |
| OnRedrawEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates when content of loaded web page in the browser view has been rendered as image.
| sender | The source of the event. |
| e | The event data OnRedrawEventArgs. |
| delegate void DotNetBrowser.Events.OnRepaintEventHandler | ( | object | sender, |
| OnRepaintEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates when content of loaded web page in the browser view has been repainted.
| sender | The source of the event. |
| e | The event data OnRepaintEventArgs. |
| delegate void DotNetBrowser.Events.PrintJobEventHandler | ( | object | sender, |
| PrintJobEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates when printing job updates its state.
| sender | The source of the event. |
| e | The event data PrintJobEventArgs. |
| delegate void DotNetBrowser.Events.ProvisionalLoadingFrameHandler | ( | object | sender, |
| ProvisionalLoadingArgs | e | ||
| ) |
Represents the method that will handle event that indicates that provisional load for a specified frame was successfully committed.
| sender | The source of the event. |
| e | The event data StartLoadingArgs. |
| delegate void DotNetBrowser.Events.RenderCreatedHandler | ( | object | sender, |
| RenderEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that the render process is gone or created.
| sender | The source of the event. |
| e | The event data RenderEventArgs. |
| delegate void DotNetBrowser.Events.ScriptContextCreatedHandler | ( | object | sender, |
| ScriptContextEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that JavaScript context has been created.
| sender | The source of the event. |
| e | The event data ScriptContextEventArgs. |
| delegate void DotNetBrowser.Events.ScriptContextDestroyedHandler | ( | object | sender, |
| ScriptContextEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that JavaScript context has been destroyed.
| sender | The source of the event. |
| e | The event data ScriptContextEventArgs. |
| delegate void DotNetBrowser.Events.SpellCheckCompletedHandler | ( | object | sender, |
| SpellCheckCompletedEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that the spell check process is completed.
| sender | The source of the event. |
| e | The event data SpellCheckCompletedEventArgs. |
| delegate void DotNetBrowser.Events.StartLoadingFrameHandler | ( | object | sender, |
| StartLoadingArgs | e | ||
| ) |
Represents the method that will handle event that indicates that frame loading process has been started.
| sender | The source of the event. |
| e | The event data StartLoadingArgs. |
| delegate void DotNetBrowser.Events.StatusEventHandler | ( | object | sender, |
| StatusEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that the status has been changed.
| sender | The source of the event. |
| e | The event data StatusEventArgs. |
| delegate void DotNetBrowser.Events.TitleChangedHandler | ( | object | sender, |
| TitleEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that the title of a document in main frame has been changed.
| sender | The source of the event. |
| e | The event data TitleEventArgs. |
| delegate void DotNetBrowser.Events.ZoomChangedHandler | ( | object | sender, |
| ZoomEventArgs | e | ||
| ) |
Represents the method that will handle event that indicates that the zoom of a document in main frame has been changed.
| sender | The source of the event. |
| e | The event data ZoomEventArgs. |


A Business BCeID will be needed if an organization and/or a user is accessing this system.
If you have any questions regarding your Business BCeID, please read the Frequently Asked Questions.


Cinder on DevStack - Quick Start
This blog post covers all the important commands for OpenStack Cinder - The block storage project. Although this guide is written based on DevStack, it will work with actual deployment of OpenStack cloud also (except the DevStack/Linux specific bits).
All the Cinder operations can be performed via either of these three means:
- CLI (Cinder's
python-cinderclient
command line module) - GUI (Using OpenStack's GUI project
horizon
) - Directly calling the Cinder APIs
Internally, the CLI and GUI both use Cinder APIs to interact with the Cinder API server, but for a relatively new guy to OpenStack, I think an introduction through CLI would make the most sense.
Assumptions made:
- You understand how to setup a DevStack environment and already have one ready at hand (remember
./stack.sh
?) - You know how to pass default credentials to local shell environment (
. /home/path_to_your_devstack_repo/eucarc
will do)
Let's start.
Creation and deletion of volumes
Create a 1-GB cinder volume with no name by running command cinder create 1
.
stack@stlrx300s7-27:/$ cinder create 1
+---------------------+--------------------------------------+
| Property | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | false |
| created_at | 2013-05-28T10:32:47.243613 |
| display_description | None |
| display_name | None |
| id | 6754d216-4792-4a38-964a-d002686c8f92 |
| metadata | {} |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | creating |
| volume_type | None |
+---------------------+--------------------------------------+
Here I am describing only the minimal functionality of a command. If you wish to see more info about what all you
can do with that command, just type cinder help <command>
, so to see all the optional parameters you can pass
while creating a Cinder volume, execute cinder help create
.
stack@stlrx300s7-27:/$ cinder help create
usage: cinder create [--snapshot-id <snapshot-id>]
[--source-volid <source-volid>] [--image-id <image-id>]
[--display-name <display-name>]
[--display-description <display-description>]
[--volume-type <volume-type>]
[--availability-zone <availability-zone>]
[--metadata [<key=value> [<key=value> ...]]]
<size>
Add a new volume.
Positional arguments:
<size> Size of volume in GB
Optional arguments:
--snapshot-id <snapshot-id>
Create volume from snapshot id (Optional,
Default=None)
--source-volid <source-volid>
Create volume from volume id (Optional, Default=None)
--image-id <image-id>
Create volume from image id (Optional, Default=None)
--display-name <display-name>
Volume name (Optional, Default=None)
--display-description <display-description>
Volume description (Optional, Default=None)
--volume-type <volume-type>
Volume type (Optional, Default=None)
--availability-zone <availability-zone>
Availability zone for volume (Optional, Default=None)
--metadata [<key=value> [<key=value> ...]]
Metadata key=value pairs (Optional, Default=None)
Don't worry about the parameters, we'll use most of them in a short time.
Let's create a Cinder volume of size 1GB with a name, using cinder create --display-name my_second_vol 1
:
stack@stlrx300s7-27:/$ cinder create --display-name my_second_vol 1
+---------------------+--------------------------------------+
| Property | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | false |
| created_at | 2013-05-28T10:40:32.801981 |
| display_description | None |
| display_name | my_second_vol |
| id | 25fa2028-46dc-4870-84c5-d062ae99dd7a |
| metadata | {} |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | creating |
| volume_type | None |
+---------------------+--------------------------------------+
Now lets list out all the Cinder volumes, using cinder list
:
stack@stlrx300s7-27:/$ cinder list
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
| ID | Status | Display Name | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
| 25fa2028-46dc-4870-84c5-d062ae99dd7a | available | my_second_vol | 1 | None | false | |
| 6754d216-4792-4a38-964a-d002686c8f92 | available | None | 1 | None | false | |
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
Now lets delete the first volume (the one without a name), using cinder delete <volume_id>
command. If you
execute cinder list
real quick, you will see the status of the volume going to ‘deleting’, and after some time
the volume will be deleted:
stack@stlrx300s7-27:/$ cinder delete 6754d216-4792-4a38-964a-d002686c8f92
stack@stlrx300s7-27:/$ cinder list
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
| ID | Status | Display Name | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
| 25fa2028-46dc-4870-84c5-d062ae99dd7a | available | my_second_vol | 1 | None | false | |
| 6754d216-4792-4a38-964a-d002686c8f92 | deleting | None | 1 | None | false | |
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
stack@stlrx300s7-27:/$
stack@stlrx300s7-27:/$
stack@stlrx300s7-27:/$ cinder list
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
| ID | Status | Display Name | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
| 25fa2028-46dc-4870-84c5-d062ae99dd7a | available | my_second_vol | 1 | None | false | |
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
On a default DevStack installation, for a volume in Cinder, a ‘logical volume’ is created on the Linux machine,
inside the ‘physical volume’ named stack-volumes
. To see the logical volumes, and physical volumes on the
ubuntu machine, just run lvs
(logical volume scan) and pvs
(physical volume scan) respectively (this is just
for information and you can entirely skip this part):
stack@stlrx300s7-27:/$ sudo lvs
LV VG Attr LSize Origin Snap% Move Log Copy% Convert
volume-25fa2028-46dc-4870-84c5-d062ae99dd7a stack-volumes -wi-ao 1.00g
stack@stlrx300s7-27:/$
stack@stlrx300s7-27:/$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/loop0 stack-volumes lvm2 a- 5.01g 4.01g
Volume snapshots
Create the snapshot of volume:
stack@stlrx300s7-27:/$ cinder snapshot-create 25fa2028-46dc-4870-84c5-d062ae99dd7a
+---------------------+--------------------------------------+
| Property | Value |
+---------------------+--------------------------------------+
| created_at | 2013-05-28T10:55:03.966690 |
| display_description | None |
| display_name | None |
| id | baf8764f-4c9b-496a-b2ff-bd49825c5d09 |
| metadata | {} |
| size | 1 |
| status | creating |
| volume_id | 25fa2028-46dc-4870-84c5-d062ae99dd7a |
+---------------------+--------------------------------------+
List all the snapshots:
stack@stlrx300s7-27:/$ cinder snapshot-list
+--------------------------------------+--------------------------------------+-----------+--------------+------+
| ID | Volume ID | Status | Display Name | Size |
+--------------------------------------+--------------------------------------+-----------+--------------+------+
| baf8764f-4c9b-496a-b2ff-bd49825c5d09 | 25fa2028-46dc-4870-84c5-d062ae99dd7a | available | None | 1 |
+--------------------------------------+--------------------------------------+-----------+--------------+------+
Now lets create a new volume of 1GB from the snapshot:
stack@stlrx300s7-27:/$ cinder create --snapshot-id baf8764f-4c9b-496a-b2ff-bd49825c5d09 1
+---------------------+--------------------------------------+
| Property | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | false |
| created_at | 2013-05-28T10:56:20.478141 |
| display_description | None |
| display_name | None |
| id | 99ebe1d0-678b-4a9a-8ec4-438f9804d327 |
| metadata | {} |
| size | 1 |
| snapshot_id | baf8764f-4c9b-496a-b2ff-bd49825c5d09 |
| source_volid | None |
| status | creating |
| volume_type | None |
+---------------------+--------------------------------------+
Now you will see two volumes when you'll do a cinder list
.
Accessing volumes from inside a virtual instance
You can attach a volume to a VM instance, to provide additional persistent storage to that VM. It works just like you attach an external HDD to your computer/laptop. But first, we'll need to create a virtual machine for that.
List out all the virtual machine images present in our DevStack setup, from which we can boot a
brand new VM instance, using glance image-list
or ‘nova image-list`:
stack@stlrx300s7-27:/$ nova image-list
+--------------------------------------+---------------------------------+--------+--------+
| ID | Name | Status | Server |
+--------------------------------------+---------------------------------+--------+--------+
| 291fe347-3a6f-4a21-9e85-e8809cb05d6e | cirros-0.3.1-x86_64-uec | ACTIVE | |
| 69d14d74-4185-4ba3-9666-1e7f569f38c6 | cirros-0.3.1-x86_64-uec-kernel | ACTIVE | |
| 8793532d-0c09-4b1c-aab8-d10832f13c09 | cirros-0.3.1-x86_64-uec-ramdisk | ACTIVE | |
+--------------------------------------+---------------------------------+--------+--------+
We'll use the image with the shortest name, and boot an instance, giving it a name myinstance
.
You can list all the virtual machine instances registered with Nova using command nova list
.
If just after running the command to boot the virtual machine, you run nova list
a few times,
you will see the machine state going from ‘BUILD’ to ‘ACTIVE’ in a few seconds.
stack@stlrx300s7-27:/$ nova boot --flavor m1.tiny --image 291fe347-3a6f-4a21-9e85-e8809cb05d6e myinstance
+-----------------------------+--------------------------------------+
| Property | Value |
+-----------------------------+--------------------------------------+
| status | BUILD |
| updated | 2013-05-28T11:03:47Z |
| OS-EXT-STS:task_state | scheduling |
| key_name | None |
| image | cirros-0.3.1-x86_64-uec |
| hostId | |
| OS-EXT-STS:vm_state | building |
| flavor | m1.tiny |
| id | 3b6dd9f1-3ca3-4eed-a508-1cd62d55629f |
| security_groups | [{u'name': u'default'}] |
| user_id | 35708cb6795845fcab6362e908e6b0cf |
| name | myinstance |
| adminPass | cQh34G96dCHX |
| tenant_id | 11f8fde7d627422d84036cabd6cbb7f8 |
| created | 2013-05-28T11:03:47Z |
| OS-DCF:diskConfig | MANUAL |
| metadata | {} |
| accessIPv4 | |
| accessIPv6 | |
| progress | 0 |
| OS-EXT-STS:power_state | 0 |
| OS-EXT-AZ:availability_zone | nova |
| config_drive | |
+-----------------------------+--------------------------------------+
stack@stlrx300s7-27:/$ nova list
+--------------------------------------+------------+--------+------------+-------------+----------+
| ID | Name | Status | Task State | Power State | Networks |
+--------------------------------------+------------+--------+------------+-------------+----------+
| 3b6dd9f1-3ca3-4eed-a508-1cd62d55629f | myinstance | BUILD | networking | NOSTATE | |
+--------------------------------------+------------+--------+------------+-------------+----------+
stack@stlrx300s7-27:/$ nova list
+--------------------------------------+------------+--------+------------+-------------+----------+
| ID | Name | Status | Task State | Power State | Networks |
+--------------------------------------+------------+--------+------------+-------------+----------+
| 3b6dd9f1-3ca3-4eed-a508-1cd62d55629f | myinstance | BUILD | spawning | NOSTATE | |
+--------------------------------------+------------+--------+------------+-------------+----------+
stack@stlrx300s7-27:/$ nova list
+--------------------------------------+------------+--------+------------+-------------+------------------+
| ID | Name | Status | Task State | Power State | Networks |
+--------------------------------------+------------+--------+------------+-------------+------------------+
| 3b6dd9f1-3ca3-4eed-a508-1cd62d55629f | myinstance | ACTIVE | None | Running | private=<IP_ADDRESS> |
+--------------------------------------+------------+--------+------------+-------------+------------------+
Now lets attach one of our volume to this instance, and then try to peek into this volume after logging into the instance.
Attach volume using command nova volume-attach <instance_id> <volume_id> <attach_location>
. We'll attach at the first
free device location: /dev/vdb
:
stack@stlrx300s7-27:/$ nova volume-attach 3b6dd9f1-3ca3-4eed-a508-1cd62d55629f 25fa2028-46dc-4870-84c5-d062ae99dd7a /dev/vdb
+----------+--------------------------------------+
| Property | Value |
+----------+--------------------------------------+
| device | /dev/vdb |
| serverId | 3b6dd9f1-3ca3-4eed-a508-1cd62d55629f |
| id | 25fa2028-46dc-4870-84c5-d062ae99dd7a |
| volumeId | 25fa2028-46dc-4870-84c5-d062ae99dd7a |
+----------+--------------------------------------+
Now listing the volume will tell you that the volume is attached to an instance (in use):
stack@stlrx300s7-27:/$ cinder list
+--------------------------------------+-----------+---------------+------+-------------+----------+--------------------------------------+
| ID | Status | Display Name | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+---------------+------+-------------+----------+--------------------------------------+
| 25fa2028-46dc-4870-84c5-d062ae99dd7a | in-use | my_second_vol | 1 | None | false | 3b6dd9f1-3ca3-4eed-a508-1cd62d55629f |
| 99ebe1d0-678b-4a9a-8ec4-438f9804d327 | available | None | 1 | None | false | |
+--------------------------------------+-----------+---------------+------+-------------+----------+--------------------------------------+
Now let's login into this virtual machine using the private IP of the instance (<IP_ADDRESS>
in our case). Note how an
error message pops up if you have already created an instance last time when you installed DevStack. If such an error
appears on your screen too, follow the instructions just like the way I did. The default password for the cirros image
we used is cubswin:)
. Enter into the instance, and then become root:
stack@stlrx300s7-27:/$ ssh<EMAIL_ADDRESS>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
f5:ac:45:4c:63:8e:e4:19:cc:5a:76:7e:a1:08:e7:c8.
Please contact your system administrator.
Add correct host key in /opt/stack/.ssh/known_hosts to get rid of this message.
Offending RSA key in /opt/stack/.ssh/known_hosts:4
remove with: ssh-keygen -f "/opt/stack/.ssh/known_hosts" -R <IP_ADDRESS>
RSA host key for <IP_ADDRESS> has changed and you have requested strict checking.
Host key verification failed.
stack@stlrx300s7-27:/$ ssh-keygen -f "/opt/stack/.ssh/known_hosts" -R <IP_ADDRESS>
/opt/stack/.ssh/known_hosts updated.
Original contents retained as /opt/stack/.ssh/known_hosts.old
stack@stlrx300s7-27:/$ ssh<EMAIL_ADDRESS>The authenticity of host '<IP_ADDRESS> (<IP_ADDRESS>)' can't be established.
RSA key fingerprint is f5:ac:45:4c:63:8e:e4:19:cc:5a:76:7e:a1:08:e7:c8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '<IP_ADDRESS>' (RSA) to the list of known hosts.
<EMAIL_ADDRESS>password:
$sudo -i
#
Run fdisk -l
to see the disks present for the instance. You will see that your newly attached disk
/dev/vdb
of size 1GB is now present:
# fdisk -l
Disk /dev/vda: 1073 MB,<PHONE_NUMBER> bytes
16 heads, 63 sectors/track, 2080 cylinders, total 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /dev/vda doesn't contain a valid partition table
Disk /dev/vdb: 1073 MB,<PHONE_NUMBER> bytes
16 heads, 63 sectors/track, 2080 cylinders, total 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /dev/vdb doesn't contain a valid partition table
Command blkid /dev/vd*
lists out the IDs of block devices for this machine and some related info. Running
this command you will see that info of only the virtual disk /dev/vda
is present, meaning our disk /dev/vdb
needs formatting.
# blkid /dev/vd*
/dev/vda: LABEL="cirros-rootfs" UUID="74251bb8-3a28-4a46-9a78-064497b26b9d" SEC_TYPE="ext2" TYPE="ext3"
Lets format it to make an EXT3 partition with block-size 1024 bytes using command mkfs.ext3 -b 1024 /dev/vdb
:
# mkfs.ext3 -b 1024 /dev/vdb
mke2fs 1.42.2 (27-Mar-2012)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
65536 inodes, 1048576 blocks
52428 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=68157440
128 block groups
8192 blocks per group, 8192 fragments per group
512 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553,
1024001
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
Run blkid
again to see the newly partitioned disk listed:
# blkid /dev/vd*
/dev/vda: LABEL="cirros-rootfs" UUID="74251bb8-3a28-4a46-9a78-064497b26b9d" SEC_TYPE="ext2" TYPE="ext3"
/dev/vdb: UUID="22838e81-eb97-457d-b1e0-4ff3d8e45b05" SEC_TYPE="ext2" TYPE="ext3"
In order to use this disk, you need to mount it at some location. I'll create a directory /tempmount
and mount our virtual block device there:
# mkdir /tempmount
# mount /dev/vdb /tempmount/
Now you can see the disk listed in the machine disks, using df -h
command:
# df -h
Filesystem Size Used Available Use% Mounted on
/dev 242.3M 0 242.3M 0% /dev
/dev/vda 31.0M 9.7M 19.7M 33% /
tmpfs 245.9M 0 245.9M 0% /dev/shm
tmpfs 200.0K 76.0K 124.0K 38% /run
/dev/vdb 1007.7M 34.9M 921.6M 4% /tempmount
Now you can cd
into /tempmount
directory, and do whatever you want to do with the new disk – put some files there,
or download one!
Lets wrap up this part. Unmount this volume by umount /tempmount
, and log out from the machine by pressing CTRL+D
twice, and execute nova volume-detach <server_id> <volume_id>
to detach this volume. You can now see the ‘Attached to’ column becomes empty again after detaching.
stack@stlrx300s7-27:/$ cinder list
+--------------------------------------+-----------+---------------+------+-------------+----------+--------------------------------------+
| ID | Status | Display Name | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+---------------+------+-------------+----------+--------------------------------------+
| 25fa2028-46dc-4870-84c5-d062ae99dd7a | in-use | my_second_vol | 1 | None | false | 3b6dd9f1-3ca3-4eed-a508-1cd62d55629f |
| 99ebe1d0-678b-4a9a-8ec4-438f9804d327 | available | None | 1 | None | false | |
+--------------------------------------+-----------+---------------+------+-------------+----------+--------------------------------------+
stack@stlrx300s7-27:/$ nova volume-detach 3b6dd9f1-3ca3-4eed-a508-1cd62d55629f 25fa2028-46dc-4870-84c5-d062ae99dd7a
stack@stlrx300s7-27:/$ cinder list
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
| ID | Status | Display Name | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
| 25fa2028-46dc-4870-84c5-d062ae99dd7a | available | my_second_vol | 1 | None | false | |
| 99ebe1d0-678b-4a9a-8ec4-438f9804d327 | available | None | 1 | None | false | |
+--------------------------------------+-----------+---------------+------+-------------+----------+-------------+
More features
(Will update shortly)
Cheers!