Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnishapi
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
uplex-varnish
varnishapi
Commits
20054d30
Commit
20054d30
authored
Dec 05, 2018
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add admin.VCLList() and .ActiveVCL().
parent
be0a7893
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
331 additions
and
0 deletions
+331
-0
cli.go
pkg/admin/cli.go
+331
-0
No files found.
pkg/admin/cli.go
View file @
20054d30
...
...
@@ -30,6 +30,8 @@ package admin
import
(
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"time"
...
...
@@ -279,3 +281,332 @@ func (adm *Admin) VCLDiscard(config string) error {
}
return
nil
}
// VCLStatus encodes whether a VCL configuration is the one in active
// use by a Varnish instance, having been specified by VCLUse() or the
// vcl.use command. It corresponds to the first column of vcl.list
// output.
type
VCLStatus
uint8
const
(
// Active indicates that a VCL has been specified by vcl.use.
Active
VCLStatus
=
iota
// Available indicates that a VCL has been loaded, but is not
// active.
Available
// Discarded indicates that a VCL has been marked for removal,
// having been specified by VCLDiscard() or the vcl.discard
// command.
Discarded
)
// String returns the string for a VCLStatus that appears in the first
// column of vcl.list output.
func
(
status
VCLStatus
)
String
()
string
{
switch
status
{
case
Active
:
return
"active"
case
Available
:
return
"available"
case
Discarded
:
return
"discarded"
default
:
panic
(
"Invalid status"
)
}
}
// VCLState encodes the state of a VCL configuration or label. It
// corresponds the string before the slash in the second column of
// vcl.list output.
//
// If a VCL's state is Label, then it is a label that has been applied
// to a configuration with VCLLabel() or the vcl.label
// command. Otherwise it is a configuration that has been loaded with
// VCLLoad() or VCLInline(), or one of the vcl.load or vcl.inline
// commands.
type
VCLState
uint8
const
(
// Auto indicates a VCL configuration that undergoes
// temperature transitions automatically -- it remains warm
// when not in use for the duration of the cooldown period
// (set by the varnishd parameter vcl_cooldown).
Auto
VCLState
=
iota
// ColdState indicates a VCL configuration in the cold state
// -- it has released resources, including removal of backend
// definitions and running VMOD finalizers.
ColdState
// WarmState indicates a VCL configuration in the warm state
// -- even while inactive, resources are not yet released (so
// so that it can be quickly made active again).
WarmState
// Label indicates a VCL label, applied to a configuration
// with VCLLabel() or the vcl.label command.
Label
)
// String returns the string for a VCLState that appears in the second
// column of vcl.list output.
func
(
state
VCLState
)
String
()
string
{
switch
state
{
case
Auto
:
return
"auto"
case
ColdState
:
return
"cold"
case
WarmState
:
return
"warm"
case
Label
:
return
"label"
default
:
panic
(
"Invalid state"
)
}
}
// VCLTemperature encodes information about the initialized or
// released state of a VCL configuration. It corresponds the string
// after the slash in the second column of vcl.list output.
type
VCLTemperature
uint8
const
(
// Init indicates that a VCL instance is initializing (for
// example, it may be running VMOD object constructors).
Init
VCLTemperature
=
iota
// ColdTemp indicates that the VCL instance is in the cold
// state -- it has released resources, including removal of
// backend definitions and running VMOD finalizers.
ColdTemp
// WarmTemp indicates a VCL configuration in the warm state --
// even while inactive, resources are not yet released (so so
// that it can be quickly made active again).
WarmTemp
// Busy indicates that the VCL instance is transitioning to
// the cold state, but there are still active threads using
// the configuration.
Busy
// Cooling indicates a VCL instance in the transition to the
// cold state that is not in use by any thread, but has not
// yet completed releasing resources.
Cooling
)
// String returns the string for a VCLTemperature that appears in the
// second column of vcl.list output.
func
(
temp
VCLTemperature
)
String
()
string
{
switch
temp
{
case
Init
:
return
"init"
case
ColdTemp
:
return
"cold"
case
WarmTemp
:
return
"warm"
case
Busy
:
return
"busy"
case
Cooling
:
return
"cooling"
default
:
panic
(
"Invalid temperature"
)
}
}
// VCLData represents information about loaded VCL configurations and
// labels that is returned by the vcl.list command.
//
// If the value of the State field is Label, then this object
// represents a VCL label, applied to a configuration with VCLLabel()
// or the vcl.label command. In that case, the Labels field does not
// apply, but the LabelVCL and LabelReturns fields are valid.
//
// With any other value for the State field, the object represents a
// VCL configuration, loaded with VCLLoad() or VCLInline(), or one of
// the vcl.load or vcl.inline commands. In that case the Labels field
// is valid, but the LabelVCL and LabelReturns fields are not.
type
VCLData
struct
{
// Name is the name of the VCL configuration or label, given
// when the object was created. It corresponds to the fourth
// column of vcl.list output.
Name
string
// Status indicates whether a VCL configuration is in active
// use, having been specified by VCLUse() or vcl.use. It
// corresponds to the first column of vcl.list output.
Status
VCLStatus
// State indicates the state of the configuration or label.
// It is a label if and only if State==Label. The field
// corresponds to the string before the slash in the second
// column of vcl.list output.
State
VCLState
// Temperature indicates the initialized or released state of
// a VCL configuration. It corresponds to the string after the
// slash in the second column of vcl.list output.
Temperature
VCLTemperature
// Busy indicates the number of resources using the VCL
// configuration, such as client sessions or backend
// fetches. A VCL instance cannot transition to the cold state
// or be discarded until the busy count reaches 0. The field
// corresponds to the number in the third column of vcl.list
// output
Busy
uint
// LabelVCL is only valid for a label (State==Label). It is
// the name of the VCL configuration to which the label is
// applied.
LabelVCL
string
// LabelReturns is only valid for a label (State==Label),
// indicating the number of return(vcl) statements in VCL
// configurations that branch to the label.
LabelReturns
uint
// Labels is only valid for a VCL configuration
// (State!=Label), indicating the number of labels that have
// been applied to it.
Labels
uint
}
var
(
str2status
=
map
[
string
]
VCLStatus
{
"active"
:
Active
,
"available"
:
Available
,
"discarded"
:
Discarded
,
}
str2state
=
map
[
string
]
VCLState
{
"auto"
:
Auto
,
"cold"
:
ColdState
,
"warm"
:
WarmState
,
"label"
:
Label
,
}
str2temp
=
map
[
string
]
VCLTemperature
{
"init"
:
Init
,
"cold"
:
ColdTemp
,
"warm"
:
WarmTemp
,
"busy"
:
Busy
,
"cooling"
:
Cooling
,
}
vclMain
=
regexp
.
MustCompile
(
`^(\w+)\s+(\w+)/(\w+)\s+(\d+)\s+(\S+)`
)
vclLbls
=
regexp
.
MustCompile
(
`->\s+(\S+)\s+\((\d+)`
)
vclLblRefs
=
regexp
.
MustCompile
(
`(\d+)\s+labels?\)\s*$`
)
)
// VCLList encapsulates the "vcl.list" command. error is non-nil when
// the response was not OK. In that case, the error is an
// UnexpectedResponse, which wraps the response from Varnish.
//
// When error is nil, VCLList() returns a slice of VCLData objects --
// structured data encoding the information in the output of vcl.list.
func
(
adm
*
Admin
)
VCLList
()
([]
VCLData
,
error
)
{
data
:=
[]
VCLData
{}
resp
,
err
:=
adm
.
Command
(
"vcl.list"
)
if
err
!=
nil
{
return
data
,
err
}
if
resp
.
Code
!=
OK
{
badResp
:=
UnexpectedResponse
{
Response
:
resp
}
return
data
,
badResp
}
vcls
:=
strings
.
Split
(
resp
.
Msg
,
"
\n
"
)
for
_
,
vcl
:=
range
vcls
{
datum
:=
VCLData
{}
if
main
:=
vclMain
.
FindStringSubmatch
(
vcl
);
main
!=
nil
{
if
status
,
ok
:=
str2status
[
main
[
1
]];
ok
{
datum
.
Status
=
status
}
else
{
return
data
,
fmt
.
Errorf
(
"Unknown status %s: %s"
,
main
[
1
],
vcl
)
}
if
state
,
ok
:=
str2state
[
main
[
2
]];
ok
{
datum
.
State
=
state
}
else
{
return
data
,
fmt
.
Errorf
(
"Unknown state %s: %s"
,
main
[
2
],
vcl
)
}
if
temp
,
ok
:=
str2temp
[
main
[
3
]];
ok
{
datum
.
Temperature
=
temp
}
else
{
return
data
,
fmt
.
Errorf
(
"Unknown temperature %s: %s"
,
main
[
3
],
vcl
)
}
if
b
,
e
:=
strconv
.
ParseUint
(
main
[
4
],
0
,
0
);
e
!=
nil
{
datum
.
Busy
=
uint
(
b
)
}
else
{
return
data
,
fmt
.
Errorf
(
"Cannot parse busy field %s"
+
": %s"
,
main
[
4
],
vcl
)
}
datum
.
Name
=
main
[
5
]
}
else
{
return
data
,
fmt
.
Errorf
(
"Cannot parse vcl.list output: %s"
,
vcl
)
}
if
datum
.
State
!=
Label
{
if
r
:=
vclLblRefs
.
FindStringSubmatch
(
vcl
);
r
!=
nil
{
if
n
,
err
:=
strconv
.
ParseUint
(
r
[
1
],
0
,
0
);
err
!=
nil
{
datum
.
Labels
=
uint
(
n
)
}
else
{
return
data
,
fmt
.
Errorf
(
"Cannot parse "
+
"labels field %s: %s"
,
r
[
1
],
vcl
)
}
}
}
else
{
if
l
:=
vclLbls
.
FindStringSubmatch
(
vcl
);
l
!=
nil
{
datum
.
LabelVCL
=
l
[
1
]
if
n
,
err
:=
strconv
.
ParseUint
(
l
[
2
],
0
,
0
);
err
!=
nil
{
datum
.
LabelReturns
=
uint
(
n
)
}
else
{
return
data
,
fmt
.
Errorf
(
"Cannot parse "
+
"returns field %s: %s"
,
l
[
2
],
vcl
)
}
}
else
{
return
data
,
fmt
.
Errorf
(
"Cannot parse vcl.list "
+
"output: %s"
,
vcl
)
}
}
data
=
append
(
data
,
datum
)
}
return
data
,
nil
}
// ActiveVCL returns data about the active VCL configuration, as
// indicated by the output of the vcl.list command. error is non-nil
// if the response to vcl.list was not OK. In that case, the error is
// an UnexpectedResponse, which wraps the response from Varnish.
//
// When error is nil, ActiveVCL() returns a VCLData object --
// structured data encoding the information in the output of vcl.list.
// If no configuration is currently active, all fields of the VCLData
// object are set to their zero values; for example, the Name field is
// empty (which is otherwise never the case).
func
(
adm
*
Admin
)
ActiveVCL
()
(
VCLData
,
error
)
{
vcl
:=
VCLData
{}
data
,
err
:=
adm
.
VCLList
()
if
err
!=
nil
{
return
vcl
,
err
}
for
_
,
datum
:=
range
data
{
if
datum
.
Status
==
Active
{
return
datum
,
nil
}
}
return
vcl
,
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment